JLabel with multiple lines and alignment to the right - java

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

Related

jpanel cannot make gridlayout with 7 rows and 2 cols

i want to ask if anything goes wrong with my code. i've set my frame with borderlayout . and on the center part, i want to use gridlayout with 7rows and 2 cols inside them.
paneltengah= new JPanel();
paneltengah.setLayout(new GridLayout(7,2));
labelname = new JLabel(lbl_name,SwingConstants.LEFT);
labelusername = new JLabel(lbl_username,SwingConstants.LEFT);
labelpassword = new JLabel(lbl_password,SwingConstants.LEFT);
labelgender = new JLabel(lbl_gender,SwingConstants.LEFT);
labelemail = new JLabel(lbl_email,SwingConstants.LEFT);
labelhobby = new JLabel(lbl_hobby,SwingConstants.LEFT);
labelrole = new JLabel(lbl_role,SwingConstants.LEFT);
textname = new JTextField(20);
textusername = new JTextField(20);
textpassword = new JPasswordField(20);
textemail = new JTextField(20);
comboboxhobby = new JComboBox();
comboboxrole = new JComboBox();
radiobuttonmale = new JRadioButton("Male");
radiobuttonfemale = new JRadioButton("Female");
ButtonGroup btngroup = new ButtonGroup();
btngroup.add(radiobuttonmale);
btngroup.add(radiobuttonfemale);
paneltengah.add(labelname);
paneltengah.add(labelusername);
paneltengah.add(labelpassword);
paneltengah.add(labelgender);
paneltengah.add(labelemail);
paneltengah.add(labelrole);
paneltengah.add(labelhobby);
//// paneltengah.add(textname); when i open this, the layout become awkward
//// paneltengah.add(textusername);
//// paneltengah.add(textpassword);
//// paneltengah.add(radiobuttonmale);
//// paneltengah.add(radiobuttonfemale);
//// paneltengah.add(comboboxhobby);
//// paneltengah.add(comboboxrole);
pane.add(paneltengah, BorderLayout.CENTER);
the following pictures is shown without opening the comment
the following picture is shown with uncomment
what is wrong with my code ?
First of all, a GridLayout sizes all components evenly in its associated Container, which explains why your labels and fields are all the same size. For example, if you had a JTextArea 200 columns × 20 lines in your JPanel, then even the tiniest label would occupy that huge a space as well!
Next, according to the GridLayout Javadoc, when a GridLayout instance is constructed with two non-zero arguments, the number of rows gets fixed and the number of columns is adjusted according to the number of components put into the parent Container.
What I suggest is using a BorderLayout to set up your main form layout. Put your title at NORTH and keep the CENTER for your labels and fields (your current JPanel).
For your labels and fields, the simplest solution might be using a GridLayout(0, 2) (fixed number of columns). But all your components will still be equally sized.
If you need more control over the size of your components (e.g., fields wider than labels), then I suggest using another layout manager such as GridBagLayout. I know it's more complex to manage but using a GridBagLayout formatting preview utility should help. Such a program may be named something like GridBagLab (I know David Geary's book Graphic Java volume 2 — Swing features one on its companion CD).
There is also a GridBagLayout tutorial at https://www.youtube.com/watch?v=Ts5fsHXIuvI.

how to Put JLabel text over a JTextField

how to add a JLabel simple text over/above a JTextField.
I tried many commands as you can see in my code but nothings works.
this is a snapshot of my code
private JPanel createTextPanel() {
int panelWidth = PANEL_SIZE.width;
int panelHeight = PANEL_SIZE.height/3;
Dimension panelSize = new Dimension(panelWidth,panelHeight);
JPanel textPanel = new JPanel();
textPanel.setPreferredSize(panelSize);
//textPanel.setLayout(null);
/* Add text */
JLabel Text_RED = new JLabel();
Text_RED.setText("Red");
//Text_RED = new JLabel("\nRED\n");
//Text_RED.setHorizontalTextPosition(SwingConstants.TOP);
//Text_RED.setVerticalAlignment(SwingConstants.TOP);
Red = new JTextField(3);
//Red.setVerticalAlignment(JTextField.TRAILING );
Red.setLocation(100,100);
//Red.setLocation(50, 50);
JLabel Text_Green = new JLabel("Green");
Green = new JTextField(3);
JLabel Text_Blue = new JLabel("Blue");
Blue = new JTextField(3);
//setLayout(new GridLayout(2,2,10,10));
textPanel.add(Text_RED);
textPanel.add(Red);
textPanel.add(Text_Green);
textPanel.add(Green);
textPanel.add(Text_Blue);
textPanel.add(Blue);
return textPanel;
}
Suggestions:
Don't use null layouts and absolute positioning. While it seems initially that using these tools is the easiest way to create complex GUI's, it's really a newbie fallacy, as the more you understand and use the layout managers, the more you'll find that they make the job of creating GUI's much easier, and the results much more attractive.
Learn about and use the layout managers. Tutorial link.
Consider using a BorderLayout and adding your JLabel BorderLayout.CENTER and the JTextField at BorderLayout.PAGE_END. As a side note, I generally avoid placing JTextFields in a BorderLayout.CENTER position since this will cause horizontal stretching of the field if the GUI changes size, which I don't think is aesthetically pleasing.

