JEditorPane HTMLDocument adds p-implied into HTML unnecessarily when setCharacterAttributes called - java

I am creating an editor using JEditorPane, HTMLDocument and HTMLEditorKit. I have a toolbar which has various components to change style attributes of the editor. One of them is a JComboBox to change the ZOOM_FACTOR attribute. The code below is the code that executes when that JComboBox 's value changes.
final SimpleAttributeSet attrs = new SimpleAttributeSet();
zoomCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = (String) zoomCombo.getSelectedItem();
s = s.substring(1, s.length());
double scale = new Double(s).doubleValue() / 100;
editorPane.getDocument().putProperty("ZOOM_FACTOR", new Double(scale));
try {
StyledDocument doc = (StyledDocument) editorPane.getDocument();
doc.setCharacterAttributes(0, 1, attrs, true);
doc.insertString(0, "", null); // refresh
} catch (Exception ex) {
logger.error("Hata", ex);
}
}
});
doc.setCharacterAttributes(0, 1, attrs, true); is the line where root of my problem starts. After this line of code executes, <p-implied> is added into the <head></head> part of the HTML text in the JEditorPane.getText. And after this happens, if some certain pattern of events occur my HTML text gets corrupted. Is there any way how not to create <p-implied> along? If not so what could be the best workaround for this problem?
PS : There is something old reported here in the JDK Bug System. It is reported for a different reason, but it is shown there also, that the same <p-implied> is being added into <head></head> afterwards. I know the problem reported in this link uses JTextPane (a subclass of JEditorPane) and setCharacterAttributes method in the JTextPane class but that method also calls same setCharacterAttributes method I used inside itself.

You use 0 position, but for HTMLDocument the positions belong to HEAD (not BODY) section.
Looks like you use it just to refresh the content. You can apply the same code for the end of the document.
doc.setCharacterAttributes(doc.getLength(), 1, attrs, true);
Thus the attribute change event is applied to the BODY.

Related

JEditorPane (JTextComponent) print HTML and fit to page

I have a problem with printing out HTML content. In details HTML is not scaled to fit the page and most of long line is cut off and rest of the line is wraped. I want to use print implementation from JTextComponent because I can pass footer element with page numbering.
Here is full code:
String line = "That's really long text line because it's containing one hundred character, so believe me it is long";
JEditorPane p = new JEditorPane();
p.setContentType("text/html");
StringBuilder htmlContent = new StringBuilder();
htmlContent.append("<html>");
htmlContent.append("<head>");
htmlContent.append("</head>");
htmlContent.append("<body>");
htmlContent.append("<table width = \"845\">");
htmlContent.append("<tr>");
htmlContent.append("<td>");
for(int i = 0 ; i < 100 ; i ++)
htmlContent.append("<font face=\"monospace\">" + line + "</font><br>");
htmlContent.append("</td>");
htmlContent.append("</tr>");
htmlContent.append("</table>");
htmlContent.append("</body>");
htmlContent.append("</html>");
MessageFormat footer = new MessageFormat(" Page #{0,number,integer}");
MessageFormat header = new MessageFormat("");
p.setText(htmlContent.toString());
p.print(header, footer, false, null, null, false);
Is there any way to force this print implementation to scale HTML content do page width?
Screenshot from my result (bottom of page):
HTML printed with JEditorPane
I have tried also to make font smaller with adding size attribute to HTML font element.
I have also tried to Override print method, but I don't know Swing components well and I have a problem with adding constant footer "near" the JEditorPane - in this case JEditorPane just takes all the printable area.
Thank you for any help.

alignment using StyledDocument in drag and drop java

I tired from search the solution for this: i want to align text pane from left to right however but drag and drop java this is last code i written :
` StyledDocument doc = txtio.getStyledDocument();
Style style = txtio.addStyle("right",null);
StyleConstants . setAlignment (style, StyleConstants .ALIGN_RIGHT);
try {
doc.insertString(0,txtio.getSelectedText(), style);
}
catch (BadLocationException ex) {
Logger . getLogger ( mswordframe.class.getName() ).log(Level.SEVERE,null, ex);
}
txtio.setStyledDocument(doc);`
txtio : is the name of text pane;
it doesn't work ,
Sorry i am weak in english
JTextPane supports character and paragraph attributes. Character attributes are for pieces of text and paragraph attributes are for a whole line of text.
Alignment of text is a paragraph attribute because you can't have part of the text center aligned and part right aligned for the same line of text.
Try the following:
SimpleAttributeSet green = new SimpleAttributeSet();
StyleConstants.setForeground(green, Color.GREEN);
SimpleAttributeSet right = new SimpleAttributeSet();
StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
try
{
doc.insertString(0, txtio.getSelectedText(), green);
doc.setParagraphAttributes(0, 1, right, false);
}
catch(Exception e) {}

How to set text # absolute position in the PDF Document using iText

