How to infer a page break in a TextFlow? - javafx-8

I am trying to create a NotePad screen in my application. Once notes are created they are locked and unable to be edited, however new pages can be added to a note.
I thought that using the TextFlow would be a great control for this. What I would like to do is the following:
**Note Taker Name**
**Date of Note**
Line of Note Text
Line of Note Text
Line of Note Text
Line of Note Text
------------------------------------------
**Note Taker Name**
**Date of Note**
Line of Note Text
Line of Note Text
Line of Note Text
Line of Note Text
I have attempted it this way:
String s1 = "line of text";
textFlow.getChildren().add(new Text(s1));
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Separator(Orientation.HORIZONTAL));
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text(s1));
scrollPane.setFitToWidth(true);
This provides me pretty much what I want, except the separator is just a tiny line. I would like the line to cross the entire TextFlow and I wasn't really sure how to go about that.
Thanks.

There is already a JavaFX built in control for your needs: a Separator (javadoc).
#Override
public void start(Stage primaryStage) {
TextFlow textFlow = new TextFlow();
Text nameText = new Text("Taken By me ");
nameText.setFill(Color.CRIMSON);
textFlow.getChildren().add(nameText);
textFlow.getChildren().add(new Text(System.lineSeparator()));
Text takenOn = new Text("Taken On: " + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(LocalDateTime.now()));
takenOn.setFill(Color.CRIMSON);
textFlow.getChildren().add(takenOn);
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text("this is a note"));
textFlow.getChildren().add(new Text(System.lineSeparator()));
// Separator
final Separator separator = new Separator(Orientation.HORIZONTAL);
separator.prefWidthProperty().bind(textFlow.widthProperty());
separator.setStyle("-fx-background-color: red;");
textFlow.getChildren().add(separator);
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text("this is another note"));
Scene scene = new Scene(textFlow, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}

I found an answer that works - though I am not sure if this is the best way to handle it:
private void loadTextFlowWithNotes() {
textFlow.getChildren().clear();
notes.forEach(note -> {
Text nameText = new Text("Taken By: " + note.takenBy);
nameText.setFill(Color.CRIMSON);
textFlow.getChildren().add(nameText);
textFlow.getChildren().add(new Text(System.lineSeparator()));
Text takenOn = new Text("Taken On: " + note.takenOn.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)));
takenOn.setFill(Color.CRIMSON);
textFlow.getChildren().add(takenOn);
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text(note.noteText));
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text(System.lineSeparator()));
Line line = new Line();
line.setStartX(0);
line.endXProperty().bind(textFlow.widthProperty());
line.setFill(Color.CRIMSON);
textFlow.getChildren().add(line);
textFlow.getChildren().add(new Text(System.lineSeparator()));
textFlow.getChildren().add(new Text(System.lineSeparator()));
});
}

Related

How do I cut off one half of a PDF page?

I want to print a DHL label using a label printer.
The DHL label consists of 2 parts: The left half of the image is just info that I can keep to myself. The right part of the PDF is what should actually be printed.
I would therefore like to cut away the left part of the PDF.
I do not want to make it blank, but I really I want to cut if off.
How could I do this?
You essentially want to cut away one half of the PDF page; looking at you screenshot most likely the lower half.
Using iTextSharp 5.5.13.3 you can do that like this:
var testFile = #"new pdf1.pdf";
var resultFile = #"new pdf1-Cut.pdf";
using (PdfReader pdfReader = new PdfReader(testFile))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, File.Create(resultFile)))
{
for (int i = 1; i <= pdfReader.NumberOfPages; i++)
{
Rectangle cropBox = pdfReader.GetCropBox(i);
PdfArray newCropBox = new PdfArray(new float[] {
cropBox.Left, (cropBox.Bottom + cropBox.Top) / 2,
cropBox.Right, cropBox.Top });
PdfDictionary pageDictionary = pdfReader.GetPageN(i);
pageDictionary.Put(PdfName.CROPBOX, newCropBox);
pageDictionary.Put(PdfName.MEDIABOX, newCropBox);
}
}
(CutPages test CutInHalfForTmighty)
Before
After

