Generate underline Waves itext7 - java

How can I draw specific underline between :
String s = "This text is underlined with a dashed line";
Paragraph paragraph = new Paragraph();
Text text;
for (int i = 0; i <s.length() ; i++) {
text = new Text(String.valueOf(s.charAt(i)));
paragraph.add(text);
text.setNextRenderer(new DashedLineTextRenderer(text));
}
doc.add(paragraph);
doc.close();
private static class DashedLineTextRenderer extends TextRenderer {
public DashedLineTextRenderer(Text textElement) {
super(textElement);
}
// If renderer overflows on the next area, iText uses getNextRender() method to create a renderer for the overflow part.
// If getNextRenderer isn't overriden, the default method will be used and thus a default rather than custom
// renderer will be created
#Override
public IRenderer getNextRenderer() {
return new DashedLineTextRenderer((Text) modelElement);
}
#Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
Rectangle rect = this.getOccupiedAreaBBox();
PdfCanvas canvas = drawContext.getCanvas();
canvas.moveTo(rect.getLeft(), rect.getBottom());
canvas.curveTo(rect.getLeft()+100,rect.getBottom()+5,
rect.getLeft()+150,rect.getBottom()-2,rect.getLeft()+200,rect.getBottom()-5);
canvas.stroke();
}
}
if i do with single element text it works:
enter image description here
How i can define where draw canvas if there are several text elements

The question is underspecified (see clarifying comment). Basically to avoid the overlap as on the screenshot:
You can customize the renderer for the Paragraph, not for the Text:
private static class WaveUnderlinedParagraphRenderer extends ParagraphRenderer {
public WaveUnderlinedParagraphRenderer(Paragraph paragraph) {
super(paragraph);
}
#Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
Rectangle rect = this.getOccupiedAreaBBox();
PdfCanvas canvas = drawContext.getCanvas();
canvas.moveTo(rect.getLeft(), rect.getBottom());
canvas.curveTo(rect.getLeft() + 100, rect.getBottom() + 5,
rect.getLeft() + 150, rect.getBottom() - 2, rect.getLeft() + 200, rect.getBottom() - 5);
canvas.stroke();
}
#Override
public IRenderer getNextRenderer() {
return new WaveUnderlinedParagraphRenderer((Paragraph) modelElement);
}
}
Document doc = new Document(pdfDocument);
String s = "This text is underlined with a dashed line";
Paragraph paragraph = new Paragraph();
Text text;
for (int i = 0; i <s.length() ; i++) {
text = new Text(String.valueOf(s.charAt(i)));
paragraph.add(text);
}
paragraph.setNextRenderer(new WaveUnderlinedParagraphRenderer(paragraph));
doc.add(paragraph);
doc.close();
And get the following result:

Related

JavaFX - Positioning image with character input

