JTextPane word wrapping issue - java

I'm using JTextPane in an application for wiki source editing. I've added a simple spell checking functionality to it which underlines mispelled words by changing character attributes to a different style via StyledDocument.setCharacterAttributes.
There are only these two styles used: the default and the 'mispelled' one. The text editor control does word wrapping, which is the expected behavior.
My problem is that there are cases (not always, but is reproducible with a specific wiki document) this character attribute changing somehow disables the word wrapping. More specifically, I delete three lines from the middle of the document, and the next run of the spell checker, when resets the character attributes to the default style (before rerunning the spell checking), the word wrapping functionality gets disabled and it remains that way. If I undo the deletion, the word wrapping goes back to normal.
Commenting out the single line that resets the style:
editorPane.getStyledDocument().setCharacterAttributes(0, editorPane.getStyledDocument().getLength(), defaultStyle, true);
solves the issue.
EDIT 1
I've extracted the problem to a simple test case. Sorry for the long line, that example text is important to reproduce the bug (it has been randomized):
package jtextpanebug;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;
import javax.swing.text.Style;
public class DemoFrame extends javax.swing.JFrame {
private final JButton btResetStyle;
private final JScrollPane scrollPane;
private final JTextPane textPane;
private final Style defaultStyle;
public DemoFrame() {
// Creating a simple form with a scrollable text pane and a button
scrollPane = new JScrollPane();
textPane = new JTextPane();
btResetStyle = new JButton();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
// The text pane's text is the scrambled version of my original test data,
// it is important because the problem depends on the pane's text
// (not every text makes it wrong)
textPane.setText("= Gernela Stuff Dogo to Wnko Obuat Oebrfe Disytung hte Iidnividal Oitpcs =\n\n== Elmyonrogit ==\n\n'''memidtaie-ngiebhro opnits''' - 2 points, \nwihhc nac eb ense ot eb mmiieadte hnigeorbs fo haec othre. \nThere si no strict | cxeat defiintoin. \nEth etipcur owebl shsow sa an example optins dna the rispa \nienbg mimedtiea iebnghsor ear ncnoetced.\n\n[[Amieg:einogrhb_pinsot.pgn]]\n\n'''enihgorb optnsi distacne''' - het avaeegr of sdntaisce \nderemitedn by het mimeidate-hieobngr tonpi ipras. \n\n'''lalw''' - a iotpntes nepgesnietrr a llwa, with toerh orwds: 2 apraelll, \nevyr sloce sraufce picsee. Heer is an xamelpe. \nIt is eualgttandri ofr eterbt zisiuaitovlan.\n\n[[Gimae:llwa.npg]]\n\n'''addtaiilon emmory reeueimtnqr of na laigorthm''' - \n(eth kepa mmeory suaeg fo teh nltpiaciapo ndirug the excteouin of eht grlaotihm) - \n(hte moeymr sueag fo hte loragitmh befoer ro ftrea eht ucxeeiont of the laogrihmt)\n\n== Het Input Pnoitset Ash to Repnrsete Ufscear Arsnoelbay Elwl ==\n\nIf tno efisciped toehrwsie yb hte cdoritnpsei of an aoglirthm, \nhetn hte eqtunrmeersi of it are heste:\n\n* Ifsrt fo all the poisentt umst reprseent urfseac, not urvec ro uvomel or nayithng eesl.\n* Awlls aym otn eb tniehnr tanh at least 3 * fo ienhbgro-tpoin-sidenact.\n* Dseeg amy ton be rhserap tnha 70 grdesee (as het agnle fo eht trmeaial) nda husdol be ta tleas 290 redeseg (ni caes fo cnvocae eedgs).\n* Onpti edintsy amy ont vayr oto humc \n** Het angre fo the coall ption desitnsei of a igsenl pisnotte nutip ushold eb sallm. Ahtt is: teh orait of het oclla oitnp idsentise oarund any 2 ipnost lsdhou eb lmitied.\n** Hte lcoal noipt deisynt ushlod otn ahencg sdduelyn (gliftyscaiinn ni a hotsr idnsteac). \n\nYreftntunaoul the largoimths cna tno yb ethmsevesl \nhcekc these qutenmeserir nda usjt yden rnuning, \nso it si eth rseu's iyponerissbtil to ton extucee an raltghomi no a itseopnt \nthat does ont mete het aogitmlhr's terieseurmnq.\n\nIf eth rmeteriuqen fo na airlgmoth on its npuit is ont mte, then tobh hte ueavbhior nad hte srluet fo hte alghoritms si dinfeuned. \nTeh loirgamth amy nru rfo iinfntie long imet or rodpuce evry abd rselut, ro a eruslt htat oolsk good btu is nicrtroec. Ni htis scea rtehe si tno nay aguntreee toabu the tmniatreion of the iralgtmho ro eht lqutaiy fo the sreltu ecxept htat the nptapalcioi iwll ont carsh.\n");
scrollPane.setViewportView(textPane);
getContentPane().add(scrollPane);
btResetStyle.setText("Reset style");
btResetStyle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
btResetStyleActionPerformed(evt);
}
});
getContentPane().add(btResetStyle);
pack();
// The default style, the problem happens when we reset the full document
// to it:
defaultStyle = textPane.addStyle("default", null);
}
private void btResetStyleActionPerformed(java.awt.event.ActionEvent evt) {
// When the button is pressed we reset the full document to the default
// style. In the original application this was periodically done as
// part of the spell checking
textPane.getStyledDocument().setCharacterAttributes(0, textPane.getStyledDocument().getLength(), defaultStyle, true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new DemoFrame().setVisible(true);
}
});
}
}
Reproducing the issue:
Compile and run the class above
Try to resize the frame - word wrapping works
Locate and delete the three lines I copied below
Press the Reset style button
The word wrapping turned off
* Onpti edintsy amy ont vayr oto humc
** Het angre fo the coall ption desitnsei of a igsenl pisnotte nutip ushold eb sallm. Ahtt is: teh orait of het oclla oitnp idsentise oarund any 2 ipnost lsdhou eb lmitied.
** Hte lcoal noipt deisynt ushlod otn ahencg sdduelyn (gliftyscaiinn ni a hotsr idnsteac).
EDIT 2
Using the highlighter instead of styles solved my problem, but I'm still curious what was wrong with the original approach.