I am trying to use #aaronbartell example, to place the text at required (absolute) position in the PDF document. please give me some direction, thanks.
Example:
private static void absText(String text, int x, int y) {
try {
PdfContentByte cb = writer.getDirectContent();
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.saveState();
cb.beginText();
cb.moveText(x, y);
cb.setFontAndSize(bf, 12);
cb.showText(text);
cb.endText();
cb.restoreState();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
If you use iText, you create a PDF document in 5 steps"
Create a Document instance
Create a PdfWriter instance
Open the document
Add content
Close the document
In your question, you do not create the PdfWriter instance (unless it's a global variable). In your comment, you do not open the document (you've skipped step 3 and this step is essential in the document creation process).
Take the code from your comment, and add the following line at the appropriate place:
document.open();
The appropriate place is after the line where you create the PdfWriter instance and before you start using the writer instance.
Update
In your comment, you are now sharing some code that contains a logical error.
Your main method pdfGeneration() (probably) contains the five steps in the creating process:
You create a Document instance
You create a PdfWriter instance that writes bytes to a file My First PDF Doc.pdf
You open the document
You call a method setPara() that is supposed to add content
You close the document (not visible in your code)
The logical error can be found in the setPara() method. In this method, you repeat the five steps. You create a new Document instance (there's no need to do this) and you create a new PdfWriter instance that creates a new file My First PDF Doc.pdf. This throws an exception, because that file is already in use!
You should change setPara() like this:
public void setPara(PdfContentByte canvas, Phrase p, float x, float y) {
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, x, y, 0);
}
You should call this method from your main method like this:
setPara(writer.getDirectContent(), new Phrase(text), x, y);
Of course: as the setPara() method is little more than a reduced version of the showTextAligned() method that already exists in iText, you may want to use that method directly. For instance: use this in your main method, instead of introducing a setPara() method:
Phrase phrase = new Phrase("Some text", new Font());
PdfContentByte canvas = writer.getDirectContent();
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 20, 20, 0);

how can I find default attributes for JTextPane document?

I'm working with a JTextPane.
JTextPane pane = new JTextPane();
String content = "I'm a line of text that will be displayed in the JTextPane";
StyledDocument doc = pane.getStyledDocument();
SimpleAttributeSet aSet = new SimpleAttributeSet();
If I add this aSet to the textpane's document like this:
doc.setParagraphAttributes(0, content.length(), aSet, false);
Nothing visible happens. No big surprise since I haven't set any custom attributes for aSet. However, if I allow aSet to replace the current ParagraphAttributes of doc like this:
doc.setParagraphAttributes(0, content.length(), aSet, true);
A lot of things happen. How can I get information on those default values of the JTextPane document? Particularly my problems is that when I'm defining a custom Font for aSet and set it to replace the current attributes, the font is displayed as if it was bold. StyleConstants.setBold(aSet, false); doesn't help.
I have looked at the source code to see what data structures are holding the information that you want. This is a modification of that code that prints the attributes for each paragraph.
int offset, length; //The value of the first 2 parameters in the setParagraphAttributes() call
Element section = doc.getDefaultRootElement();
int index0 = section.getElementIndex(offset);
int index1 = section.getElementIndex(offset + ((length > 0) ? length - 1 : 0));
for (int i = index0; i <= index1; i++)
{
Element paragraph = section.getElement(i);
AttributeSet attributeSet = paragraph.getAttributes();
Enumeration keys = attributeSet.getAttributeNames();
while (keys.hasMoreElements())
{
Object key = keys.nextElement();
Object attribute = attributeSet.getAttribute(key);
//System.out.println("key = " + key); //For other AttributeSet classes this line is useful because it shows the actual parameter, like "Bold"
System.out.println(attribute.getClass());
System.out.println(attribute);
}
}
The output for a simple textPane with some text added through the setText() method gives:
class javax.swing.text.StyleContext$NamedStyle
NamedStyle:default {foreground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],size=12,italic=false,name=default,bold=false,FONT_ATTRIBUTE_KEY=javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12],family=Dialog,}
About your particular problem, looking at a related SO question I have been able to set the text of a paragraph to bold with:
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aSet = sc.addAttribute(aSet, StyleConstants.Bold, true);
In this case the class of aSet is javax.swing.text.StyleContext$SmallAttributeSet which is not mutable (does not implement MutableAttributeSet). For your case something along the lines:
aSet.addAttribute(StyleConstants.Bold, true);
should work.

Convert url of image to actual image when opening document

When I open up my file in my text editor. I am only getting the file's location in the text pane. Am I making a simple mistake somewhere or is there a better way to do this? Should I use an ArrayList to store the images locations?
Example of what is happening: I have a file that has two lines...
C:\...\pic.png
(picture description)
When I try to open up the file (after I save it in the text editor) it shows the actual location of the picture. I want to be able to use BufferedImage to get the directory and add the image to the JTextPane. Otherwise (if the text isn't a location), simply add the text to the text pane.
FYI: textArea is of type JTextPane
Code that opens my file
// sb is my StringBuffer
try
{
b = new BufferedReader(new FileReader(filename));
String line;
while((line=b.readLine())!=null)
{
if (line.contains("C:\\...\\Pictures\\"))
{
BufferedImage image = ImageIO.read(new File(line));
ImageIcon selectedPicture = new ImageIcon(image);
textArea.insertIcon(selectedPicture);
}
sb.append(line + "\n");
textArea.setText(sb.toString());
}
b.close();
}
If you have any questions about this code or need clarification, don't hesitate to ask.
OK. The way you are setting content on to the JTextPane is incorrect.
The basic trick is to get StyleDocument out of the JTextPane and then set a Style on the document. A style basically explains how the component needs to be rendered. For example, text formatting, image icons, spacing etc.
Given that following code will get you started.
JTextPane textPane = new JTextPane();
try {
BufferedReader b = new BufferedReader(
new FileReader("inputfile.txt"));
String line;
StyledDocument doc = (StyledDocument) textPane.getDocument();
while ((line = b.readLine()) != null) {
if (line.contains("/home/user/pictures")) {
Style style = doc.addStyle("StyleName", null);
StyleConstants.setIcon(style, new ImageIcon(line));
doc.insertString(doc.getLength(), "ignore", style);
} else {
Style textStyle = doc.addStyle("StyleName", null);
//work on textStyle object to get required color/formatting.
doc.insertString(doc.getLength(), "\n" + line, textStyle);
}
}
b.close();
} catch (Exception e) {
e.printStackTrace();
}

Categories