I have a GUI that takes the input of an image name, and once the refresh button is pressed, its displayed in a fixed position. I want to be able to input a character 'A-G' which will change the X position of the image, and a character '0-6' that will change the Y position of the image. The name of the images are just "A1", "A2"..."A5". So, if the user inputs "A1B3", it will display the image A1 in X-Position 'B' and Y-Position '3'. So B could be 200, and 3 could be 300, which makes the (X,Y) coordinates (200,300).
This is my code that gets the users input for the image.
private void getImage(){
Image img = new Image("comp1110/ass2/gui/assets/" + textField.getText() + ".png", 100, 100, false, false);
ImageView image = new ImageView();
image.setImage(img);
image.setX(100);
image.setY(100);
pane.getChildren().add(image);
}
I think you should do something along the lines of this yes there is some cosmetic issues that you will need to fix. But its only to give you an idea of what to do. It uses a gridpane so you don't have to worry about getting exact coordinates I choose a vbox so I didn't have to worry about layout you can keep the Pane that you have it shouldn't make a difference.
public class Main extends Application {
private GridPane gridPane;
private TextField imageTextField = new TextField();
private HashMap<String,String> hashMap = new HashMap<>();
#Override
public void start(Stage primaryStage) {
fillHashMapValues();
gridPane = new GridPane();
gridPane.setGridLinesVisible(true);
for (int i = 0; i < 7; i++) {
RowConstraints rowConstraints = new RowConstraints();
rowConstraints.setPercentHeight(14);
gridPane.getRowConstraints().add(rowConstraints);
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setPercentWidth(14);
gridPane.getColumnConstraints().add(columnConstraints);
gridPane.addColumn(i);
gridPane.addRow(i);
}
imageTextField.setPromptText("Enter Image Letters?");
TextField textField = new TextField();
textField.setPromptText("Enter Coordinates");
Button button = new Button("Go!");
button.setOnAction(event -> {
addToGridPane(textField.getText());
});
VBox vBox = new VBox();
vBox.setPrefSize(300, 300);
vBox.setAlignment(Pos.TOP_CENTER);
vBox.getChildren().addAll(imageTextField, textField, button, gridPane);
primaryStage.setScene(new Scene(vBox));
primaryStage.show();
button.requestFocus();//This is only so you can see the prompt text its irrelevant
}
private void fillHashMapValues(){
hashMap.put("A", "1");
hashMap.put("B", "2");
hashMap.put("C", "3");
hashMap.put("D", "4");
hashMap.put("E", "5");
hashMap.put("F", "6");
hashMap.put("G", "7");
}
private void addToGridPane(String string){
char[] chars = string.toCharArray();
if(chars.length==2){//Do more data validation here
if(hashMap.containsKey(String.valueOf(chars[0]))) {
int xValue = Integer.parseInt(hashMap.get(String.valueOf(chars[0])));
int yValue = Integer.parseInt(String.valueOf(chars[1]));
ImageView image = getImage();
gridPane.add(image, xValue, yValue);
}
}
}
private ImageView getImage(){
Image image = new Image("comp1110/ass2/gui/assets/" + imageTextField.getText() + ".png", 100, 100, false, false);
ImageView imageView = new ImageView();
imageView.setImage(image);
//imageView.setX(100);
//imageView.setY(100);
//pane.getChildren().add(image);
return imageView;
}
public static void main(String[] args) { launch(args); }
}

