I'm having trouble trying to get a linebreak included in a Stringbuilder to appear in a JLabel.
I've found a couple of similar problems solved here, e.g. [here] Problems to linebreak with an int in JLabel and [here] How do I append a newline character for all lines except the last one? , along with a few others but none of them seem to work for me.
When printing to System.out, it works fine and I get a new line each time but when passed to a JLabel, everything appears as one line.
Here's the current version of the code, which has attempted to append a newline character, as well as including one in the main declaration. Neither has any effect when passed to the JLabel:
public void layoutCenter() {
JPanel central = new JPanel();
add(central, BorderLayout.CENTER);
JTabbedPane tabs = new JTabbedPane();
this.add(tabs);
// memory tab
StringBuilder mList = new StringBuilder();
memLocList = new Memory[MEM_LOCATIONS]; //Memory is a separate class
for (int i = 0; i < memLocList.length; i++) {
mList.append("\n");
memLocList[i] = null;
mList.append("Memory location: " + i + " " + memLocList[i] + "\n");
}
System.out.println(mList.toString());
JComponent memTab = makeTextPanel(mList.toString());
tabs.addTab("Memory", memTab);
}
protected JComponent makeTextPanel(String text) {
JPanel panel = new JPanel(false);
JLabel filler = new JLabel(text);
panel.add(filler);
return panel;
}
I've also tried using System.getProperty(line.separator) with similar results and can't think of anything else to try so thought I'd appeal for help here.
Thanks,
Robert.
-EDIT-
Thanks to mKorbel, changing the JLabel to a JTextPane solved it.
The two lines in question are:
JTextPane filler = new JTextPane();
filler.setText(text);
Thanks again to everyone.
JLabel isn't designated to held multilines document, there are two choices (by accepting newline or tab by default)
if document could not be decorated or styled somehow then to use JTextArea
in the case document could be decorated or styled somehow then to use JEditorPane or JTextPane
You're going to have to use <html> and <br> to get line breaks in a JLabel Swing component.
If you absolutely must use JLabel, then I suggest using one for each line.
You can make a JLabel have mulitple lines by wrapping the text in HTML tags and using br tags to add a new line.
If you news auto wrapping I suggest using a JTexrArea. You can make it uneditable and style it so it looks like a label.
You can look at this tutorial:
http://docs.oracle.com/javase/tutorial/uiswing/components/html.html
One of the example is using html to make it two lines for a JButton text. It should be very similar.
Related
I am using MigLayout 3.5.5, as the newer updates are not compatible with my older code.
Problem
When setting text to a JTextPane in a MigLayout, the JTextPane will take double the space (according to font size) IF the text I am setting the JTextPane contains space characters. It does not happen all the time, but in the specific program I am making, it happens frequently.
The program's goal is to present information in a letter-by-letter basis, so there is a button that updates the text to the next letter. However, the text bounces around, because the JTextPane is sometimes occupying more space than usual. I identified a certain pattern to the height differences.
Pattern
A new line indicates that I added a letter.
"|" represents a space character in the text.
"Space" means JTextPane is taking double the space.
Full String: "The quick brown fox jumps over the lazy dog."
T
Th
The
The|
The|q (Space)
The|qu
The|qui (Space)
The|quic
The|quick (Space)
The|quick|
Note: I stopped the pattern here, because from this point on (starting with The|quick|b), every single letter addition resulted in the JTextPane occupying double its height.
I've already tried printing out the letter-by-letter text to the console to see if there were any new line characters within the text being added, but to no avail. I also thought it might be a problem with the automatic wrapping of the JTextPane, but the text I inserted isn't quite long enough to wrap in the JFrame's size.
Here is a short example to reproduce the behavior:
public class MainFrame extends JFrame {
int currentLetter = 1;
final String FULL_TEXT = "The quick brown fox jumps over the lazy dog.";
JTextPane text;
JButton addLetter;
MainFrame() {
setSize(500, 500);
setLayout(new MigLayout("align center, ins 0, gap 0"));
addElements();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MainFrame application = new MainFrame();
}
});
}
private void addElements() {
text = new JTextPane();
text.setEditable(false);
text.setFont(new Font("Times New Roman", Font.BOLD, 19));
text.setForeground(Color.WHITE);
text.setBackground(Color.BLACK);
add(text, "alignx center, wmax 80%, gapbottom 5%");
addLetter = new JButton("Add Letter");
addLetter.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (currentLetter != FULL_TEXT.length()) {
currentLetter++;
updateText();
}
}
});
add(addLetter, "newline, alignx center");
updateText();
}
private void updateText() {
String partialText = new String();
for (int letter = 0; letter < currentLetter; letter++) {
partialText += FULL_TEXT.toCharArray()[letter];
}
text.setText(partialText);
}
}
Why am I using JTextPane?
I tried using JLabel for this task, and it worked well... until the text was long enough to wrap. Then, when I used HTML within the JLabel text to wrap it, every time I updated the text, it would take time for the HTML to render and result in some pretty nasty visual effects.
Next, I tried JTextArea to disguise it as a JLabel, since it not only has line wrapping, but word wrapping as well. It was a great solution, until I found out that I couldn't use a center paragraph alignment in a JTextArea.
So I settled for a JTextPane, which will work well if only I got rid of the extra space at the bottom of it.
Thanks in advance for your help!
The solution is to append text by using the insertString() method on the StyledDocument of the JTextPane instead of using setText() on the JTextPane itself.
For example, instead doing this every time:
JTextPane panel = new JTextPane();
panel.setText(panel.getText() + "test");
You should do this:
JTextPane panel = new JTextPane();
StyledDocument document = panel.getStyledDocument();
document.insertString(document.getLength(), "test", null);
And of course you need to catch the BadLocationException.
Then the space disappears. Here's the question where I found my answer to the rendering problem: JTextPane appending a new string
The answers to those questions don't address the problem with the space, but they do show the correct way to edit text in the JTextPane.
I searched through many posts and figured out that JLabel supports HTML.
So I can do
JLabel search = new JLabel("<html>Search<br/> By:</html>");
to get multiple lines. Above code will result in
Search
By:
However, What I want is something like
Search
By:
Adding spaces before "By:" will work only when the window is not resizable(And very silly lol).
Can anyone tell me how to modify this code to make it work as I wanted?
Slightly simpler HTML than seen in #MadProgrammer's answer:
new JLabel("<html><body style='text-align: right'>Search<br>By:");
Non-breaking spaces ( ) are supported:
new JLabel("<html>Search<br/> By:</html>");
If you want to have real right-alignment, use individual right-aligned labels and combine them:
JLabel search = new JLabel("Search", SwingConstants.RIGHT);
JLabel by = new JLabel("By:", SwingConstants.RIGHT);
JPanel combined = new JPanel();
combined.setOpaque(false);
combined.setLayout(new GridLayout(2, 1));
combined.add(search);
combined.add(by);
or use a read-only JTextPane instead (with \n for line breaks):
JTextPane text = new JTextPane();
SimpleAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setAlignment(attributes, StyleConstants.ALIGN_RIGHT);
StyleConstants.setFontFamily(attributes, "Default");
text.setParagraphAttributes(attributes, true);
text.setEditable(false);
text.setOpaque(false);
text.setText("Search\nBy:");
There are a number of ways you might achieve this, one of the safer ways might be to use a <table> and aligning both cells to the right...
JLabel label = new JLabel(
"<html><table border='0' cellpadding='0' cellspacing='0'>" +
"<tr><td align='right'>Search</td></tr>" +
"<tr><td align='right'>By:</td></tr></table>"
);
This overcomes issues with differences between fonts and font rendering on different platforms
I am new to programming and I would like some tips.
I have a program that reads from a text file using the the following method:
BufferedReader reader = new BufferedReader(new FileReader(file));
.....
This works but the problem is that some lines are long and I can't see all the text in the GUI. How should I tell Java to go to next line if length is equal to a certain amount?
Example text:
A week after Mozart died, his ghost was discovered trying to erase his music. When asked why, it said "I'm decomposing.
Instead of two lines, I want to parse it into four lines. Any help would be appreciated.
as per your comments, you are using JLabel for displaying the data.
to show multi-line text in JLabel just wrap your text in <html> tag like:
JLabel label = new JLabel("<html>your long text here ....</html>");
example:
String theReadLineFromTextFile = ....;
theReadLineFromTextFile = "<html>"+theReadLineFromTextFile+"</html>";
JLabel label = new JLabel(theReadLineFromTextFile);
//or
JLabel label = new JLabel();
label.setText(theReadLineFromTextFile);
If you can't do it in the gui, then some of the answers here will help: Wrap the string after a number of characters word-wise in Java
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Multiline text in JLabel
I want to do this:
JLabel myLabel = new JLabel();
myLabel.setText("This is\na multi-line string");
Currently this results in a label that displays
This isa multi-line string
I want it to do this instead:
This is
a multi-line string
Any suggestions?
Thank you
EDIT: Implemented solution
In body of method:
myLabel.setText(convertToMultiline("This is\na multi-line string"));
Helper method:
public static String convertToMultiline(String orig)
{
return "<html>" + orig.replaceAll("\n", "<br>");
}
You can use HTML in JLabels. To use it, your text has to start with <html>.
Set your text to "<html>This is<br>a multi-line string" and it should work.
See Swing Tutorial: JLabel and Multiline label (HTML) for more information.
public class JMultilineLabel extends JTextArea{
private static final long serialVersionUID = 1L;
public JMultilineLabel(String text){
super(text); // According to Mr. Polywhirl, this might improve it -> text + System.lineSeparator()
setEditable(false);
setCursor(null);
setOpaque(false);
setFocusable(false);
setFont(UIManager.getFont("Label.font"));
setWrapStyleWord(true);
setLineWrap(true);
//According to Mariana this might improve it
setBorder(new EmptyBorder(5, 5, 5, 5));
setAlignmentY(JLabel.CENTER_ALIGNMENT);
}
}
It totally looks the same for me, but its ugly
Another easy way (but changes the text style a bit) is to use a <pre></pre> html block.
This will persist any formatting the user entered if the string you are using came from a user input box.
Example:
JLabel label = new JLabel("<html><pre>First Line\nSecond Line</pre></html>");
The direct procedure of writing a multi-line text in a jlabel is:
JLabel label = new JLabel("<html>First Line<br>Second Line</html>");
The problem with using html in JLabel or any Swing component is that you then have to style it as html, not with the usual setFont, setForeground, etc. If you're ok with that, fine.
Otherwise you can use something like MultilineLabel from JIDE, which extends JTextArea. It's part of their open source Commom Layer.
JLabel can accept html code. Maybe you can try to use the <br> tag.
Example:
JLabel myLabel = new JLabel();
myLabel.setText("<html> This is a <br> multi-line string </html>");
http://java.sun.com/docs/books/tutorial/uiswing/components/html.html
I'm trying to make a Swing JLabel with multiple lines of text. It's added just fine, but the line breaks don't come through. How do I do this? Alternatively, can I just specify a maximum width for a JLabel and know that the text would wrap, like in a div?
private void addLegend() {
JPanel comparisonPanel = getComparisonPanel();
//this all displays on one line
JLabel legend = new JLabel("MMM FFF MMM FFFO O OOM M MMMM.\nMMM FFF MMM FFFO O OOM M MMMM.\nMMM FFF MMM FFFO O OOM M MMMM.\n");
comparisonPanel.add(legend);
}
Use HTML in setText, e.g.
myLabel.setText("<html><body>with<br>linebreak</body></html>");
You can get automatic line break if you set the paragraph width in html.
label.setText("<html><p style=\"width:100px\">"+paragraph+"</p></html>");
By default, Swing does not wrap text. If you specify a size on the JLabel it will only paint the part of the text that fits and then add "..." to the end.
As suggested you can use HTML to enable line wrapping. However, I've actually created a custom Swing UI delegate not long ago to achieve this and even more: MultiLineLabelUI.
It will wrap your text to fit the available space and also respect hard line breaks. If you choose to try it out, it is as simple as:
JLabel label = new JLabel("Text that'll wrap if necessary");
label.setUI(MultiLineLabelUI.labelUI);
Or alternatively use the custom MultiLineLabel class that in addition to wrapping text supports vertical and horizontal text alignment.
UPDATE
I lost the domain with the original code samples. It can now be viewed on github instead: https://github.com/sasjo/multiline
You can put HTML inside of a JLabel and use the linebreak tag to achieve this.
What about using the wrapping feature in a JTextArea?
String text = "some really long string that might need to"+
"be wrapped if the window is not wide enough";
JTextArea multi = new JTextArea(text);
multi.setWrapStyleWord(true);
multi.setLineWrap(true);
multi.setEditable(false);
JLabel single = new JLabel(text);
JPanel textpanel = new JPanel(new GridLayout(2,1));
textpanel.add(multi);
textpanel.add(single);
JFrame frame = new JFrame();
frame.add(textpanel);
frame.pack();
frame.setVisible(true);
Simple,use HTML. Java Swing components though does not provide a 'fantastic' support for the HTML, you can use it for such simple purposes.
label.setText("<html>This is first line.<br/>This is second line.</html>");
I did not manage to specify a maximum width for a label but you can specify a concrete width.
By measuring the current width of a JLabel we can only apply the new fixed width if the JLabels's width is higher that our maxWidth:
JLabel label = new JLabel("<html>" + myVeryLongMessage + "<html>");
int maxWidth = 400;
Dimension size = label.getPreferredSize();
if (size.width > maxWidth) {
// Estimate the number of lines
int lineCount = (int) Math.ceil(((double) size.width) / maxWidth);
lineCount += 1; // Add one extra line as reserve
size.width = maxWidth; // Apply the maximum width
// Increase the height so that all lines will be visible
size.height *= lineCount;
label.setPreferredSize(size);
}
You can use a JTextArea and disable the TextArea, this way, you will only display what you want, and the user won't be able to type in
JTextArea area = new JTextArea("Here \n\n you \n\n put \n\n your \n\n text");
area.setBounds(10, 11, 500, 143);
area.setEditable(false);
yourPannel.add(area);