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.
Related
i wanna extract specific text from pdf i have the exactly position of the text
i try to use itext7 for the extraction but when i create the rectangle for the extraction with the correct dimension it seems too big for match the text but the dimension is correct i tried SimpleTextExtractionStrategy and
LocationTextExtractionStrategy same result
pdfFile
private void estraiValori(PdfPage page) {
for (Entry<String, Elemento> entry : templateMap.entrySet()) {
String key = entry.getKey();
Elemento value=(Elemento) entry.getValue();
//Rectangle tmp=new Rectangle((float)238.64,(float) 14.8,(float) 122,(float) 28.7);
TextRegionEventFilter fontFilter = new TextRegionEventFilter(value.getDim()); //getDim is a rectangle
FilteredEventListener listener = new FilteredEventListener();
//LocationTextExtractionStrategy extractionStrategy = listener.attachEventListener(new LocationTextExtractionStrategy(), fontFilter);
SimpleTextExtractionStrategy extractionStrategy = listener.attachEventListener(new SimpleTextExtractionStrategy(), fontFilter);
new PdfCanvasProcessor(listener).processPageContent(page);//page is a PdfPage
String actualText = extractionStrategy.getResultantText();
System.out.println(actualText);
}
}
There are multiple ways to show (visually) same content in PDF. You can append text glyph by glyph, or in whole sentences. TextRegionEventFilter does not split bigger chunks of text into smaller ones before filtering. If text was written in a big chunk and you want only a part of it, the raw content needs to be preprocessed, i.e. split into smaller chunks.
Fortunately, iText provides an out of the box way to do that - the class is called GlyphTextEventListener and it can be chained to the other ITextExtractionStrategy instances. Just wrap your listener into ITextExtractionStrategy in the following way:
TextRegionEventFilter filter = new TextRegionEventFilter(new Rectangle(x1, y1, x2, y2));
ITextExtractionStrategy filteredListener = new FilteredTextEventListener(new LocationTextExtractionStrategy(), filter);
ITextExtractionStrategy fineGrainedListener = new GlyphTextEventListener(filteredListener);
new PdfCanvasProcessor(fineGrainedListener).processPageContent(page);
I am trying to add small text (left side) and page number (right side) on the footer of a .docx document in the same line
so far I can add the text and the page number but in 2 lines
TextVersionv02312
1
But I need it
TextVersionv02312 1
The code that I am using to add text and page number is:
private static Ftr createFooter(WordprocessingMLPackage wordMLPackage, String content, ObjectFactory factory, Part sourcePart, InputStream is) throws IOException, Throwable {
Ftr footer = factory.createFtr();
P paragraph = factory.createP();
R run = factory.createR();
/*
* Change the font size to 8 points(the font size is defined to be in half-point
* size so set the value as 16).
*/
RPr rpr = new RPr();
HpsMeasure size = new HpsMeasure();
size.setVal(BigInteger.valueOf(16));
rpr.setSz(size);
run.setRPr(rpr);
Text text = new Text();
text.setValue(content);
run.getContent().add(text);
paragraph.getContent().add(run);
footer.getContent().add(paragraph);
// add page number
P pageNumParagraph = factory.createP();
addFieldBegin(factory, pageNumParagraph);
addPageNumberField(factory, pageNumParagraph);
addFieldEnd(factory, pageNumParagraph);
footer.getContent().add(pageNumParagraph);
return footer;
}
private static void addPageNumberField(ObjectFactory factory, P paragraph) {
R run = factory.createR();
PPr ppr = new PPr();
Jc jc = new Jc();
jc.setVal(JcEnumeration.RIGHT);
ppr.setJc(jc);
paragraph.setPPr(ppr);
Text txt = new Text();
txt.setSpace("preserve");
txt.setValue(" PAGE \\* MERGEFORMAT ");
run.getContent().add(factory.createRInstrText(txt));
paragraph.getContent().add(run);
}
I have been thinking to add a table or something like that on the footer to put the elements in the same line, But it seems that I am overcomplicating the stuff.
or maybe I can append the page number to the text paragraph
what do you think?
thanks in advance!
You can do it any way you can in Word, for example, with tab stops. (Or as you say, tables, but I'd use say a centre aligned then a right aligned tab if you wanted centre then right)
Easiest is to get it right in Word, then use the docx4j webapp or Docx4j Helper Word AddIn, to generate corresponding Java code from that sample document.
I have come across various solutions to changing the margins when printing in Java but none seem to work. Here and Here.
What I have so far is,
TextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
// Define a keyword attribute
SimpleAttributeSet keyWord = new SimpleAttributeSet();
StyleConstants.setBold(keyWord, true);
Style style = doc.addStyle("StyleName", null);
StyleConstants.setIcon(style, new ImageIcon(qrcode));
doc.insertString(0, "Title Here\n", null );
doc.insertString(doc.getLength(), "Ignored", style);
textPane.print();
When using the inbuilt print method the margins are set to default as 25.4mm. I'd like to be able to edit these margins while still being able to have a print dialog.
What I "can" verify is, something like this will effect the page size and margins of the output
JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
// Define a keyword attribute
SimpleAttributeSet keyWord = new SimpleAttributeSet();
StyleConstants.setBold(keyWord, true);
Style style = doc.addStyle("StyleName", null);
//StyleConstants.setIcon(style, new ImageIcon(qrcode));
doc.insertString(0, "Title Here\n", null);
doc.insertString(doc.getLength(), "Ignored", style);
Paper paper = new Paper();
paper.setSize(fromCMToPPI(21.0), fromCMToPPI(29.7)); // A4
paper.setImageableArea(fromCMToPPI(5.0), fromCMToPPI(5.0),
fromCMToPPI(21.0) - fromCMToPPI(10.0), fromCMToPPI(29.7) - fromCMToPPI(10.0));
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(textPane.getPrintable(null, null), pageFormat);
PageFormat pf = pj.pageDialog(pageFormat);
if (pj.printDialog()) {
pj.print();
}
Normal output vs modified output (border added after to highlight change)
And the conversation methods...
protected static double fromCMToPPI(double cm) {
return toPPI(cm * 0.393700787);
}
protected static double toPPI(double inch) {
return inch * 72d;
}
What I can't verify is if those values appear in either page setup or printer dialogs, as MacOS has decided I don't need to see them :/
From previous experience on Windows, I seem to remember it working
I have a bit of code that goes to a website, finds text, and prints it out html style in a JLabel. I want to be able to change the color of a specific word in the text ( maybe all of the word "cow" would be green). Here is the code:
public void code() throws IOException
{
Document document = Jsoup.connect("http://www.nbcwashington.com/weather/school-closings/").get();
Elements tags = document.select("p");
String txt = "<html>";
for (Element tag : tags) {
txt += tag.text() + "<br/>";
}
txt += "</html>";
output.setText(txt);
}
I have a bit of code that goes to a website, finds text, and prints it out html style in a JLabel
I find working with JTextPane and style attributes easier than working with HTML.
Just add the text to a text pane as normal text, then you can search the text and change the attributes as required:
Untested code would be something like:
JTextPane textPane = new JTextPane();
textPane.setText(...);
SimpleAttributSet keyword = new SimpleAttributeSet();
StyleConstants.setForeground(keyword, Color.GREEN);
StyledDocument doc = textPane.getStyledDocument();
int length = textPane.getDocument().getLength();
text = textPane.getDocument().getText(0, length);
String search = "cow";
int offset = 0;
while ((offset = text.indexOf(search, offset)) != -1)
{
doc.setCharacterAttributes(offset, search.length(), keyword, false);
offset += search.length();
}
You can also make the JTextPane look like a JLabel by using:
textPane.setOpaque( false );
you can check value using .equals method .you can use span tag to color it.
public void code() throws IOException
{
Document document = Jsoup.connect("http://www.nbcwashington.com/weather/school-closings/").get();
Elements tags = document.select("p");
String txt = "<html>";
for (Element tag : tags) {
if(tag.text().equals("cow")){
txt += "<span style=\"color:#00FF00\">"+tag.text()+"</span><br/>";
}else{
txt += tag.text() + "<br/>";
}
}
txt += "</html>";
output.setText(txt);
}
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.