How to draw label bigger size?

I am working with Unity and I try to output some info, in order to do this I draw label
void OnGUI()
{
GUI.Label(new Rect(10, 10, 300, 100), FpsDecoded.ToString("D3")+" FPS Decoded" + (buffereing?" Bufferring...":""));
}.
As a result I see label with output info, but problem is that size of this label very small...
and whatever I do, nothing work. I tried to apply different Rect sizes , but text size doesn't changes
What am I doing wrong?
Eventually I solved it this way
private GUIStyle guiStyle = new GUIStyle(); //create a new variable
void OnGUI()
{
guiStyle.fontSize = 20;
string text = FpsDecoded.ToString("D3") + " FPS Decoded" + (buffereing ? " Bufferring..." : "");
GUI.Label(new Rect(10, 10, 300, 100), text, guiStyle);
}

iTextSharp centering text on page

I cannot get the text to be centered on the page. What am I doing wrong? I have tried several ways to get the page with, but none seem to make the text centered on the page.....
BaseFont bf = BaseFont.CreateFont("c:\\windows\\fonts\\calibri.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfReader reader = new PdfReader("C:\\temp\\Certificate12.pdf");
var pageSize = reader.GetPageSize(1);
iTextSharp.text.Rectangle rec2 = new iTextSharp.text.Rectangle(PageSize.LETTER);
PdfStamper stamper = new PdfStamper(reader, stream1);
PdfContentByte canvas = stamper.GetUnderContent(1);
canvas.BeginText();
canvas.SetFontAndSize(bf, 24);
string nameText = "First Name Last Name";
int textWidth = (int)nameText.Length;
int canvasWidth = (int)canvas.PdfDocument.PageSize.Width;
float xStart = (canvasWidth / 2) - (textWidth / 2);
canvas.ShowTextAligned(PdfContentByte.ALIGN_CENTER, nameText, xStart, pageSize.GetTop(Utilities.MillimetersToPoints(145)), 0);
First of all, if you use ShowTextAligned with ALIGN_CENTER, iTextSharp will center the text for you, so you do not have to deal with the text width at all. You merely need to tell it to center the text on which center point.
Thus, you can center your text on the page like this:
BaseFont bf = BaseFont.CreateFont("c:\\windows\\fonts\\calibri.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create, FileAccess.Write)))
{
Rectangle pageSize = reader.GetPageSize(1);
PdfContentByte canvas = stamper.GetUnderContent(1);
string nameText = "First Name Last Name";
canvas.BeginText();
canvas.SetFontAndSize(bf, 24);
canvas.ShowTextAligned(PdfContentByte.ALIGN_CENTER, nameText, (pageSize.Left + pageSize.Right) / 2, pageSize.GetTop(Utilities.MillimetersToPoints(145)), 0);
canvas.EndText();
}

Page Header overlaps with Table

In itext, I have a table in my pdf. When the table gets full for a page the entries continues on the next page but it overlaps with my pdf page header. How do I avoid that?
Please take a look at the TableHeader example.
In this example, I create a document with some "Hello World" content:
public void createPdf(String filename) throws IOException, DocumentException {
TableHeader.HeaderTable event = new TableHeader.HeaderTable();
// step 1
Document document = new Document(PageSize.A4, 36, 36, 20 + event.getTableHeight(), 36);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
writer.setPageEvent(event);
// step 3
document.open();
// step 4
for (int i = 0; i < 50; i++)
document.add(new Paragraph("Hello World!"));
document.newPage();
document.add(new Paragraph("Hello World!"));
document.newPage();
document.add(new Paragraph("Hello World!"));
// step 5
document.close();
}
As you can see, I also define a TableHeader event. I use this event as a page event, but I also need this event when I define the Document. I use the following value as top margin:
20 + event.getTableHeight()
What does this mean? Let's take a look at the implementation of this event:
public class HeaderTable extends PdfPageEventHelper {
protected PdfPTable table;
protected float tableHeight;
public HeaderTable() {
table = new PdfPTable(1);
table.setTotalWidth(523);
table.setLockedWidth(true);
table.addCell("Header row 1");
table.addCell("Header row 2");
table.addCell("Header row 3");
tableHeight = table.getTotalHeight();
}
public float getTableHeight() {
return tableHeight;
}
public void onEndPage(PdfWriter writer, Document document) {
table.writeSelectedRows(0, -1,
document.left(),
document.top() + ((document.topMargin() + tableHeight) / 2),
writer.getDirectContent());
}
}
When I create the event, a PdfPTable is constructed. I store this table as a member variable, along with the height of this table: tableHeight.
I use this tableHeight when I define the top margin, so that I am 100% sure that the table will fit the margin. I add an additional 20 user units because I don't want the table to stick to the top border of the page:
20 + event.getTableHeight()
When I add the table in the onEndPage() method, I use the following coordinates:
x = document.left()
y = document.top() + ((document.topMargin() + tableHeight) / 2),
The value of document.top() is the value of the top of the page minus the top margin. I add some extra space, more specifically the difference of the top margin and the table height divided by two, added to the table height:
tableHeight + ((document.topMargin() - tableHeight) / 2)
This formula can be simplified to:
((document.topMargin() + tableHeight) / 2)
As you can see, all of this is simple Math, the kind of Math you are taught in primary school.
The resulting PDF looks like this:
This proves that your allegation that "it doesn't work" is wrong. Please understand that it is not polite to say "it doesn't work" after people have explained in great detail how to do something. By showing that it does work, people reading this could interpret your allegation as a lie (and that is bad for your karma).

Using ColumnText results in "The document has no pages" exception

I want to wrap text in a rect which is below (or left or right) of a image as below :
Please see link : http://upanh.in/SLk/
I use ColumnText for wrapping text in my code:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/pdf");
try {
// step 1
Document document = new Document(PageSize.A4.rotate());
// step 2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(new Phrase("text is very long ..."), 10, 10, 20, 20, 18, Element.ALIGN_CENTER);
column.go();
// step 5
document.close();
ServletOutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
} catch (DocumentException e) {
throw new IOException(e.getMessage());
}
}
Result:
ExceptionConverter: java.io.IOException: The document has no pages.
Do you have any suggestions how to fix that?
Question 2
I try to display text (center and middle) in the rect with below code but it wasn't success. The text was only center in the rect.
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(RectImg1[0], RectImg1[1], RectImg1[0] + squareHeight, RectImg1[1] + squareHeight
* 1 / 4);
Paragraph p = new Paragraph(imgr.getText(), fontH);
p.setAlignment(Element.ALIGN_CENTER | Element.ALIGN_MIDDLE);
p.setLeading(18);
column.addElement(p);
column.go();
where was my mistake ?
I have edited the title of your question because it was misleading: the exception you encounter will occur in a standalone application too. The fact that you are using the code in a Servlet is irrelevant.
I see that you have the following line:
column.go();
You did not use something like this:
int status = column.go();
If you did, and if you examined status, you would have noticed that the column object still contained some text.
What text? All the text.
There is a serious error in this line:
column.setSimpleColumn(new Phrase("text is very long ..."), 10, 10, 20, 20, 18, Element.ALIGN_CENTER);
You are trying to add the text "text is very long ..." into a rectangle with the following coordinates:
float llx = 10;
float lly = 10;
float urx = 20;
float ury = 20;
You didn't define a font, so the font is Helvetica with font size 12pt and you defined a leading of 18pt.
This means that you are trying to fit text that is 12pt high with an extra 6pt for the leading into a square that measures 10 by 10 pt. Surely you understand that this can't work!
As a result, nothing is added to the PDF and rather than showing an empty page, iText throws an exception saying: there are no pages! You didn't add any content to the document!
You can fix this, for instance by changing the incorrect line into something like this:
column.setSimpleColumn(new Phrase("text is very long ..."), 36, 36, 559, 806, 18, Element.ALIGN_CENTER);
An alternative would be:
column.setSimpleColumn(rect);
column.addElement(paragraph);
In these two lines rect is a Rectangle object. The leading and the alignment are to be defined at the level of the Paragraph object (in this case, you don't use a Phrase).