Getting NullPointerException when adding Header/Footer in iText [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I was trying to create a PDF using iText.
My objective is to make a question paper. I was able to only add the questions and answers to the PDF.
Then i tried modifying it by adding page numbers, watermarks etc. by adding Header/Footer. Now it gives me NullPointerException i cannot figure out what went wrong.
Error I'm getting
Caused by: java.lang.NullPointerException
at
edu.ijse.gdse41.ams.other.HeaderFooter.onEndPage(HeaderFooter.java:57)
at com.itextpdf.text.pdf.PdfDocument.newPage(PdfDocument.java:902)
at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:837) at
com.itextpdf.text.Document.close(Document.java:416) at
edu.ijse.gdse41.ams.view.CreateAssignmentController.createPDF(CreateAssignmentController.java:644)
at
edu.ijse.gdse41.ams.view.CreateAssignmentController.proceedBtnClicked(CreateAssignmentController.java:292)
... 58 more
createPDF() method in CreateAssignment.java class
private void createPDF(ArrayList<Assignment_QuesDTO> questionPaper) throws DocumentException, BadElementException, IOException {
try {
OutputStream outputStream = null;
Document doc = new Document();
outputStream = new FileOutputStream(new File("C:\\Users\\Dell\\Documents\\NetBeansProjects\\AssignmentManagementSystem\\src\\PDF\\mypdf.pdf"));
PdfWriter writer = PdfWriter.getInstance(doc, outputStream);
PdfPageEventHelper eventHelper = new HeaderFooter(doc);
writer.setPageEvent(eventHelper);
doc.open();
Font fontTitle = new Font(Font.getFamily("TIMES_ROMAN"), 15);
Paragraph title = new Paragraph("ABC", fontTitle);
title.setAlignment(Paragraph.ALIGN_CENTER);
doc.add(title);
for (int i = 0; i < 3; i++) {
doc.add(Chunk.NEWLINE);
}
Paragraph subTitle = new Paragraph(questionPaper.get(1).getAssignment().getAssignName());
subTitle.setAlignment(Paragraph.ALIGN_CENTER);
Paragraph subTitle2 = new Paragraph(questionPaper.get(1).getAssignment().getDate());
subTitle2.setAlignment(Paragraph.ALIGN_CENTER);
doc.add(subTitle);
doc.add(subTitle2);
List orderedList = new List(List.ORDERED);
for (Assignment_QuesDTO questionPaper1 : questionPaper) {
Paragraph question = new Paragraph(questionPaper1.getQuestion().getQues());
question.setAlignment(Paragraph.ALIGN_JUSTIFIED);
orderedList.add(question);
List desc = new List(List.UNORDERED);
desc.setIndentationLeft(36);
desc.setListSymbol(new Chunk(" "));
desc.add(new Phrase("\t\t" + questionPaper1.getQuestion().getQuesDesc()));
orderedList.add(desc);
orderedList.add(Chunk.NEWLINE);
List answers = new List(List.ORDERED,List.ALPHABETICAL);
answers.setIndentationLeft(72);
for (AnswerDTO answer : questionPaper1.getQuestion().getAnswers()) {
answers.add(" " + answer.getAnswer());
}
orderedList.add(answers);
orderedList.add(Chunk.NEWLINE);
}
doc.add(orderedList);
doc.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(CreateAssignmentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
HeaderFooter.java class
public class HeaderFooter extends PdfPageEventHelper {
Phrase[] header = new Phrase[2];
int pageNum;
Image watermark;
public HeaderFooter(Document doc) throws BadElementException, IOException {
this.watermark = Image.getInstance("C:\\Users\\Dell\\Documents\\NetBeansProjects\\AssignmentManagementSystem\\src\\edu\\ijse\\gdse41\\ams\\resources\\images\\watermark.png");
watermark.rotate();
watermark.scaleToFit(doc.getPageSize());
watermark.setRotationDegrees(30);
}
#Override
public void onChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) {
header[1] = new Phrase(title.getContent());
pageNum = 1;
}
#Override
public void onEndPage(PdfWriter writer, Document document) {
try {
Rectangle rect = writer.getBoxSize("art");
switch (writer.getPageNumber() % 2) {
case 0:
ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_RIGHT, header[0], rect.getRight(), rect.getTop(), 0);
break;
case 1:
ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, header[1], rect.getLeft(), rect.getTop(), 0);
break;
}
ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(String.format("Page %d", pageNum)), (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0);
PdfContentByte content = writer.getDirectContent();
content.addImage(watermark);
} catch (DocumentException ex) {
Logger.getLogger(HeaderFooter.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void onStartPage(PdfWriter writer, Document document) {
pageNum++;
}
#Override
public void onOpenDocument(PdfWriter writer, Document document) {
header[0] = new Phrase("ABC");
}
}
In your page event, you assume that the PDF you are creating has an /ArtBox boundary:
Rectangle rect = writer.getBoxSize("art");
However, when I look at the code that creates your PDF, I don't see you creating such a page boundary anywhere. This means that rect is null, and that methods such as rect.getRight(), rect.getTop(),... throw a NullPointerException.

CENTER align text when using StyledCellLabelProvider

I use a StyledCellLabelProvider to format text string as 'Hyperlink'.
// Column for the link
TableViewerColumn col2 = createTableViewerColumn("Link", 100, 1, viewer);
col2.setLabelProvider(new StyledCellLabelProvider() {
#Override
public void update(ViewerCell cell)
{
Object element = cell.getElement();
if(element instanceof Person)
{
Person person = (Person) cell.getElement();
/* make text look like a link */
StyledString text = new StyledString();
StyleRange myStyledRange = new StyleRange(0, person.getLocation().length(), Display.getCurrent().getSystemColor(SWT.COLOR_BLUE), null);
myStyledRange.underline = true;
text.append(person.getLocation(), StyledString.DECORATIONS_STYLER);
cell.setText(text.toString());
StyleRange[] range = { myStyledRange };
cell.setStyleRanges(range);
super.update(cell);
}
}
});
I also set text align of TableViewerColumn is CENTER but after using this style the text is left align.
How can I set CENTER align of text and change the cursor into link cursor when touch to the text?
Thanks

Designing chat layout with Swing

I am trying to design a chat UI with Swing, but I am too dumb to figure out how to do proper indentation for the message portion.
Here's an example of what I'm after:
Here's what I just hacked together (just copy-and-paste it):
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class Scrap {
private static final int NICK_INDENT = 120;
private static final int MESSAGE_INDENT = NICK_INDENT + 10;
private static boolean applyHangingIndent = false;
public static void main(final String args[]) {
StyledDocument doc = new DefaultStyledDocument();
JTextPane pane = new JTextPane(doc) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine(NICK_INDENT + 5, 0, NICK_INDENT + 5, getHeight());
}
};
TabStop[] tabs = new TabStop[2];
tabs[0] = new TabStop(NICK_INDENT, TabStop.ALIGN_RIGHT, TabStop.LEAD_NONE);
tabs[1] = new TabStop(MESSAGE_INDENT, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);
TabSet tabset = new TabSet(tabs);
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.TabSet, tabset);
pane.setParagraphAttributes(aset, false);
insertString(doc, "\ta nickname:\tthis is the message blaa blaa blaa\n");
if (applyHangingIndent) {
applyHangingIndent(doc);
}
insertString(doc, "\tanother nickname:\there is another message blaa blaa blaablaa, try to resize the window\n");
if (applyHangingIndent) {
applyHangingIndent(doc);
}
insertString(doc, "\ta third nickname:\tnow try to set the applyHangingIndent to true!\n");
if (applyHangingIndent) {
applyHangingIndent(doc);
}
JFrame frame = new JFrame();
frame.setContentPane(new JScrollPane(pane));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(600, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static void insertString(StyledDocument doc, String str) {
try {
doc.insertString(doc.getLength(), str, null);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
private static void applyHangingIndent(StyledDocument doc) {
SimpleAttributeSet sas = new SimpleAttributeSet();
int indent = MESSAGE_INDENT;
StyleConstants.setFirstLineIndent(sas, -indent);
StyleConstants.setLeftIndent(sas, indent);
doc.setParagraphAttributes(0, doc.getLength(), sas, false);
}
}
Try to resize the window to a smaller size.
Now, try to set the applyHangingIndent to true and resize again.
To my mind the code should be OK, however the negative first line indent property does not seem to work with tabstops.
Anyone have ideas how to make the indentation work properly?
I would recommend another approach - tables based.
See the example http://java-sl.com/JEditorPaneTables.html and this http://java-sl.com/JEditorPaneTablesRowColumnInsert.html
You can define a table with 2 columns and as many rows as you need (for each message).
The first cell contains nickname and the second contains message. You can align content of cells (normal paragraphs in fact) as you wish. Also you can define any desired borders to be rendered or not for the columns/rows.

How to add Hyperlink in SWT Table`s column?

How to add Hyperlink in SWT Table column ?
I`m using org.eclipse.swt.widgets.Table class.
Is there any way to do this without using TableViewer, JFace ?
I tried this way but not working correctly (not showing hyperlinks).
for(int i=2; i<4; i++){
Hyperlink link = new Hyperlink(table, SWT.WRAP);
link.setText(temp[i]);
link.setUnderlined(true);
TableEditor editor = new TableEditor(table);
editor.setEditor(link, tableItem[index-1], i); //set hyperlinks in column i
}
Below is one way to draw the hyperlink using TableView with a LabelProvider, as mentioned in Tonny Madsen's answer.
The code below just paints the hyperlink.
TableViewerColumn column = ...
column.setLabelProvider( new MyHyperlinkLabelProvider( tableViewerFiles.getTable() ));
private final class MyHyperlinkLabelProvider extends StyledCellLabelProvider {
MyHyperlink m_control;
private MyHyperlinkLabelProvider( Composite parent ) {
m_control = new MyHyperlink( parent, SWT.WRAP );
}
#Override
protected void paint( Event event, Object element ) {
String sValue = ... [Get cell value from row element]
m_control.setText( sValue );
GC gc = event.gc;
Rectangle cellRect = new Rectangle( event.x, event.y, event.width, event.height );
cellRect.width = 4000;
m_control.paintText( gc, cellRect);
}
}
private class MyHyperlink extends Hyperlink {
public MyHyperlink(Composite parent, int style) {
super(parent, style);
this.setUnderlined(true);
}
#Override
public void paintText(GC gc, Rectangle bounds) {
super.paintText(gc, bounds);
}
}
Yes, that is certainly possible. To do this you have to implement SWT.ItemPaint (and possibly also SWT.ItemErase and SWT.ItemMeassure).
It is easier with TableView though if you use the correct LabelProvider...
You need to set the size of the editor:
editor.grabHorizontal = true;
//or
editor.minimumWidth = 50;

Categories