Java Swing panel layered on top with centered text

I'm making a simple Jeopardy-esque game:
using Java Swing. It's obviously a JFrame with a JPanel in it and buttons in rows.
Now what I need is to add a layered panel with a centered and wrapped text in it:
Which I can remove later. I already tried using JTextPane and JTextArea and JPanel, none of those want to even display. The best effect I have achieved with AWT Panel, it does display but I can't center or wrap text in it.
Here's some code for which I appologise, I would usually try to make it short and readable but since it's not working I don't know what to do with it to make ti look better:
JLabel questionLabel = new JLabel(questionList.get(randomNumber).getQuestion(), SwingConstants.CENTER);
Font font = new Font("Arial", Font.PLAIN, 20);
//------------------JTextPane--------------------
JTextPane questionPane = new JTextPane();
questionPane.setForeground(Color.WHITE);
questionPane.setSize(gameWidth, gameHeight);
questionPane.setText(questionList.get(randomNumber).getQuestion());
questionPane.setFont(font);
questionPane.setEditable(false);
//------------------AWT panel--------------------
Panel awtPanel = new Panel();
awtPanel.setBackground(Color.blue);
awtPanel.setSize(game.getWidth(),game.getHeight());
Label labelQuestion = new Label("<html>" + questionList.get(randomNumber).getQuestion() + "</html>", Label.CENTER);
labelQuestion.setFont(font);
awtPanel.setForeground(Color.white);
awtPanel.add(labelQuestion);
//------------------JPanel-----------------------
JPanel layeredPanel = new JPanel();
layeredPanel.setBackground(Color.blue);
layeredPanel.setSize(game.getWidth(),game.getHeight());
JLabel jLabelQuestion = new JLabel("<html>" + questionList.get(randomNumber).getQuestion() + "</html>", SwingConstants.CENTER);
jLabelQuestion.setFont(font);
layeredPanel.setForeground(Color.WHITE);
layeredPanel.add(jLabelQuestion, BorderLayout.CENTER);
game.getLayeredPane().add(layeredPanel, JLayeredPane.DEFAULT_LAYER);
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
button.setEnabled(false);
font = new Font("Arial", Font.PLAIN, 16);
button.add(jLabelQuestion, BorderLayout.CENTER);
button.setDisabledIcon(new ImageIcon(source.getScaledInstance(gameWidth/4, gameHeight/5, java.awt.Image.SCALE_SMOOTH)));
questionList.remove(randomNumber);
logger.info(questionList.size());
game.getLayeredPane().remove(layeredPanel);
UPDATE: I chnaged to SWT rather than Swing, and I use the StackLayout with a few Composites in it, and just change between them as I see fit.
You can generally solve issues like this with a JLabel.
I would recommend encapsulating the above grid in the BorderLayout.CENTER of another pane, perhaps a new content pane. Then, add the caption to BorderLayout.NORTH.
As a more tangible example,
private void createContent() {
this.getContentPane().setLayout(new BorderLayout());
//establish the panel currently set as center, here labeled "everythingElse"
this.getContentPane().add(everythingElse, BorderLayout.CENTER);
//Create a JLabel with your caption
JLabel jlbl = new JLabel("Question");
//format that caption, most details being rather obvious, but most importantly:
jlbl.setHorizontalAlignment(SwingConstants.CENTER); //keeps text centered
this.getContentPane().add(jlbl, BorderLayout.NORTH); //add it to the top of the panel
//...other cleanup operations...
}
The issue with grid panes is that they have a limited tolerance for the number of components visible in them. If you overload one, it won't show. For BorderLayout panes, you can easily swap new items into and out of them.
For efficiency's sake, I might recommend compiling this JLabel as a final somewhere else in your code, and holding onto it for when you need it. This way, you will also dodge overhead from repeatedly creating the label object.
Lastly, avoid AWT whenever you can. It's been deprecated for an excess of ten years, and if you do use it you will run into numerous critical problems involving heavyweight and lightweight component incompatibilities. If you intend to use another windowing kit, consider implementing the new standard, JavaFX, with a JFXPane-- it's much more tolerant of HTML syntax, as well.

Including linebreak in StringBuilder

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.

Java: Linebreaks in JLabels?

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);

Categories

Resources