I need help, as I've tried to make the quantity work - jframe

Can someone help me on my problem regarding on the Quantity as it will not display in my bill(JTextArea) and i've already fixed my printwriter problem
Here is the code below:
`
So,please i need everyone's help regarding on the Quantity issue
package gb.dhaneBonz.ChezDanielle.Main;
//Chez Danielle Bistro System
//importations and the heading of this System.
import java.awt.*;
import java.awt.event.*;
import java.io.FileWriter;
import java.io.PrintWriter;
import javax.swing.*;
import javax.swing.event.*;
//The menuChoicesItems and menuChoicesPrices have worked together
//with the bill(JList) in order to display it
public class ChezDanielle extends JFrame implements ActionListener
{
static String[] menuChoicesItems =
{"Andouillette (pork offal sausage) 120.00",
"Pot au feu (Lyonnais pot roast) 80.75",
"Reinsdyrsteik (Reindeer roast) 250.30",
"Bordeaux Superieur Wine 250.00",
"Crispy Pata 380.00",
"Cabernet Sauvignon Wine 180.40",
"Pain Perdu(French Toast)65.00",
"French Fries(1 bucket) 55.50",
"Chicharon 34.00",
"Coffee(Cappuccino) 40.90",
"Latte Coffee 35.00",
"Iced Tea(Bottomless) 40.00",
"Leche Flan 55.75",
"Maja Blanca 250.00",
"Bistek Tagalog 87.00",
"Buko Pie 67.00",
"Coq au Vin(Chicken with red wine soup) 180.00",
"Ice Cream Box 230,00",
"Baileys Whisky 380.00",
"Durian Shake(Bottomless) 60.00",
"Creme Brulee 230.00",};
static double[] menuChoicesPrices = {120.00, 80.75, 250.30, 250.00, 380.00,
180.40, 65.00, 55.50, 34.00,
40.00, 35.00, 40.00, 55.75, 250.00, 87.00, 67.00, 180.00, 230.00, 380.00, 60.00, 230.00};
private JList menuChoices;
private JTextArea bill;
private Container pane;
public ChezDanielle()
{
super("ChezDanielle Bistro Simplice");
setResizable(false);
setIconImage(Toolkit.getDefaultToolkit().getImage(ChezDanielle.class.getResource("/Images/Icon.png")));
//Colours and Layouts of this programme.
pane = getContentPane();
pane.setBackground(new Color(255, 20, 147));
pane.setLayout(new BorderLayout(5, 5));
//Label placement is on the NORTH and its parameters below.
JLabel menuChoicesJLabel = new JLabel("Le Menu");
menuChoicesJLabel.setForeground(Color.WHITE);
menuChoicesJLabel.setHorizontalAlignment(SwingConstants.LEFT);
pane.add(menuChoicesJLabel,BorderLayout.NORTH);
menuChoicesJLabel.setFont(new Font("Segoe UI", Font.BOLD, 20));
//Menu is on the WEST and its parameters below.
menuChoices = new JList(menuChoicesItems);
menuChoices.setForeground(Color.BLACK);
menuChoices.setBackground(Color.WHITE);
JScrollPane scrollPane = new JScrollPane (menuChoices);
pane.add(scrollPane,BorderLayout.WEST);
menuChoices.setFont(new Font("Segoe UI", Font.BOLD, 14));
//Receipt area is on the EAST and its parameters below.
bill = new JTextArea();
pane.add(bill,BorderLayout.EAST);
bill.setFont(new Font("Segoe UI", Font.PLAIN, 14));
//Button is on the SOUTH and its parameters below in order to
//make it work.
JButton button = new JButton("Please Select and Order");
button.setFont(new Font("Segoe UI", Font.PLAIN, 11));
setSize(747, 484);
pane.add(button,BorderLayout.SOUTH);
button.addActionListener(this);
setSize(747, 484);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//Method for quantity
private void quantity()
{
final double[] quantity = {0,1,2,3,10,20};
Double.parseDouble(JOptionPane.showInputDialog(null,"Enter Quantity: "+quantity));
}
//Method codes to display the order and the total cost.
private void displayBill()
{
int[] listArray = menuChoices.getSelectedIndices();
double salesTax = 0.065;
double quantity = 0;
double tax;
double subTotal = 0;
double total;
//Receipt area's extra parameters.
bill.setEditable(false);
bill.setText("");
//Total and initialisation of the programme.
for (int index = 0; index < listArray.length; index++)
subTotal = subTotal
+ menuChoicesPrices,quantity[listArray[index]];
tax = salesTax * subTotal;
total = subTotal + tax;
//This Displays the costs of the order.
bill.append("---------------------Chez Danielle--------------------------\n");
bill.append("---------------------Our Branches:--------------------------\n");
bill.append("------Paris Davao London Edinburgh Oslo Marseille-----------\n");
bill.append("----Website: www.chezdanielle.co.uk | Phone No: 440-9087----\n\n");
for (int index = 0; index < listArray.length; index++)
{
bill.append(menuChoicesItems,quantity[listArray[index]]+ "\n");
}
bill.append("\n");
bill.append("SUB TOTAL\t\tPHP "
+ String.format("%.2f", subTotal) + "\n");
bill.append("TAX \t\tPHP "
+ String.format("%.2f", tax) + "\n");
bill.append("TOTAL \t\tPHP "
+ String.format("%.2f", total) + "\n\n");
bill.append("Bonjour, Merci - Have a Nice Day\n\n");
//Resets the receipt array in order to pave way for the new order(Loop).
menuChoices.clearSelection();
repaint();
}
public void actionPerformed(ActionEvent event)
{
if (event.getActionCommand().equals("Please Select and Order"))
quantity();
outFile();
displayBill();
}
public static void main(String[] args)
{
ChezDanielle alc = new ChezDanielle();
}
//Method for the TextFile
private void outFile()
{
try{
PrintWriter printW=new PrintWriter(new FileWriter("Receipt.txt",true));
printW.println(""+bill.getText());
printW.close();
JOptionPane.showMessageDialog(null, new JTextArea("Thank You for Choosing Chez Danielle!"));
}catch (Exception e) {
JOptionPane.showInternalMessageDialog(null, e.getMessage());
}
}
}
Any Ideas on how to make it work?

It's already fixed and its okay already
package gb.dhaneBonz.ChezDanielle.Main;
//Chez Danielle Bistro System
//importations and the heading of this System.
import java.awt.*;
import java.awt.event.*;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.event.*;
//The menuChoicesItems and menuChoicesPrices have worked together due to array methods.
//with the bill(JList) in order to display it
public class ChezDanielle extends JFrame implements ActionListener
{
static String[] menuChoicesItems =
{"Andouillette (pork offal sausage) 120.00",
"Pot au feu (Lyonnais pot roast) 80.75",
"Reinsdyrsteik (Reindeer roast) 250.30",
"Bordeaux Superieur Wine 250.00",
"Crispy Pata 380.00",
"Cabernet Sauvignon Wine 180.40",
"Pain Perdu(French Toast)65.00",
"French Fries(1 bucket) 55.50",
"Chicharon 34.00",
"Coffee(Cappuccino) 40.90",
"Latte Coffee 35.00",
"Iced Tea(Bottomless) 40.00",
"Leche Flan 55.75",
"Maja Blanca 250.00",
"Bistek Tagalog 87.00",
"Buko Pie 67.00",
"Coq au Vin(Chicken with red wine soup) 180.00",
"Ice Cream Box 230,00",
"Baileys Whisky 380.00",
"Durian Shake(Bottomless) 60.00",
"Creme Brulee 230.00",};
static double[] menuChoicesPrices = {120.00, 80.75, 250.30, 250.00, 380.00,
180.40, 65.00, 55.50, 34.00,
40.90, 35.00, 40.00, 55.75, 250.00, 87.00, 67.00, 180.00, 230.00, 380.00, 60.00, 230.00};
private JList menuChoices;
private JTextArea bill;
private Container pane;
public ChezDanielle()
{
super("ChezDanielle Bistro Simplice");
setResizable(false);
setIconImage(Toolkit.getDefaultToolkit().getImage(ChezDanielle.class.getResource("/Images/Icon.png")));
//Colours and Layouts of this programme.
pane = getContentPane();
pane.setBackground(new Color(255, 20, 147));
pane.setLayout(new BorderLayout(5, 5));
// the Label placement is on the NORTH and its parameters below.
JLabel menuChoicesJLabel = new JLabel("Le Menu");
menuChoicesJLabel.setForeground(Color.WHITE);
menuChoicesJLabel.setHorizontalAlignment(SwingConstants.LEFT);
pane.add(menuChoicesJLabel,BorderLayout.NORTH);
menuChoicesJLabel.setFont(new Font("Segoe UI", Font.BOLD, 20));
// the menuChoicesItems is on the WEST and its parameters below.
menuChoices = new JList(menuChoicesItems);
menuChoices.setForeground(Color.BLACK);
menuChoices.setBackground(Color.WHITE);
JScrollPane scrollPane = new JScrollPane (menuChoices);
pane.add(scrollPane,BorderLayout.WEST);
menuChoices.setFont(new Font("Segoe UI", Font.BOLD, 14));
//I've placed the receipt area is on the EAST and its parameters below.
bill = new JTextArea();
pane.add(bill,BorderLayout.EAST);
bill.setFont(new Font("Segoe UI", Font.PLAIN, 14));
//Button is on the SOUTH and its parameters below in order to
//make it work.
JButton button = new JButton("Please Select and Order");
button.setFont(new Font("Segoe UI", Font.PLAIN, 11));
setSize(747, 484);
pane.add(button,BorderLayout.SOUTH);
button.addActionListener(this);
setSize(747, 484);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//Method codes for quantity
private void quantity()
{
}
//Method codes to display the order and the total cost.
private void displayBill()
{
JOptionPane.showMessageDialog(null, new JTextArea("Thank You for Choosing Chez Danielle!"));
int[] quantity = new int[0];
int choiceLength = menuChoices.getSelectedIndices().length;
for(int i = 0; i < choiceLength; i++){
// JOptionPane.showMessageDialog(null, menuChoices.getSelectedValues());
int qty = Integer.parseInt(JOptionPane.showInputDialog(null,"Enter Quantity of "+menuChoices.getSelectedValues()[i]));
quantity = Arrays.copyOf(quantity, quantity.length + 1);
quantity[quantity.length - 1] = qty;
}
int[] listArray = menuChoices.getSelectedIndices();
double salesTax = 0.065;
//int quantity ;
double tax;
double subTotal = 0;
double total;
double itemTotal;
//Receipt area's extra parameters.
bill.setEditable(false);
bill.setText("");
//Total and initialisation of the programme.
for (int index = 0; index < listArray.length; index++)
{
itemTotal = menuChoicesPrices[listArray[index]] * quantity[index];
subTotal = subTotal + itemTotal;
}
tax = salesTax * subTotal;
total = subTotal + tax ;
//This Displays the costs of the order.
bill.append("---------------------Chez Danielle--------------------------\n");
bill.append("---------------------Our Branches:--------------------------\n");
bill.append("------Paris Davao London Edinburgh Oslo Marseille-----------\n");
bill.append("----Website: www.chezdanielle.co.uk | Phone No: 440-9087----\n\n");
for (int index = 0; index < listArray.length; index++)
{
bill.append(menuChoicesItems[listArray[index]]+ " x "+ quantity[index]+" /Order"+"\n");
}
bill.append("\n");
bill.append("SUB TOTAL\t\tPHP "
+ String.format("%.2f", subTotal) + "\n");
bill.append("TAX \t\tPHP "
+ String.format("%.2f", tax) + "\n");
bill.append("TOTAL \t\tPHP "
+ String.format("%.2f", total) + "\n\n");
bill.append("Bonjour, Merci - Have a Nice Day\n\n");
//Resets the receipt array in order to pave way for the new order(Loop).
menuChoices.clearSelection();
repaint();
}
public void actionPerformed(ActionEvent event)
{
if (event.getActionCommand().equals("Please Select and Order"))
quantity();
outFile();
displayBill();
}
public static void main(String[] args)
{
ChezDanielle alc = new ChezDanielle();
}
//Method for the TextFile
private void outFile()
{
try{
PrintWriter printW=new PrintWriter(new FileWriter("Receipt.txt",true));
printW.println(""+bill.getText());
printW.close();
}catch (Exception e) {
JOptionPane.showInternalMessageDialog(null, e.getMessage());
}
}
}

Related

Multi-Line Text Fitting in IText 7

This question is a follow-up from this
After the previous post I managed to create the following method that fits text in certain spaces in paragraphs.
public static void getPlainFill2(String str, Document doc, PdfDocument document, Paragraph root,
Paragraph space, boolean isCentred) {
// System.out.println("prevText: "+prev.getText());
float width = doc.getPageEffectiveArea(PageSize.A4).getWidth();
float height = doc.getPageEffectiveArea(PageSize.A4).getHeight();
if (str.isEmpty() || str.isBlank()) {
str = "________";
}
IRenderer spaceRenderer = space.createRendererSubTree().setParent(doc.getRenderer());
LayoutResult spaceResult = spaceRenderer
.layout(new LayoutContext(new LayoutArea(1, new Rectangle(width, height))));
Rectangle rectSpaceBox = ((ParagraphRenderer) spaceRenderer).getOccupiedArea().getBBox();
float writingWidth = rectSpaceBox.getWidth();
float writingHeight = rectSpaceBox.getHeight();
Rectangle remaining = doc.getRenderer().getCurrentArea().getBBox();
float yReal = remaining.getTop() + 2f;// orig 4f
float sizet = 0;
for (int i = 0; i < root.getChildren().size(); i++) {
IElement e = root.getChildren().get(i);
if (e.equals(space)) {
break;
}
IRenderer ss = e.createRendererSubTree().setParent(doc.getRenderer());
LayoutResult ss2 = ss.layout(new LayoutContext(new LayoutArea(1, new Rectangle(width, height))));
sizet += ss.getOccupiedArea().getBBox().getWidth();
System.out.println("width: " + width + " current: " + sizet);
}
float start = sizet+doc.getLeftMargin();
if(isCentred)
start = (width - getRealWidth(doc, root,width,height))/2+doc.getLeftMargin()+sizet;
Rectangle towr = new Rectangle(start, yReal, writingWidth, writingHeight);// sizet+doc.getLeftMargin()
PdfCanvas pdfcanvas = new PdfCanvas(document.getFirstPage());
Canvas canvas = new Canvas(pdfcanvas, towr);
canvas.setTextAlignment(TextAlignment.CENTER);
canvas.setHorizontalAlignment(HorizontalAlignment.CENTER);
Paragraph paragraph = new Paragraph(str).setTextAlignment(TextAlignment.CENTER).setBold();//.setMultipliedLeading(0.9f);
Div lineDiv = new Div();
lineDiv.setVerticalAlignment(VerticalAlignment.MIDDLE);
lineDiv.add(paragraph);
float fontSizeL = 1f;
float fontSizeR = 12;
int adjust = 0;
while (Math.abs(fontSizeL - fontSizeR) > 1e-1) {
float curFontSize = (fontSizeL + fontSizeR) / 2;
lineDiv.setFontSize(curFontSize);
// It is important to set parent for the current element renderer to a root
// renderer
IRenderer renderer = lineDiv.createRendererSubTree().setParent(canvas.getRenderer());
LayoutContext context = new LayoutContext(new LayoutArea(1, towr));
if (renderer.layout(context).getStatus() == LayoutResult.FULL) {
// we can fit all the text with curFontSize
fontSizeL = curFontSize;
} else {
fontSizeR = curFontSize;
}
if(adjust>=2) {
writingHeight -=1.3f;
yReal += 1.4f;
adjust= 0;
}
}
lineDiv.setFontSize(fontSizeL);
canvas.add(lineDiv);
// border
// PdfCanvas(document.getFirstPage()).rectangle(towr).setStrokeColor(ColorConstants.BLACK).stroke();
canvas.close();
}
public static float getRealWidth (Document doc, Paragraph root,float width,float height) {
float sizet = 0;
for(int i = 0;i<root.getChildren().size();i++) {
IElement e = root.getChildren().get(i);
IRenderer ss = e.createRendererSubTree().setParent(doc.getRenderer());
LayoutResult ss2 = ss.layout(new LayoutContext(new LayoutArea(1, new Rectangle(width,height))));
sizet +=ss.getOccupiedArea().getBBox().getWidth();
}
return sizet;}
Now this works almost decent, there are minor issues when text scales to lower sizes and it goes like:
https://i.ibb.co/MkxfwjQ/Screenshot-from-2021-06-14-18-27-09.png (I can't post images because I have no rep.)
but the main issue is that you have to write Paragraphs line by line to work. As next example:
Cell cell3 = new Cell();
LineCountingParagraph line3 = new LineCountingParagraph("");
Text ch07 = new Text("Paragraph Prev ");
line3.add(ch07);
Paragraph nrZile = getEmptySpace(15);
line3.add(nrZile);
Text ch08 = new Text("afterStr, textasdsadasdas ");
line3.add(ch08);
Paragraph data = getEmptySpace(18);
line3.add(data);
Text ch09 = new Text(".\n");
line3.add(ch09);
line3.setTextAlignment(TextAlignment.CENTER);
cell3.add(line3);
doc.add(cell3);
getPlainFill2("thisisalongstring", doc, document, line3, nrZile, true);
getPlainFill2("1333", doc, document, line3, data, true);
Cell cell4 = new Cell();
LineCountingParagraph line4 = new LineCountingParagraph("");
Paragraph loc2 = getEmptySpace(30);
line4.add(loc2);
Text pr32 = new Text(" aasdbsadasd ");
line4.add(pr32);
Paragraph nr2 = getEmptySpace(8);
line4.add(nr2);
Text pr33 = new Text(" asdasdasdasd.\n");
line4.add(pr33);
line4.setTextAlignment(TextAlignment.CENTER);
cell4.add(line4);
doc.add(cell4);
getPlainFill2("1333", doc, document, line4, nr2, true);
If you need more code, I'll upload it somewhere.
Now is there a way to insert text within the same paragraph on multiple lines ? because there seems I cannot find a way to detect line break in IText 7.1.11.
Full code:
package pdfFill;
import java.io.File;
import java.io.IOException;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Div;
import com.itextpdf.layout.element.IElement;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.layout.LayoutArea;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.layout.LayoutResult;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.ParagraphRenderer;
public class Newway4 {
public static void main(String[] args) {
PdfWriter writer;
try {
writer = new PdfWriter(new File("test4.pdf"));
PdfDocument document = new PdfDocument(writer);
document.getDocumentInfo().addCreationDate();
document.getDocumentInfo().setAuthor("Piri");
document.getDocumentInfo().setTitle("Test_Stackoverflow");
document.setDefaultPageSize(PageSize.A4);
Document doc = new Document(document);
doc.setFontSize(12);
final Paragraph titlu = new Paragraph();
final Text t1 = new Text("\n\n\n\nTest Stackoverflow\n\n\n").setBold().setUnderline();
titlu.setHorizontalAlignment(HorizontalAlignment.CENTER);
titlu.setTextAlignment(TextAlignment.CENTER);
titlu.add(t1).setBold();
doc.add(titlu);
Cell cell1 = new Cell();
LineCountingParagraph line1 = new LineCountingParagraph("");
line1.add( addTab());
Text ch01 = new Text("This is the 1st example ");
line1.add(ch01);
Paragraph name = getEmptySpace(42);
line1.add(name);// cnp new line
Text ch02 = new Text(" that works ");
line1.add(ch02);
Paragraph domiciliu = getEmptySpace(63);
line1.add(domiciliu);
/* Text ch03 = new Text("\njudet");
line1.add(ch03);
Paragraph judet = getEmptySpace(12);
line1.add(judet);*/
Text ch031 = new Text("\n");
line1.add(ch031);
cell1.add(line1);
doc.add(cell1);
getPlainFill2("with insertion str", doc, document, line1, name, false);
getPlainFill2("because is writtin line by line", doc, document, line1, domiciliu, false);
Cell cell2 = new Cell();
LineCountingParagraph line2 = new LineCountingParagraph("");
Text p51 = new Text("as you can see in this");
line2.add(p51);
Paragraph localitatea = getEmptySpace(30);
line2.add(localitatea);
Text p7 = new Text(" and ");
line2.add(p7);
Paragraph nrCasa =getEmptySpace(8);
line2.add(nrCasa);
Text p09 = new Text(" of text scalling ");
line2.add(p09);
Paragraph telefon = getEmptySpace(22);
line2.add(telefon);
Text p11 = new Text(".");
line2.add(p11);
line2.setTextAlignment(TextAlignment.CENTER);
cell2.add(line2);
doc.add(cell2);
getPlainFill2("sentence", doc, document, line2, localitatea, true);
getPlainFill2("example", doc, document, line2, nrCasa, true);
getPlainFill2("text scalling bla bla", doc, document, line2, telefon, true);
doc.add(new Paragraph("\n\n\n"));
LineCountingParagraph paragraphTest = new LineCountingParagraph("");
paragraphTest.add(addTab());
Text testch01 = new Text("This is the 2nd example ");
paragraphTest.add(testch01);
Paragraph emptyTest01 = getEmptySpace(42);
paragraphTest.add(emptyTest01);
Text testch02 = new Text(" that doesn't work ");
paragraphTest.add(testch02);
Paragraph emptyTest02 = getEmptySpace(53);
paragraphTest.add(emptyTest02);
Text testch04 = new Text(" this next goes to the next line but ");
paragraphTest.add(testch04);
Paragraph emptyTest03 = getEmptySpace(42);
paragraphTest.add(emptyTest03);
Text testch05 = new Text(" won't appear !!");
paragraphTest.add(testch05);
doc.add(paragraphTest);
getPlainFill2("with insertion str", doc, document, paragraphTest, emptyTest01, false);
getPlainFill2("because next text goes next line", doc, document, paragraphTest, emptyTest02, false);
getPlainFill2("this text", doc, document, paragraphTest, emptyTest03, false);
doc.close();
writer.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String getStrWithDots(final int dots, final String str) {
final int strSize = str.length();
final StringBuilder sb = new StringBuilder();
int dotsRemained;
if (strSize > dots) {
dotsRemained = 0;
} else {
dotsRemained = dots - strSize;
}
for (int i = 0; i < dotsRemained; ++i) {
if (i == dotsRemained / 2) {
sb.append(str);
}
sb.append(".");
}
return sb.toString();
}
public static void getPlainFill2(String str, Document doc, PdfDocument document, Paragraph root,
Paragraph space, boolean isCentred) {
// System.out.println("prevText: "+prev.getText());
float width = doc.getPageEffectiveArea(PageSize.A4).getWidth();
float height = doc.getPageEffectiveArea(PageSize.A4).getHeight();
if (str.isEmpty() || str.isBlank()) {
str = "________";
}
IRenderer spaceRenderer = space.createRendererSubTree().setParent(doc.getRenderer());
LayoutResult spaceResult = spaceRenderer
.layout(new LayoutContext(new LayoutArea(1, new Rectangle(width, height))));
Rectangle rectSpaceBox = ((ParagraphRenderer) spaceRenderer).getOccupiedArea().getBBox();
float writingWidth = rectSpaceBox.getWidth();
float writingHeight = rectSpaceBox.getHeight();
Rectangle remaining = doc.getRenderer().getCurrentArea().getBBox();
float yReal = remaining.getTop() + 2f;// orig 4f
float sizet = 0;
for (int i = 0; i < root.getChildren().size(); i++) {
IElement e = root.getChildren().get(i);
if (e.equals(space)) {
break;
}
IRenderer ss = e.createRendererSubTree().setParent(doc.getRenderer());
LayoutResult ss2 = ss.layout(new LayoutContext(new LayoutArea(1, new Rectangle(width, height))));
sizet += ss.getOccupiedArea().getBBox().getWidth();
}
float start = sizet+doc.getLeftMargin();
if(isCentred)
start = (width - getRealWidth(doc, root,width,height))/2+doc.getLeftMargin()+sizet;
Rectangle towr = new Rectangle(start, yReal, writingWidth, writingHeight);// sizet+doc.getLeftMargin()
PdfCanvas pdfcanvas = new PdfCanvas(document.getFirstPage());
Canvas canvas = new Canvas(pdfcanvas, towr);
canvas.setTextAlignment(TextAlignment.CENTER);
canvas.setHorizontalAlignment(HorizontalAlignment.CENTER);
Paragraph paragraph = new Paragraph(str).setTextAlignment(TextAlignment.CENTER).setBold();//.setMultipliedLeading(0.9f);//setbold oprtional
Div lineDiv = new Div();
lineDiv.setVerticalAlignment(VerticalAlignment.MIDDLE);
lineDiv.add(paragraph);
float fontSizeL = 0.0001f, fontSizeR= 10000;
int adjust = 0;
while (Math.abs(fontSizeL - fontSizeR) > 1e-1) {
float curFontSize = (fontSizeL + fontSizeR) / 2;
lineDiv.setFontSize(curFontSize);
// It is important to set parent for the current element renderer to a root
// renderer
IRenderer renderer = lineDiv.createRendererSubTree().setParent(canvas.getRenderer());
LayoutContext context = new LayoutContext(new LayoutArea(1, towr));
if (renderer.layout(context).getStatus() == LayoutResult.FULL) {
// we can fit all the text with curFontSize
fontSizeL = curFontSize;
if (++adjust>1)
towr.setHeight(towr.getHeight()-0.90f);
} else {
fontSizeR = curFontSize;
}
}
lineDiv.setFontSize(fontSizeL);
canvas.add(lineDiv);
new PdfCanvas(document.getFirstPage()).rectangle(towr).setStrokeColor(ColorConstants.BLACK).stroke();
canvas.close();
}
public static Text addTab() {
StringBuilder sb = new StringBuilder();
for(int i = 0;i<8;i++)
sb.append("\u00a0");
return new Text(sb.toString());
}
public static float getRealWidth (Document doc, Paragraph root,float width,float height) {
float sizet = 0;
for(int i = 0;i<root.getChildren().size();i++) {
IElement e = root.getChildren().get(i);
IRenderer ss = e.createRendererSubTree().setParent(doc.getRenderer());
LayoutResult ss2 = ss.layout(new LayoutContext(new LayoutArea(1, new Rectangle(width,height))));
sizet +=ss.getOccupiedArea().getBBox().getWidth();
}
return sizet;
}
private static Paragraph getEmptySpace(int size) {
Paragraph space = new Paragraph();
space.setMaxWidth(size);
for(int i=0;i<size;i++) {
// par.add("\u00a0");
space.add("\u00a0");
}
return space;
}
private static class LineCountingParagraph extends Paragraph {
private int linesWritten = 0;
public LineCountingParagraph(String text) {
super(text);
}
public void addWrittenLines(int toAdd) {
linesWritten += toAdd;
}
public int getNumberOfWrittenLines() {
return linesWritten;
}
#Override
protected IRenderer makeNewRenderer() {
return new LineCountingParagraphRenderer(this);
}
}
private static class LineCountingParagraphRenderer extends ParagraphRenderer {
public LineCountingParagraphRenderer(LineCountingParagraph modelElement) {
super(modelElement);
}
#Override
public void drawChildren(DrawContext drawContext) {
((LineCountingParagraph)modelElement).addWrittenLines(lines.size());
super.drawChildren(drawContext);
}
#Override
public IRenderer getNextRenderer() {
return new LineCountingParagraphRenderer((LineCountingParagraph) modelElement);
}
}
}
The issue: in the top half of the PDF you can see the result of two LineCountingParagraph instances being created, one per line. In the bottom half of the PDF you can see the result when only one instance of LineCountingParagraph is created. So fitting the text in boxes does not work well in case content of the paragraph wraps to the next line.
You have unnecessarily complicated things in such a way that we have to start from scratch :)
So the goal is to be able to create paragraphs with boxed intrusions of fixed width, where we need to copy-fit (place) some text, making sure the font size is selected in such a way that the text fits into that box.
The result should look similar to this picture:
The idea is that we will add paragraphs of fixed width into our main paragraph (iText allows adding block elements and a paragraph is a block element - into paragraphs). The fixed width will be guaranteed by the contents of our paragraph - it will just contain non-breakable spaces. Our paragraph will actually be backed by another paragraph with the actual content we want to fit into our wrapping paragraph. During the layout of the wrapping paragraph we will know its effective boundary and we will just use that area to determine the right font size for our content paragraph using binary search algorithm. Once the right font size has been determined we will just make sure the paragraph with the content gets drawn right next to our wrapping paragraph.
The code for our wrapping paragraph is pretty simple. It just expects the underlying paragraph with real content as the parameter. As always with iText layout, we should customize the renderer of our autoscaling paragraph:
private static class AutoScalingParagraph extends Paragraph {
Paragraph innerParagraph;
public AutoScalingParagraph(Paragraph innerParagraph) {
this.innerParagraph = innerParagraph;
}
#Override
protected IRenderer makeNewRenderer() {
return new AutoScalingParagraphRenderer(this);
}
}
private static class AutoScalingParagraphRenderer extends ParagraphRenderer {
private IRenderer innerRenderer;
public AutoScalingParagraphRenderer(AutoScalingParagraph modelElement) {
super(modelElement);
}
#Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult baseResult = super.layout(layoutContext);
this.innerRenderer = ((AutoScalingParagraph)modelElement).innerParagraph.createRendererSubTree().setParent(this);
if (baseResult.getStatus() == LayoutResult.FULL) {
float fontSizeL = 0.0001f, fontSizeR= 10000;
while (Math.abs(fontSizeL - fontSizeR) > 1e-1) {
float curFontSize = (fontSizeL + fontSizeR) / 2;
this.innerRenderer.setProperty(Property.FONT_SIZE, UnitValue.createPointValue(curFontSize));
if (this.innerRenderer.layout(new LayoutContext(getOccupiedArea().clone())).getStatus() == LayoutResult.FULL) {
// we can fit all the text with curFontSize
fontSizeL = curFontSize;
} else {
fontSizeR = curFontSize;
}
}
this.innerRenderer.setProperty(Property.FONT_SIZE, UnitValue.createPointValue(fontSizeL));
this.innerRenderer.layout(new LayoutContext(getOccupiedArea().clone()));
}
return baseResult;
}
#Override
public void drawChildren(DrawContext drawContext) {
super.drawChildren(drawContext);
innerRenderer.draw(drawContext);
}
#Override
public IRenderer getNextRenderer() {
return new AutoScalingParagraphRenderer((AutoScalingParagraph) modelElement);
}
}
Now we add the helper function for creating our wrapper paragraphs that just accepts the desired paragraph width in spaces and the underlying content we want to fit into that space:
private static Paragraph createAdjustableParagraph(int widthInSpaces, Paragraph innerContent) {
AutoScalingParagraph paragraph = new AutoScalingParagraph(innerContent);
paragraph.setBorder(new SolidBorder(1));
StringBuilder sb = new StringBuilder();
for(int i=0;i<widthInSpaces;i++) {
sb.append("\u00a0");
}
paragraph.add(sb.toString());
return paragraph;
}
Finally, the main code:
PdfWriter writer = new PdfWriter(new File("test4.pdf"));
PdfDocument document = new PdfDocument(writer);
Document doc = new Document(document);
Paragraph paragraphTest = new Paragraph();
Text testch01 = new Text("This is the 2nd example ");
paragraphTest.add(testch01);
paragraphTest.add(createAdjustableParagraph(42, new Paragraph("with insertion str")));
Text testch02 = new Text(" that doesn't work ");
paragraphTest.add(testch02);
paragraphTest.add(createAdjustableParagraph(53, new Paragraph("because next text goes next line")));
Text testch04 = new Text(" this next goes to the next line but ");
paragraphTest.add(testch04);
paragraphTest.add(createAdjustableParagraph(42, new Paragraph("this text")));
Text testch05 = new Text(" won't appear !!");
paragraphTest.add(testch05);
doc.add(paragraphTest);
doc.close();
Which gives us the following result:
So we just have the one main paragraph which contains some content and our paragraph wrappers, which in tern have the underlying content we want to fit.
Hint: centering the text is very easy, you don't need to calculate coordinates etc. Just set the right property to the paragraph with the content that you feed to your wrapper paragraph:
paragraphTest.add(createAdjustableParagraph(42, new Paragraph("this text").setTextAlignment(TextAlignment.CENTER)));
And you get the result:

Could someone give me an example of how to extract coordinates for a 'word' using PDFBox

Could someone give me an example of how to extract coordinates for a 'word' with PDFBox
I am using this link to extract positions of individual characters:
https://www.tutorialkart.com/pdfbox/how-to-extract-coordinates-or-position-of-characters-in-pdf/
I am using this link to extract words:
https://www.tutorialkart.com/pdfbox/extract-words-from-pdf-document/
I am stuck getting coordinates for whole words.
You can extract the coordinates of words by collecting all the TextPosition objects building a word and combining their bounding boxes.
Implementing this along the lines of the two tutorials you referenced, you can extend PDFTextStripper like this:
public class GetWordLocationAndSize extends PDFTextStripper {
public GetWordLocationAndSize() throws IOException {
}
#Override
protected void writeString(String string, List<TextPosition> textPositions) throws IOException {
String wordSeparator = getWordSeparator();
List<TextPosition> word = new ArrayList<>();
for (TextPosition text : textPositions) {
String thisChar = text.getUnicode();
if (thisChar != null) {
if (thisChar.length() >= 1) {
if (!thisChar.equals(wordSeparator)) {
word.add(text);
} else if (!word.isEmpty()) {
printWord(word);
word.clear();
}
}
}
}
if (!word.isEmpty()) {
printWord(word);
word.clear();
}
}
void printWord(List<TextPosition> word) {
Rectangle2D boundingBox = null;
StringBuilder builder = new StringBuilder();
for (TextPosition text : word) {
Rectangle2D box = new Rectangle2D.Float(text.getXDirAdj(), text.getYDirAdj(), text.getWidthDirAdj(), text.getHeightDir());
if (boundingBox == null)
boundingBox = box;
else
boundingBox.add(box);
builder.append(text.getUnicode());
}
System.out.println(builder.toString() + " [(X=" + boundingBox.getX() + ",Y=" + boundingBox.getY()
+ ") height=" + boundingBox.getHeight() + " width=" + boundingBox.getWidth() + "]");
}
}
(ExtractWordCoordinates inner class)
and run it like this:
PDDocument document = PDDocument.load(resource);
PDFTextStripper stripper = new GetWordLocationAndSize();
stripper.setSortByPosition( true );
stripper.setStartPage( 0 );
stripper.setEndPage( document.getNumberOfPages() );
Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
stripper.writeText(document, dummy);
(ExtractWordCoordinates test testExtractWordsForGoodJuJu)
Applied to the apache.pdf example the tutorials use you get:
2017-8-6 [(X=26.004425048828125,Y=22.00372314453125) height=5.833024024963379 width=36.31868362426758]
Welcome [(X=226.44479370117188,Y=22.00372314453125) height=5.833024024963379 width=36.5999755859375]
to [(X=265.5881652832031,Y=22.00372314453125) height=5.833024024963379 width=8.032623291015625]
The [(X=276.1641845703125,Y=22.00372314453125) height=5.833024024963379 width=14.881439208984375]
Apache [(X=293.5890197753906,Y=22.00372314453125) height=5.833024024963379 width=29.848846435546875]
Software [(X=325.98126220703125,Y=22.00372314453125) height=5.833024024963379 width=35.271636962890625]
Foundation! [(X=363.7962951660156,Y=22.00372314453125) height=5.833024024963379 width=47.871429443359375]
Custom [(X=334.0334777832031,Y=157.6195068359375) height=4.546705722808838 width=25.03936767578125]
Search [(X=360.8929138183594,Y=157.6195068359375) height=4.546705722808838 width=22.702728271484375]
You can create CustomPDFTextStripper which extends PDFTextStripper and override protected void writeString(String text, List<TextPosition> textPositions). In this overriden method you need to split textPositions by the word separator to get List<TextPosition> for each word. After that you can join each character and compute bounding box.
Full example below which contains also drawing of the resulting bounding boxes.
package com.example;
import lombok.Value;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import org.junit.Ignore;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PdfBoxTest {
private static final String BASE_DIR_PATH = "C:\\Users\\Milan\\50330484";
private static final String INPUT_FILE_PATH = "input.pdf";
private static final String OUTPUT_IMAGE_PATH = "output.jpg";
private static final String OUTPUT_BBOX_IMAGE_PATH = "output-bbox.jpg";
private static final float FROM_72_TO_300_DPI = 300.0f / 72.0f;
#Test
public void run() throws Exception {
pdfToImage();
drawBoundingBoxes();
}
#Ignore
#Test
public void pdfToImage() throws IOException {
PDDocument document = PDDocument.load(new File(BASE_DIR_PATH, INPUT_FILE_PATH));
PDFRenderer renderer = new PDFRenderer(document);
BufferedImage image = renderer.renderImageWithDPI(0, 300);
ImageIO.write(image, "JPEG", new File(BASE_DIR_PATH, OUTPUT_IMAGE_PATH));
}
#Ignore
#Test
public void drawBoundingBoxes() throws IOException {
PDDocument document = PDDocument.load(new File(BASE_DIR_PATH, INPUT_FILE_PATH));
List<WordWithBBox> words = getWords(document);
draw(words);
}
private List<WordWithBBox> getWords(PDDocument document) throws IOException {
CustomPDFTextStripper customPDFTextStripper = new CustomPDFTextStripper();
customPDFTextStripper.setSortByPosition(true);
customPDFTextStripper.setStartPage(0);
customPDFTextStripper.setEndPage(1);
Writer writer = new OutputStreamWriter(new ByteArrayOutputStream());
customPDFTextStripper.writeText(document, writer);
List<WordWithBBox> words = customPDFTextStripper.getWords();
return words;
}
private void draw(List<WordWithBBox> words) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File(BASE_DIR_PATH, OUTPUT_IMAGE_PATH));
Graphics2D graphics = bufferedImage.createGraphics();
graphics.setColor(Color.GREEN);
List<Rectangle> rectangles = words.stream()
.map(word -> new Rectangle(word.getX(), word.getY(), word.getWidth(), word.getHeight()))
.collect(Collectors.toList());
rectangles.forEach(graphics::draw);
graphics.dispose();
ImageIO.write(bufferedImage, "JPEG", new File(BASE_DIR_PATH, OUTPUT_BBOX_IMAGE_PATH));
}
private class CustomPDFTextStripper extends PDFTextStripper {
private final List<WordWithBBox> words;
public CustomPDFTextStripper() throws IOException {
this.words = new ArrayList<>();
}
public List<WordWithBBox> getWords() {
return new ArrayList<>(words);
}
#Override
protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
String wordSeparator = getWordSeparator();
List<TextPosition> wordTextPositions = new ArrayList<>();
for (TextPosition textPosition : textPositions) {
String str = textPosition.getUnicode();
if (wordSeparator.equals(str)) {
if (!wordTextPositions.isEmpty()) {
this.words.add(createWord(wordTextPositions));
wordTextPositions.clear();
}
} else {
wordTextPositions.add(textPosition);
}
}
super.writeString(text, textPositions);
}
private WordWithBBox createWord(List<TextPosition> wordTextPositions) {
String word = wordTextPositions.stream()
.map(TextPosition::getUnicode)
.collect(Collectors.joining());
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
for (TextPosition wordTextPosition : wordTextPositions) {
minX = Math.min(minX, from72To300Dpi(wordTextPosition.getXDirAdj()));
minY = Math.min(minY, from72To300Dpi(wordTextPosition.getYDirAdj() - wordTextPosition.getHeightDir()));
maxX = Math.max(maxX, from72To300Dpi(wordTextPosition.getXDirAdj() + wordTextPosition.getWidthDirAdj()));
maxY = Math.max(maxY, from72To300Dpi(wordTextPosition.getYDirAdj()));
}
return new WordWithBBox(word, minX, minY, maxX - minX, maxY - minY);
}
}
private int from72To300Dpi(float f) {
return Math.round(f * FROM_72_TO_300_DPI);
}
#Value
private class WordWithBBox {
private final String word;
private final int x;
private final int y;
private final int width;
private final int height;
}
}
Note:
If you are interested in other options, you can check also Poppler
PDF to image
pdftoppm -r 300 -jpeg input.pdf output
Generate an XHTML file containing bounding box information for each word in the file.
pdftotext -r 300 -bbox input.pdf

GWT - cells values after Button ClickEvent in whole table the same

My GWT-project is a simple calendar. You can add a date by clicking on a table cell, which is opening a dialog to enter a name and the description.
The date will wrote to the tablecell, when you click on "OK" or cancel with "Abbrechen".
My code (build in Eclipse):
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.RootPanel;
public class ShowCase implements EntryPoint {
int a = 24; // Anzahl Zeit-Zeilen (Normalfall 24 -> 0:00 - 23:00)
int start = 7;
int end = 21;
DecoratorPanel panel = new DecoratorPanel();
Grid t = new Grid((a + 1), 8); //
String days[] = { " ", "Montag", "Dienstag", "Mittwoch", "Donnerstag",
"Freitag", "Samstag", "Sonntag" };
String data = null, str1 = null, str2 = null;
DialogBox dialog = new DialogBox();
Grid dialoggrid = new Grid(3, 2); // Grid-Layout für gesamte DialogBox
Label lname = new Label("Name");
Label lbeschr = new Label("Beschreibung");
TextBox tbname = new TextBox();
TextBox tbbeschr = new TextBox();
Button ok = new Button("OK");
Button cancel = new Button("Abbrechen");
int indexrow, indexcol;
DialogBox leer = new DialogBox();
Button okleer = new Button("OK");
public void onModuleLoad() {
t.setBorderWidth(1);
t.setCellSpacing(0);
for (int row = 0; row < (a + 1); row++) {
for (int col = 0; col < 8; col++) {
if (col == 0) {
int z = row - 1;
System.out.println("Spalte 0 Zeit setzen: " + row);
t.setText(row, col, z + ":00"); // Spalte 0 Zeit setzen
} else {
t.setText(row, col, "");
}
t.setText(0, col, days[col]); // Tage aus days in Zeile 0 setzen
t.getCellFormatter().setWidth(row, 0, "50px");
t.getCellFormatter().setWidth(row, col, "150px");
}
} // end for(int row=0...)
panel.add(t);
RootPanel.get("content").add(panel);
t.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("Neuer Klick!");
Cell cell = ((HTMLTable) event.getSource()).getCellForEvent(event);
System.out.println("Cell cell HTML Table");
/*if (data.equals("1")){
tbname.setText(text);
tbbeschr.setText(null);
}*/
System.out.println("data1: " + data);
// Uhrzeit-Spalte und Wochentagsreihe absichern
if(!(cell.getRowIndex() == 0) && !(cell.getCellIndex() ==0)){
System.out.println("Get Index(): " + cell.getRowIndex() + "," + cell.getCellIndex()); // Ausgabe von Reihe und Spalte
final int indexrow = cell.getRowIndex();
final int indexcol = cell.getCellIndex();
// Dialog belegen und anzeigen
dialoggrid.setCellSpacing(0);
dialoggrid.setCellPadding(0);
tbname.setText(null);
tbbeschr.setText(null);
System.out.println("TBName: " + tbname.getText());
System.out.println("TBBeschr: " + tbbeschr.getText());
dialoggrid.setWidget(0, 0, lname);
dialoggrid.setWidget(1, 0, lbeschr);
dialoggrid.setWidget(2, 0, ok);
dialoggrid.setWidget(0, 1, tbname);
dialoggrid.setWidget(1, 1, tbbeschr);
dialoggrid.setWidget(2, 1, cancel);
dialog.setWidget(dialoggrid);
dialog.center();
dialog.setModal(false);
if(tbname.getText().equals(null)){
System.out.println("if tbname.getText equals null");
}
System.out.println("Dialog show");
dialog.show();
ok.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("ok Click");
// Überprüfen ob TextBox Name und Beschreibung nicht leer sind
if ((!tbname.getText().equals(null)) && (!tbbeschr.getText().equals(null))) {
System.out.println("Wenn tbname & tbbeschr nicht leer sind");
str1 = tbname.getText();
str2 = tbbeschr.getText();
data = str1 + ", " + str2;
t.setText(indexrow, indexcol, data);
dialog.hide();
System.out.println("#1: "+data+"#");
data = null;
System.out.println("#2: "+data+"#");
} else {
System.out.println("leer!");
leer.setText("Felder duerfen nicht leer sein!");
leer.add(okleer);
leer.center();
leer.setModal(true);
leer.show();
okleer.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event){
System.out.println("okleer click");
leer.hide();
}
});
} // end else
}
}); // end ok.addClickHandler
cancel.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("cancel Click");
dialog.hide();
tbname.setText(null);
tbbeschr.setText(null);
}
}); // end cancel.addClickHandler
} // end if(!(cellindex) && !(rowindex) =0 )
} // end public void OnClick()
}); // end t.addClickHandler
} // end onModuleLoad(}
The problem is, that, by entering the name & description in the dialog and click "OK", it overwrites all clicked cells (also the canceled dialog cells) with the values from my current dialog.
Some testcases with output in the console (by OK-Click it makes even more OK-Clicks for each clicked cell):
Neuer Klick!
Cell cell HTML Table
data1: null
Get Index(): 1,1
TBName:
TBBeschr:
Dialog show
ok Click
Wenn tbname & tbbeschr nicht leer sind
#1: rt, qw#
#2: null#
Neuer Klick!
Cell cell HTML Table
data1: null
Get Index(): 1,2
TBName:
TBBeschr:
Dialog show
ok Click
Wenn tbname & tbbeschr nicht leer sind
#1: gh, tz#
#2: null#
ok Click
Wenn tbname & tbbeschr nicht leer sind
#1: gh, tz#
#2: null#
Why? Or is there a better possibility to "manage" the code?
You need to use HandlerRegistration for your Click handler. As you are not clearing the the click handler, that is why it is calling the earlier events also..
Refer below links for further details:
GWT HandlerRegistration
similar issue
It seems you are quite new to GWT. Here is the working solution:
package com.my.first.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class ShowCase implements EntryPoint {
int a = 24; // Anzahl Zeit-Zeilen (Normalfall 24 -> 0:00 - 23:00)
int start = 7;
int end = 21;
DecoratorPanel panel = new DecoratorPanel();
Grid t = new Grid((a + 1), 8); //
String days[] = { " ", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" };
String data = null, str1 = null, str2 = null;
DialogBox dialog = new DialogBox();
Grid dialoggrid = new Grid(3, 2); // Grid-Layout für gesamte DialogBox
Label lname = new Label("Name");
Label lbeschr = new Label("Beschreibung");
TextBox tbname = new TextBox();
TextBox tbbeschr = new TextBox();
Button ok = new Button("OK");
Button cancel = new Button("Abbrechen");
HandlerRegistration okHandlerRegistration;
int indexrow, indexcol;
DialogBox leer = new DialogBox();
Button okleer = new Button("OK");
public void onModuleLoad() {
t.setBorderWidth(1);
t.setCellSpacing(0);
for (int row = 0; row < (a + 1); row++) {
for (int col = 0; col < 8; col++) {
if (col == 0) {
int z = row - 1;
System.out.println("Spalte 0 Zeit setzen: " + row);
t.setText(row, col, z + ":00"); // Spalte 0 Zeit setzen
} else {
t.setText(row, col, "");
}
t.setText(0, col, days[col]); // Tage aus days in Zeile 0 setzen
t.getCellFormatter().setWidth(row, 0, "50px");
t.getCellFormatter().setWidth(row, col, "150px");
}
} // end for(int row=0...)
panel.add(t);
RootPanel.get("content").add(panel);
t.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("Neuer Klick!");
Cell cell = ((HTMLTable) event.getSource()).getCellForEvent(event);
System.out.println("Cell cell HTML Table");
/*
* if (data.equals("1")){ tbname.setText(text);
* tbbeschr.setText(null); }
*/
System.out.println("data1: " + data);
// Uhrzeit-Spalte und Wochentagsreihe absichern
if (!(cell.getRowIndex() == 0) && !(cell.getCellIndex() == 0)) {
System.out.println("Get Index(): " + cell.getRowIndex() + "," + cell.getCellIndex()); // Ausgabe
// von
// Reihe
// und
// Spalte
final int indexrow = cell.getRowIndex();
final int indexcol = cell.getCellIndex();
// Dialog belegen und anzeigen
dialoggrid.setCellSpacing(0);
dialoggrid.setCellPadding(0);
tbname.setText(null);
tbbeschr.setText(null);
System.out.println("TBName: " + tbname.getText());
System.out.println("TBBeschr: " + tbbeschr.getText());
dialoggrid.setWidget(0, 0, lname);
dialoggrid.setWidget(1, 0, lbeschr);
dialoggrid.setWidget(2, 0, ok);
dialoggrid.setWidget(0, 1, tbname);
dialoggrid.setWidget(1, 1, tbbeschr);
dialoggrid.setWidget(2, 1, cancel);
dialog.setWidget(dialoggrid);
dialog.center();
dialog.setModal(false);
if (tbname.getText().equals(null)) {
System.out.println("if tbname.getText equals null");
}
System.out.println("Dialog show");
dialog.show();
if (okHandlerRegistration != null) {
okHandlerRegistration.removeHandler();
}
okHandlerRegistration = ok.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("ok Click");
// Überprüfen ob TextBox Name und Beschreibung nicht
// leer sind
if ((!tbname.getText().equals(null)) && (!tbbeschr.getText().equals(null))) {
System.out.println("Wenn tbname & tbbeschr nicht leer sind");
str1 = tbname.getText();
str2 = tbbeschr.getText();
data = str1 + ", " + str2;
t.setText(indexrow, indexcol, data);
dialog.hide();
System.out.println("#1: " + data + "#");
data = null;
System.out.println("#2: " + data + "#");
} else {
System.out.println("leer!");
leer.setText("Felder duerfen nicht leer sein!");
leer.add(okleer);
leer.center();
leer.setModal(true);
leer.show();
okleer.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("okleer click");
leer.hide();
}
});
} // end else
}
}); // end ok.addClickHandler
cancel.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
System.out.println("cancel Click");
dialog.hide();
tbname.setText(null);
tbbeschr.setText(null);
}
}); // end cancel.addClickHandler
} // end if(!(cellindex) && !(rowindex) =0 )
} // end public void OnClick()
}); // end t.addClickHandler
} // end onModuleLoad(}
}

Google maps API v2 Android, not drawing polygon when offline

I have a test application that I draw a Polygon using google maps API.
The problem is that, when I have no cache of any maps (new installed application) the Polygon does not draw.
Its not a problem not having the maps loaded, but I do need the Polygons drawn in my screen.
Is there a way I can do that?
Sry for my bad english
Heres the code I have:
package ngvl.testegmaps_v2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import ngvl.testegmaps_v2.VO.GeoPosicionamento;
import ngvl.testegmaps_v2.VO.Layer;
import ngvl.testegmaps_v2.VO.Secao;
import ngvl.testegmaps_v2.VO.Talhao;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class MainActivity extends FragmentActivity {
private List<Secao> secoes;
private List<Polygon> poligonos = new ArrayList<Polygon>();
private HashMap<String,Object[]> informacoes = new HashMap<String,Object[]>();
private GoogleMap map;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
map = fragment.getMap();
map.getUiSettings().setRotateGesturesEnabled(false);
// Setting a click event handler for the map
LatLng latLng = new LatLng(-20.9957152, -47.3241304);
// map.addMarker(new
// MarkerOptions().position(latLng).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)).title("Av. Paulista").snippet("São Paulo"));
configuraPosicao(map, latLng);
Button button = (Button)findViewById(R.id.button1);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
}
private void configuraPosicao(GoogleMap map, LatLng latLng) {
/*
* 3D map.moveCamera( CameraUpdateFactory.newLatLngZoom(latLng, 15));
* map.animateCamera( CameraUpdateFactory.zoomTo(10), 2000, null);
*
* CameraPosition cameraPosition = new CameraPosition.Builder()
* .target(latLng) .zoom(17) .bearing(90) .tilt(45) .build();
*
* map.animateCamera( CameraUpdateFactory.newCameraPosition(
* cameraPosition));
*/
map.setMapType(GoogleMap.MAP_TYPE_NONE);
// map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17.0f));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
try {
String json = readFileAsString("geo.json");
Gson gson = new Gson();
this.secoes = gson.fromJson(json, new TypeToken<List<Secao>>() {
}.getType());
json = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
escrevePoligons(map);
}
private String readFileAsString(String fileName) throws IOException {
InputStream is = getAssets().open(fileName);
if (is != null) {
StringBuilder sb = new StringBuilder();
String line;
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "UTF-8"));
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} finally {
is.close();
}
return sb.toString();
} else {
return "";
}
}
private void escrevePoligons(GoogleMap map) {
float stroke = (float) 1.5;
for (Secao secao : secoes) {
for (Talhao talhao : secao.getTalhoes()) {
for (Layer layer : talhao.getLayers()) {
// PolygonOptions rectOptions = new PolygonOptions();
List<LatLng> latlngs = new ArrayList<LatLng>();
for (GeoPosicionamento geoPosicionamento : layer.getGeoPosicionamentos()) {
latlngs.add(new LatLng(geoPosicionamento.getLatitude()
.setScale(7, BigDecimal.ROUND_HALF_EVEN)
.doubleValue(), geoPosicionamento
.getLongitude()
.setScale(7, BigDecimal.ROUND_HALF_EVEN)
.doubleValue()));
}
int color = 0x1F00FF00;
int color2 = 0x5F000000;
PolygonOptions polygonOptions = new PolygonOptions()
.fillColor(color).addAll(latlngs)
.strokeColor(color2).strokeWidth(stroke);
Polygon p = map.addPolygon(polygonOptions);
poligonos.add(p);
informacoes.put( p.getId(), new Object[]{ secao, talhao , layer } );
//System.out.println(polygonOptions.getPoints());
polygonOptions = null;
latlngs = null;
}
}
}
this.secoes = null;
// String mUrl =
// "https://khms0.google.com.br/kh/v=124&src=app&z={z}&x={x}&y={y}";
// MyUrlTileProvider mTileProvider = new MyUrlTileProvider(256, 256,
// mUrl);
// mTileProvider.tilesRange();
// map.addTileOverlay(new
// TileOverlayOptions().tileProvider(mTileProvider).zIndex(-1f));
//String mUrl = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png";
//MyUrlTileProvider mTileProvider = new MyUrlTileProvider(256, 256, mUrl);
//map.addTileOverlay(new TileOverlayOptions().tileProvider(mTileProvider).zIndex(-1f));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-20.9957152, -47.3241304), 14));
// TileProvider tileProvider = TileProviderFactory.getTileProvider();
// map.addTileOverlay(new
// TileOverlayOptions().tileProvider(tileProvider));
// map.moveCamera(CameraUpdateFactory.newLatLngZoom(new
// LatLng(-20.9957152, -47.3241304), 15));
map.setOnMapClickListener(new OnMapClickListener()
{
public void onMapClick(LatLng point)
{
Polygon p = isPointInPolygon(point);
if( p != null){
p.setFillColor(getRandomColor());
Object[] clicado = informacoes.get( p.getId() );
Secao secao_clicada = (Secao) clicado[0];
Talhao talhao_clicada = (Talhao) clicado[1];
Layer layer_clicada = (Layer) clicado[2];
//System.out.println(secao_clicada);
//System.out.println(talhao_clicada);
//System.out.println(layer_clicada);
//System.out.println("=======================");
StringBuilder texto = new StringBuilder();
texto.append("Seção: " + secao_clicada.getDesc() + "\n");
texto.append("Talhão: " + talhao_clicada.getTalhao() + "\n");
texto.append("Variedade: " + talhao_clicada.getVariedade() + " - " + talhao_clicada.getDescVariedade() + "\n");
texto.append("Layer: " + layer_clicada.getSequencia() + "\n");
//Toast.makeText(MainActivity.this, texto , Toast.LENGTH_LONG).show();
addMarker(point,texto);
}//else
//Toast.makeText(MainActivity.this,"Clicou fora da Área de um Poligono", Toast.LENGTH_LONG).show();
}
});
}
public void addMarker(LatLng point, StringBuilder texto) {
/*map.addMarker(new MarkerOptions().position(point).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
.title("Caracteristicas: ")
.snippet( texto );
*/
Toast.makeText(MainActivity.this, texto , Toast.LENGTH_LONG).show();
}
private Polygon isPointInPolygon(LatLng tap) {
for( Polygon p : poligonos){
int intersectCount = 0;
List<LatLng> vertices = p.getPoints();
for(int j=0; j<vertices.size()-1; j++) {
if( rayCastIntersect(tap, vertices.get(j), vertices.get(j+1)) ) {
intersectCount++;
}
}
if(((intersectCount % 2) == 1)){
return p;
}
}
return null;// odd = inside, even = outside;
}
private boolean rayCastIntersect(LatLng tap, LatLng vertA, LatLng vertB) {
double aY = vertA.latitude;
double bY = vertB.latitude;
double aX = vertA.longitude;
double bX = vertB.longitude;
double pY = tap.latitude;
double pX = tap.longitude;
if ( (aY>pY && bY>pY) || (aY<pY && bY<pY) || (aX<pX && bX<pX) ) {
return false; // a and b can't both be above or below pt.y, and a or b must be east of pt.x
}
double m = (aY-bY) / (aX-bX); // Rise over run
double bee = (-aX) * m + aY; // y = mx + b
double x = (pY - bee) / m; // algebra is neat!
return x > pX;
}
private OnClickListener mCorkyListener = new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-20.9957152, -47.3241304), 14));
}
};
public int getRandomColor() {
int color;
Random rnd = new Random();
color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256),
rnd.nextInt(256));
return color;
}
}
Setting map type to MAP_TYPE_NONE like example above does not solve the problem
I will this as marked solved by using Maps Forge Open Source API
If someone did with Google Maps Api please share and I would change the answer.
The answer I found is that its impossible to render or access anything without rendering the map first (online or via cache)
This is actually a bug of GoogleMaps Api v2 for Android.
It is referenced here:
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5017
Star it if you want to accelerate the bug fix!

Change y-axis format of GWT Visualization from milliseconds to hr:min:sec

I am currently generating LineChart graphs with the GWT Visualization library that show the run time of a set of jobs. The time values are in milliseconds and I would like the graph to display the y-axis labels in hr:min:sec format instead of milliseconds. I have used the setFormattedValue method to make this conversion, but unfortunately, only the tooltip values display the formatted value while the y-axis continues to display in milliseconds.
Here's my code:
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import com.electriccloud.commander.gwt.client.util.CommanderUrlBuilder;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.Table;
import com.google.gwt.visualization.client.visualizations.corechart.HorizontalAxisOptions;
import com.google.gwt.visualization.client.visualizations.corechart.LineChart;
public class ScheduledJobMonitorFancyChartPanel extends HorizontalPanel{
protected static final int MS = 0;
protected static final int HR_MIN_SEC = 1;
private String scheduleName;
private HashMap<String, AverageElapsedTime> elapsedTimeData;
private Table dataTable;
private LineChart lineChart;
private boolean graphIsVisible = true;
private int displayStyle;
public ScheduledJobMonitorFancyChartPanel(){
super();
this.setStyleName("hidden");
}
public ScheduledJobMonitorFancyChartPanel(String schedName, HashMap<String, AverageElapsedTime> data, int displayType){
this();
this.scheduleName = schedName;
this.elapsedTimeData = data;
this.displayStyle = displayType;
createTableAndChart();
this.setVisible(graphIsVisible);
}
private void createTableAndChart(){
// this block defines the table and chart
Runnable onLoadCallback = new Runnable() {
public void run() {
VerticalPanel outterPanel = new VerticalPanel();
Label chartTitle = new Label("ElapsedTime Data for " + scheduleName);
chartTitle.setStylePrimaryName("chartTitle");
outterPanel.add(chartTitle);
HorizontalPanel allChartGroups = new HorizontalPanel();
allChartGroups.setStylePrimaryName("allChartGroupsStyle");
// Since a single Job may have multiple steps being monitored, this creates the charts
// for each step, but groups them all (horizontally) under the same job
Collection<String> c = elapsedTimeData.keySet();
Iterator<String> itr = c.iterator();
while(itr.hasNext()){
String stepName = itr.next();
AverageElapsedTime aet = elapsedTimeData.get(stepName);
AbstractDataTable linkableTable = createTableWithLinks(aet);
AbstractDataTable table = createTable(aet);
dataTable = new Table(linkableTable, createDataTableOptions());
dataTable.setStylePrimaryName("dataTableStyle");
lineChart = new LineChart(table, createLineChartOptions(stepName));
lineChart.setStylePrimaryName("lineChartStyle");
HorizontalPanel tableAndChartGroup = new HorizontalPanel();
tableAndChartGroup.setStylePrimaryName("tableAndChartGroup");
tableAndChartGroup.add(dataTable);
tableAndChartGroup.add(lineChart);
allChartGroups.add(tableAndChartGroup);
}
outterPanel.add(allChartGroups);
addToPanel(outterPanel);
}
};
// this line gets the table/chart defined above displayed on the screen
VisualizationUtils.loadVisualizationApi(onLoadCallback, LineChart.PACKAGE, Table.PACKAGE);
}
// Because the table/chart is created inside an annonymous Runnable object, this method
// exposes it to being added to "this"
private void addToPanel(Widget widget){
this.add(widget);
}
// set up the table used by the LineChart
private AbstractDataTable createTable(AverageElapsedTime aet){
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "JobId");
data.addColumn(ColumnType.NUMBER, "ElapsedTime");
data.addRows(aet.getSize());
HashMap<Long, Long> jobIdElapsedTimeHash = aet.getListOfTimes();
Collection<Long> c = jobIdElapsedTimeHash.keySet();
Iterator<Long> itr = c.iterator();
int row = 0;
while(itr.hasNext()){
Long jobId = itr.next();
data.setValue(row, 0, jobId.toString());
if(this.displayStyle == ScheduledJobMonitorFancyChartPanel.MS)
data.setValue(row, 1, jobIdElapsedTimeHash.get(jobId));
else if(this.displayStyle == ScheduledJobMonitorFancyChartPanel.HR_MIN_SEC){
data.setValue(row, 1, jobIdElapsedTimeHash.get(jobId));
String formattedValue = AverageElapsedTime.getDisplayTime(jobIdElapsedTimeHash.get(jobId));
data.setFormattedValue(row, 1, formattedValue);
}
row++;
}
return data;
}
// set up the table used by the DataTable - It embeds links to the jobId listed
private AbstractDataTable createTableWithLinks(AverageElapsedTime aet){
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "JobId");
data.addColumn(ColumnType.NUMBER, "ElapsedTime");
data.addRows(aet.getSize());
HashMap<Long, Long> jobIdElapsedTimeHash = aet.getListOfTimes();
Collection<Long> c = jobIdElapsedTimeHash.keySet();
Iterator<Long> itr = c.iterator();
String urlBase = CommanderUrlBuilder.getBase();
int row = 0;
while(itr.hasNext()){
Long jobId = itr.next();
data.setValue(row, 0, "<a href='" + urlBase + "link/jobDetails/jobs/" + jobId + "' target='_blank'>" + jobId + "</a>");
// data.setValue(row, 1, jobIdElapsedTimeHash.get(jobId));
if(this.displayStyle == ScheduledJobMonitorFancyChartPanel.MS)
data.setValue(row, 1, jobIdElapsedTimeHash.get(jobId));
else if(this.displayStyle == ScheduledJobMonitorFancyChartPanel.HR_MIN_SEC){
data.setValue(row, 1, jobIdElapsedTimeHash.get(jobId));
String formattedValue = AverageElapsedTime.getDisplayTime(jobIdElapsedTimeHash.get(jobId));
data.setFormattedValue(row, 1, formattedValue);
}
row++;
}
return data;
}
// set the options for the DataTable
private Table.Options createDataTableOptions(){
Table.Options options = Table.Options.create();
options.setHeight("300");
options.setWidth("190");
options.setAllowHtml(true);
return options;
}
// set the options for the LineChart
private com.google.gwt.visualization.client.visualizations.corechart.Options createLineChartOptions(String stepName){
com.google.gwt.visualization.client.visualizations.corechart.Options options = com.google.gwt.visualization.client.visualizations.corechart.Options.create();
options.setWidth(500);
options.setHeight(300);
options.setCurveType("function");
options.setColors("#336E95");
options.setTitle(stepName);
HorizontalAxisOptions hao = HorizontalAxisOptions.create();
hao.setSlantedText(true);
hao.setSlantedTextAngle(45);
options.setHAxisOptions(hao);
return options;
}
public void setTimeDisplay(int displayType) {
switch(displayType){
case 0:
break;
case 1:
this.displayStyle = ScheduledJobMonitorFancyChartPanel.HR_MIN_SEC;
}
}
}
I don't have the code at hand.
Only, I remember that the documentation for Google Graphs API for GWT is far from completed. You only need to know that it's a wrapper over Google Graphs, the javascript library.
This means that some options you can set directly with setters, for some others you'll have to look into the JS library parameters and inject them somehow with the generic option setter (there's a method to set options on axis on a "string -> value" basis).
Here you can find a description of the JS library parameters:
https://developers.google.com/chart/interactive/docs/gallery/areachart#Data_Format
If you look at "hAxis.format", you'll probably find what you are looking for.
EDIT:
To complete my answer, you'll have to use the HorizontalAxisOptions class and its set method.
Beware that the format you send is tricky and not firing an error if it's wrong, but I would bet on set("hAxis.format", "{format:'HH:mm:ss'}");