This looks like the same issue I asked about here : Strange text wrapping with styled text in JTextPane with Java 7.
As far as I know, this is a bug in Java 7, and it is not documented in Oracle's Java Bug Parade. I have still not found a workaround (using the highlighter is not an option in my case).

Related

Some words in Arabic appear calligraphic in Swing

It seems that Swing auto decorate some Arabic words by making them look some kind calligraphic. One of those words is Muhammad which is spelled in Arabic as محمد.
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TestProject extends JFrame {
public static void main(String[] args) {
TestProject frame = new TestProject();
frame.setVisible(true);
}
public TestProject() {
this.setSize(200, 100);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("محمد");
label.setFont(new Font("Arial", Font.BOLD, 28));
this.add(label);
}
}
The problem is applied to all widely used Fonts at least.
I'm using Windows 10 & Java 8. I've tried the same program on another PC (also Windows 10) same problem.
How can we disable that?
This seems to be a bug in the old (i.e. up to Java 8) font rendering engine.
This is how it looks with Java 8 on my machine:
And this is the result with Java 9:
I don’t know whether an explicit bug report has been reported for this specific issue. But the font engine has been replaced entirely, due to JEP 258: HarfBuzz Font-Layout Engine.
Replace the existing ICU OpenType font-layout engine with HarfBuzz.
So it’s not surprising that bugs of the old font rendering are gone.
(Caveat: I am not literate in Arabic.)
Appears to be font related
By default, I do not get your longer representation (3 words?) as seen in your screenshot.
When I write a minimal Swing app with the text "محمد" I get that short string (4 characters?) that you want.
When using specific fonts, I do get what looks to my untrained eye to be the calligraphic rendering you seek to avoid.
Note that my string was not your string. I copied from Google Translate, translating Muhammad as indicated in your Question.
https://translate.google.com/?sl=en&tl=ar&text=Muhammad%0A&op=translate
I wrote this minimal Swing app with just a JLabel, enhanced only by increasing font size.
package work.basil.example;
import javax.swing.*;
import java.awt.*;
/**
* Hello world!
*/
public class App {
public static void main ( String[] args ) {
System.out.println( Runtime.version() );
javax.swing.SwingUtilities.invokeLater( () -> createAndShowGUI() );
}
private static void createAndShowGUI () {
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated( true );
//Create and set up the window.
JFrame frame = new JFrame( "Test Arabic rendering" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
//Add the ubiquitous "Hello World" label.
JLabel label = new JLabel( "محمد" );
label.setFont( new Font( label.getFont().getName() , label.getFont().getStyle() , 40 ) ); // Override default font size.
System.out.println( "Font name: " + label.getFont().getName() + " | " + "Font style: " + label.getFont().getStyle() );
frame.getContentPane().add( label );
//Display the window.
frame.pack();
frame.setVisible( true );
}
}
When run on my MacBook Pro (13-inch, M1, 2020), Apple Silicon (not Intel), 16 gigs of memory. The OS is macOS Big Sur, 11.5.1. Using early-access version of Java 17 (17+35-2724) from this page.
(By the way, this is the kind of MCVE you should have posted with your Question.)
The result of my font query is:
Font name: Lucida Grande | Font style: 0
… but I suspect that is the default font of the JLabel widget rather than the actual font used in rendering those Arabic characters. As I vaguely recall, recent versions of macOS are rich with a variety of fonts specifically for Arabic. See: Fonts included with macOS Big Sur for three lists: fonts included, fonts available for download, and older fonts available for document support. Using the Font Book app bundled with macOS, and defining a "smart collection" where languages include Arabic, I get a list of 32 such fonts installed by default in macOS Big Sur. (The four items for Pragmata Pro do not apply — that is a commercial font which I purchased, and which I highly recommend for developers.)
I ran this modified version of the code from Answer by Andrew Thompson on the same macOS Big Sur described above.
package work.basil.text;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
public class TestProject extends JFrame {
public static void main ( String[] args ) {
TestProject frame = new TestProject();
frame.setVisible( true );
}
public TestProject () {
this.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
this.setLayout( new FlowLayout() );
String input = "محمد";
String[] fontFamilies = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for ( String fontFamily : fontFamilies ) {
Font font = new Font( fontFamily , Font.PLAIN , 40 );
if ( font.canDisplayUpTo( input ) < 0 ) {
JLabel label = new JLabel( input );
label.setFont( font );
label.setBorder( new TitledBorder( fontFamily ) );
this.add( label );
}
}
this.pack();
}
}
Here is a screenshot of the result.
Try running the code below. It produced this image on my range of installed fonts.
Note also that Arial (a sans-serif or undecorated font) seems to default to Times New Roman (a serif or decorated font) for its Arabic glyphs. This is a common thing for fonts (or systems, not sure) to do, and it produces rather odd renderings when sans-serif fonts are replaced with serif fonts.
Also note this system has 255 fonts installed, but only 23 of those support Arabic characters.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class TestProject extends JFrame {
public static void main(String[] args) {
TestProject frame = new TestProject();
frame.setVisible(true);
}
public TestProject() {
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel p = new JPanel(new GridLayout(0, 5));
String arabic = "محمد";
String[] fontFamilies = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for (String fontFamily : fontFamilies) {
Font font = new Font(fontFamily, Font.PLAIN, 25);
if (font.canDisplayUpTo(arabic) < 0) {
JLabel label = new JLabel(arabic);
label.setFont(font);
label.setBorder(new TitledBorder(fontFamily));
p.add(label);
}
}
this.add(new JScrollPane(p));
this.pack();
}
}

GraphStream: a more thorough tutorial introduction?

Background
I am new to both GraphStream and Java. However, I do have experience with other OOP-languages like C++. I personally find the tutorials for GraphStream quite sparse, for example the Layout API doesn't mention which layout algorithms are valid. Thus am looking for a more consolidated tutorial.
Question
Using GraphStream, I want to be able to do the following basic operations:
Import a graph as a .dgs
Import a graph as a .csv
Change from the automatic layout to a specified layout (please list which are valid in the first place too)
Change all edge attributes (e.g. weight)
Find at most n paths of length l or less from s to t.
Add an event (e.g. click node, get user input about about length of paths from that node to show, prune/grow appropriately)
Code
Note
I am using Eclipse. From the GraphStream repository, I have added the following to my build path: gs-algo-1.3, gs-core-1.3, gs-openord-master, and gs-ui-1.3
//import anything I might need
import org.graphstream.graph.*;
import org.graphstream.graph.implementations.*;
import org.graphstream.stream.file.*;
import org.graphstream.algorithm.*;
import org.graphstream.ui.layout.*;
import java.io.IOException;
#SuppressWarnings("unused")
public class pleaseHelpMe {
public static void main(String args[]) throws IOException, InterruptedException {
//do something that was in some code somewhere...
//please explain
System.setProperty("org.graphstream.ui.renderer","org.graphstream.ui.j2dviewer.J2DGraphRenderer");
//instantiate a graph
Graph graph = new SingleGraph("thisGraphNeedsHelp");
graph.addAttribute("ui.antialias"); //this does something...
graph.addAttribute("ui.quality"); //this sounds less important...
graph.setAttribute("ui.stylesheet", "url(../myStyle.css);"); //get some style
//errors, errors everywhere
//OpenOrdLayout layout = new OpenOrdLayout();
//layout.init(graph);
//layout.compute();
//changing all edges layout.weight is not that simple
//graph.setAttribute("edges","layout.weight:4");
graph.dsiplay();//this just makes the canvas?
FileSource source = new FileSourceDGS(); //prep. to get a file
//make graph a sink of source to get the contents of the file
source.addSink(graph);
source.begin("../dgs_files/awesomeFile.dgs");//read the file? strange command name i.m.o. file below.
while(source.nextEvents()); //keep graph interactive? or is this the GraphStream version of readline?
source.end() //close file? or end interaction?
//find paths
//get user input
}
}
DGS File
DGS004
null 0 0
an a ui.label:a
an b ui.label:b
an c ui.label:c
an d ui.label:d
an e ui.label:e
an f ui.label:f
ae a_c a > c
ae c_e c > e
ae e_a e > a
ae b_d b > d
ae d_f d > f
ae f_b f > b
ae f_a f > a
ae e_b e > b
ae d_c d > c
CSS File
node:clicked {
fill-color: purple;
text-size: 16;
text-style: bold;
text-color: #FFF;
text-alignment: at-right;
text-padding: 3px, 2px;
text-background-mode: rounded-box;
text-background-color: #A7CC;
text-color: white;
text-offset: 5px, 0px;
}
node {
size: 20px;
shape: circle;
fill-color: #8facb4;
stroke-mode: plain;
stroke-color: black;
}
edge {
size: 2px;
fill-mode: plain;
/*changing edge layout here also doesn't work*/
}
/*edge:clicked isn't a thing... :( */

Creating a Table of Contents for a XWPFDocument with page numbers' indication

I am actually generating a Word Document with Apache POI, and I need to automatically create a Table of Contents (TOC) that references the paragraphs, with their page's indication.
This is the code I am using (I omit preconditions and internal methods' body):
XWPFDocument doc = new XWPFDocument(OPCPackage.openOrCreate(new File(document)));
String strStyleId = "Index Style";
addCustomHeadingStyle(doc, strStyleId, 1);
XWPFParagraph documentControlHeading = doc.createParagraph();
changeText(documentControlHeading, "First try");
documentControlHeading.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading.setPageBreak(true);
documentControlHeading.setStyle(strStyleId);
XWPFParagraph documentControlHeading1 = doc.createParagraph();
changeText(documentControlHeading1, "Second try");
documentControlHeading1.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading1.setPageBreak(true);
documentControlHeading1.setStyle(strStyleId);
doc.createTOC();
When I open the resulting document, I am getting this result (see blue squares):
In the left part, I can see the generated TOC. So far, so good.
In the document's body, however, I can just see a static text "Table of Contents", with no indications at all (neither paragraphs nor pages). I cannot even interact with it.
If I'd click on the menu entry "Table of Contents" (red square on the upper-left corner), the "real" Table of Content that I want is being generated (follow the arrow, of course...).
My question is: how can I achieve the second result (red TOC) from code?
Thank you so much.
Side note: I even tried putting doc.enforceUpdateFields(); after doc.createTOC();, but every reference of the TOC disappears, this way.
#Sucy, I add the methods that you requested. Don't know if you can find them useful, though:
/*
* Adds a custom style with the given indentation level at the given document.
*/
private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
CTStyle ctStyle = CTStyle.Factory.newInstance();
ctStyle.setStyleId(strStyleId);
CTString styleName = CTString.Factory.newInstance();
styleName.setVal(strStyleId);
ctStyle.setName(styleName);
CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
indentNumber.setVal(BigInteger.valueOf(headingLevel));
// lower number > style is more prominent in the formats bar
ctStyle.setUiPriority(indentNumber);
CTOnOff onoffnull = CTOnOff.Factory.newInstance();
ctStyle.setUnhideWhenUsed(onoffnull);
// style shows up in the formats bar
ctStyle.setQFormat(onoffnull);
// style defines a heading of the given level
CTPPr ppr = CTPPr.Factory.newInstance();
ppr.setOutlineLvl(indentNumber);
ctStyle.setPPr(ppr);
XWPFStyle style = new XWPFStyle(ctStyle);
// is a null op if already defined
XWPFStyles styles = docxDocument.createStyles();
style.setType(STStyleType.PARAGRAPH);
styles.addStyle(style);
}
/*
* Changes the text of a given paragraph.
*/
public static void changeText(XWPFParagraph p, String newText) {
if (p != null) {
List<XWPFRun> runs = p.getRuns();
for (int i = runs.size() - 1; i >= 0; i--) {
p.removeRun(i);
}
if (runs.size() == 0) {
p.createRun();
}
XWPFRun run = runs.get(0);
run.setText(newText, 0);
}
}
The XWPF classes as you have seen are a work in progress, with no real overarching architecture. That will change over time as we work on it, but in the mean time you can try to add a simple TOC field to a paragraph in this way.
XWPFParagraph p;
...
// get or create your paragraph
....
CTP ctP = p.getCTP();
CTSimpleField toc = ctP.addNewFldSimple();
toc.setInstr("TOC \\h");
toc.setDirty(STOnOff.TRUE);
This will create a Table of contents with hyperlinks to the pages, it should be recalculated when Word opens it, and the table of contents will be based on predefined HeaderX styles.
I've solved the mystery and, unfortunately (for people having the same problem), there's no good news. Apache POI's createTOC() is bugged (to be honest, it seems a method whose implementation has been started but never completed in a proper way) (please, consider jmarkmurphy's accepted answer).
The Documentation doesn't explain anything about the method itself (it just reports the signature, and nothing more), and that's suspect.
Watching at the XWPFDocument's class code:
public void createTOC() {
CTSdtBlock block = getDocument().getBody().addNewSdt();
TOC toc = new TOC(block);
for (XWPFParagraph par : this.paragraphs) {
String parStyle = par.getStyle();
if ((parStyle != null) && (parStyle.startsWith("Heading"))) try {
int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue();
toc.addRow(level, par.getText(), 1, "112723803");
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
Apache POI searches for paragraphs having style named "HeadingX", with X being a number. So, my variable strStyleId should have been valorized as Heading1, as an example. But this doesn't solved the problem. In fact, createTOC() always passes 1 as the page number to the addRow() method, that always sets the page as 1, this way. It does absolutely nothing in order to get that dinamically.
That's the final, unuseful result (as you can see, it's also a "fake" TOC, and not the one that you can create via Microsoft Word using the red-squared button in the question):
So, page numbers for a Word document cannot be retrieved dinamically (as I read in other posts), and even Apache POI seems unable to do that, sadly.
toc.setInstr("TOC \\h");
h switch has to be used with '\', not '/', because it works correctly only with '\'. More details about using TOC switches: Use Word's TOC field to fine-tune your table of contents
Recently I had had the same problem, but I wanted to add a ToC with depth=2 (exclude heading 3). I've created a copy and added the ToC manually in the Word document and rename both from .docx to .zip.
Inside each zip document, there's an XML file located in document.zip/word/document.xml. This document is the document content.
I've compared both XML files and found that Word added the following value when you add a ToC:
<w:fldSimple w:instr="TOC \o "1-2" \h \z \u"/>
I've updated my code using this:
CTP ctP = paragraph.getCTP();
CTSimpleField toc = ctP.addNewFldSimple();
toc.setInstr("TOC \\o \"1-2\" \\h \\z \\u");
toc.setDirty(STOnOff.ON);
When you open the document, Word will ask you to update the references and the ToC becomes perfect. Since I want the generation process fully automated I'm still working on that part.
If someone still looking for the answer, i followed the suggestion provided by #jmarkmurphy.
Below is the working code
import java.io.FileOutputStream;
import java.math.BigInteger;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFStyle;
import org.apache.poi.xwpf.usermodel.XWPFStyles;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSettings;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
public class ApachePOIWordTOCDemo {
public static void main(String[] args) throws Exception {
XWPFDocument doc = new XWPFDocument();
doc.createTOC();
addCustomHeadingStyle(doc, "heading 1", 1);
addCustomHeadingStyle(doc, "heading 2", 2);
addCustomHeadingStyle(doc, "heading 3", 3);
// the body content
XWPFParagraph paragraph = doc.createParagraph();
CTP ctP = paragraph.getCTP();
CTSimpleField toc = ctP.addNewFldSimple();
toc.setInstr("TOC \\h");
toc.setDirty(true);
XWPFRun run = paragraph.createRun();
paragraph = doc.createParagraph();
run = paragraph.createRun();
run.setText("Heading 1");
paragraph.setStyle("heading 1");
paragraph = doc.createParagraph();
run = paragraph.createRun();
run.addBreak(BreakType.PAGE);
run.setText("Heading 2");
paragraph.setStyle("heading 2");
paragraph = doc.createParagraph();
run = paragraph.createRun();
run.addBreak(BreakType.PAGE);
run.setText("Heading 3");
paragraph.setStyle("heading 3");
FileOutputStream fos = new FileOutputStream("createTOC.docx");
doc.write(fos);
}
private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
CTStyle ctStyle = CTStyle.Factory.newInstance();
ctStyle.setStyleId(strStyleId);
CTString styleName = CTString.Factory.newInstance();
styleName.setVal(strStyleId);
ctStyle.setName(styleName);
CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
indentNumber.setVal(BigInteger.valueOf(headingLevel));
// lower number > style is more prominent in the formats bar
ctStyle.setUiPriority(indentNumber);
CTOnOff onoffnull = CTOnOff.Factory.newInstance();
ctStyle.setUnhideWhenUsed(onoffnull);
// style shows up in the formats bar
ctStyle.setQFormat(onoffnull);
// style defines a heading of the given level
CTPPrGeneral ppr = CTPPrGeneral.Factory.newInstance();
ppr.setOutlineLvl(indentNumber);
ctStyle.setPPr(ppr);
XWPFStyle style = new XWPFStyle(ctStyle);
// is a null op if already defined
XWPFStyles styles = docxDocument.createStyles();
style.setType(STStyleType.PARAGRAPH);
styles.addStyle(style);
}
}

vaadin label text not wrapping

As it says on the tin.. I cannot get a label's text to wrap. Essentially I am building like a comments panel, user enters a comment and its displayed with timestamp etc.
I want the labels to both display with ContentMode.PREFORMATTED but also wrap.
The layouts of which contain the label are fixed width (100%) as is the label obviously by default, from what I have readin the book of vaadin what I am doing should work?
here is my code snippet:
VerticalLayout container = new VerticalLayout();
rootLayout.addComponent(container);
VerticalLayout comment = new VerticalLayout();
container.addComponent(comment);
Label createdByLbl = new Label(entity.getManagedMetadata().getAttrValue("createdBy") + " said:");
createdByLbl.setId("conversation.comment.username." + repositoryUID);
createdByLbl.setStyleName("conversation-comment-username");
Label createdDateLbl = new Label(entity.getManagedMetadata().getAttrValue("createdDate"));
createdDateLbl.setId("conversation.comment.createddate." + repositoryUID);
createdDateLbl.setSizeUndefined();
String text = entity.getDataNode().getAttrValue("text");
Label textLbl = new Label(text, ContentMode.PREFORMATTED);
textLbl.setId("conversation.comment.text." + repositoryUID);
comment.addComponent(createdByLbl);
comment.addComponent(textLbl);
comment.addComponent(createdDateLbl);
comment.setExpandRatio(createdByLbl, 0.2f);
comment.setExpandRatio(textLbl, 0.7f);
comment.setExpandRatio(createdDateLbl, 0.1f);
Note the container is also wrapped by CssLayout (rootLayout), which is full sized.
I want the textLbl as seen above to display as formatted should the user enter text on separate lines themselves and wrap if they have entered a long paragraph comment.
Here is a picturing showing my dilemma.
Any help would be appreciated.
Thanks,
Try with css.
For example:
textLbl.addStyleName("wrapLine");
Css:
.wrapLine{
word-wrap: break-word; /* IE */
white-space: -moz-pre-wrap; /* Firefox */
}

Enter key focus for a JButton in java swing?

How to make Enter key focus for a JButton in java swing?
i have done like this
btn_Login.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("enter key pressed");
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0,false), txt_Username.WHEN_FOCUSED);
but not working
I assume you want a specific button to be "pressed" if you just press Enter on a certain window.
To do this, you have to set the defaultButton on your RootPane of the current JFrame.
Here is an example:
JButton btn = new JButton();
JFrame frame = new JFrame();
frame.getContentPane().add(btn);
frame.getRootPane().setDefaultButton(btn);
That should give you the expected result.
Thanks to all! Here are some notes that I found out to fix the enter problem for the Nimbus Look and fell.
The enter key works with linux but not with windows ( Nimbus ).
For windows the actual "doClick" of the button is done with space ( Key Char 32 ).
It's possible to set the "enter" to do a click, but it must be done AFTER setting your Nimbus Look and Feel.
Here is the code that is used in my application.
UIManager.setLookAndFeel(new NimbusLookAndFeel());
//- hack pour que les bouttons qui ont le focus fassent un doClick
//- lorsque "enter" est taper. Auparavant, c'etait l'espace qui
//- activait le doClick.
InputMap im = (InputMap)UIManager.get("Button.focusInputMap");
im.put( KeyStroke.getKeyStroke( "ENTER" ), "pressed" );
im.put( KeyStroke.getKeyStroke( "released ENTER" ), "released" );
( Sorry for my french comments ! ).

Categories