Java Swing GUI JLabel Not Showing - java

I am trying to write a Title for the main menu of my program, by using a JLabel, but it doesn't seem to appear on my screen.
import javax.swing.*;
public class GUI {
public GUI() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
panel.setLayout(new GridLayout());
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Title");
frame.pack();
frame.setSize(854,560);
frame.setVisible(true);
JLabel title = new JLabel();
title.setText("Title");
//title.setSize();
title.setVisible(true);
}
public static void main(String[] args) {
new GUI();
}
}
What am I doing wrong and how could I change the position of the Text if I manage to make it visible?
And I also want to add a button to go to the next page so if you could tell me how to do that too that would be great.

I would quickly and untested say that you are adding the label after you set the frame visible.
Do it before. Else you would have to revalidate and repaint the frame

As I can see in your code you are not adding title in panel. As a quick solution put panel.add(title); after title.setVisible(true); line in your code, it will display the label.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
panel.setLayout(new GridLayout());
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Title");
frame.pack();
frame.setSize(854,560);
frame.setVisible(true);
JLabel title = new JLabel();
title.setText("Title");
//title.setSize();
title.setVisible(true);
panel.add(title); //<---- this one line will diaplay label in GUI

Related

JFrame not displaying panel content

I just got started learning JFrame and is trying to create a frame containing JLabels and JTextFields frame using grouplayout, but the contents inside my panel aren't appearing when I run the program.
All help is appreciated.
package practice;
import java.awt.*;
import javax.swing.*;
public class Boxc {
public static void main(String[] args){
JFrame frame = new JFrame("---------------------(-_-)---------------------");
JLabel headText = new JLabel("Teach Me");
//head text
headText.setVerticalAlignment(JLabel.TOP);
headText.setHorizontalAlignment(JLabel.CENTER);
headText.setFont(headText.getFont().deriveFont(20f));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 500);
frame.setResizable(false);
frame.setLocationRelativeTo(null); //Center start position
frame.add(headText);
//panel 1
JPanel panel1 = new JPanel();
GroupLayout layout = new GroupLayout(panel1);
panel1.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
JLabel uInput = new JLabel("When You Type:");
JTextField uText = new JTextField("Enter Here");
JLabel iReply = new JLabel("I Reply:");
JTextField iText = new JTextField("Enter Here");
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
hGroup.addGroup(layout.createParallelGroup().
addComponent(uInput).addComponent(iText));
hGroup.addGroup(layout.createParallelGroup().
addComponent(uText).addComponent(iText));
layout.setHorizontalGroup(hGroup);
frame.add(panel1);
}}
Java is weird.
It all has to do with the ordering of your JFrame methods. You must ALWAYS do frame.setVisible(true); at the end, preferably as the last line of code in whatever you're using to initiate the JFrame. In that case,
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 500);
frame.setResizable(false);
frame.setLocationRelativeTo(null); //Center start position
frame.add(headText);
would be changed to
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 500);
frame.setResizable(false);
frame.setLocationRelativeTo(null); //Center start position
frame.add(headText);
frame.setVisible(true);
Hope this helps.
EDIT: ignore the changing from/to. Put the frame.setVisible(true); after frame.add(panel1);.

Java: Having Multiple Components on a JFrame

I want to have multiple components on a JFrame. I don't want any UI formatting. I just want multiple components to be drawn. My full code is to large to post so here is my JFrame set up.
JPanel jPanel = new JPanel();
jPanel.setLayout(new FlowLayout());
jPanel.add(board.getPieceAt(0,0));
jPanel.add(board);
frame.add(jPanel);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
board and board.getPieceAt(0,0); are JComponents
No combination of frame.add() or adding panels seems to get both to render. It's always the last one added that gets drawn.
This example renders two components. I updated my code above to mimic this example as much as possible and it still results in an empty frame. To me it seems that I'm doing exactly what the example is doing yet I get a different result.
import java.awt.FlowLayout;
import java.awt.BorderLayout;
import javax.swing.*;
public class TestFrameExample {
public static void main(){
JFrame frame = new JFrame("JFrame Example");
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JLabel label = new JLabel("This is a label!");
JButton button = new JButton();
button.setText("Press me");
panel.add(label);
panel.add(button);
frame.add(panel);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
How do I get both components to render on the JFrame?

Picture and text in same window

This program is supposed to open a window, add a picture, and then add the text "hello world" above the picture. The text appears when i do frame.add(label) and then try to add the picture (like the code shows), but even when I do the opposite and add the picture first I only get a gray schreen. Can anybody show me how I can get both the picture and the text?
public window(){
JFrame frame = new JFrame("name");
JLabel label = new JLabel ("hello world", JLabel.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setSize(600, 400);
frame.setVisible(true);
label.setAlignmentX(0);
label.setAlignmentY(0);
frame.add(label);
frame.add(new JLabel(new ImageIcon("file")));;
}
}
You should use overlay layout, but it is applicable on JPanel.
So add a JPanel to your frame then apply the layout, finally add the components.
Your code may be like that:
public window(){
JFrame frame = new JFrame("name");
JLabel label = new JLabel ("hello world", JLabel.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel() {
public boolean isOptimizedDrawingEnabled() {
return false;
}
};
LayoutManager overlay = new OverlayLayout(panel);
panel.setLayout(overlay);
frame.setResizable(false);
frame.setSize(600, 400);
frame.setVisible(true);
label.setAlignmentX(0);
label.setAlignmentY(0);
panel.add(label);
panel.add(new JLabel(new ImageIcon("file")));
frame.add(panel, BorderLayout.CENTER);
}
}
A label can have both text and icon, and the relative position can be customized.
JLabel label = new JLabel ("hello world", new ImageIcon("file"), JLabel.CENTER);
label.setVerticalTextPosition(SwingConstants.TOP);
frame.add(label);
//frame.add(new JLabel(new ImageIcon("file")));;
The default layout is BorderLayout, and add(label, BorderLayout.CENTER).

Swing GUI problems with BorderLayout

I'm currently trying to get along with Layouts, considering that I never really understood them and only did nullLayout instead, absolutely positioning all elements then.
However, I currently have a suitable small project, where I am trying to learn it, which is some small chat service.
Here is a picture right now:
And here is a picture, of how I imagine it to be finished (Please note that this is just some concept, but it should give you the right idea. I'm not a graphic artist):
Here is my current code:
public class Gui {
JFrame frame;
JTextArea textfield;
JTextField enterMessage;
public Gui(){
frame = new JFrame();
frame.setSize(600, 400);
textfield = new JTextArea();
textfield.setText("Textfield");
textfield.setSize(400, 300);
JPanel messagePanel = new JPanel();
JTextField chatMessage = new JTextField();
chatMessage.setText("Send me");
JButton send = new JButton();
send.setText("Send");
messagePanel.add(chatMessage, BorderLayout.WEST);
messagePanel.add(send, BorderLayout.EAST);
frame.add(textfield, BorderLayout.WEST);
frame.add(messagePanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
}
My idea, together with the understanding of BorderLayouts so far was to put the Textfield, where the chat dialog ends up in later on, right inside the frame, on the WEST-side.
The button to send and the field to enter some text will be inside a panel, with an own borderlayout, while the button has some smaller part on the right and the rest of the width is being filled with the textfield.
The whole panel then ends on the SOUTH-side of the frame.
However, right now I have the problem, that the elements keep shrinking to the least possible size.
I tried to fix this with setSize(); , but that does not have an impact at all, it is just being completely ignored.
Any help to point me into the right direction?
Initially, you've got one simple problem:
// should be new JPanel(new BorderLayout())
JPanel messagePanel = new JPanel();
Then, after that, generally BorderLayout likes to stretch the component in BorderLayout.CENTER. So you want to put your textfield and chatMessage in the center.
public Gui(){
frame = new JFrame();
frame.setSize(600, 400);
textfield = new JTextArea();
textfield.setText("Textfield");
// textfield.setSize(400, 300);
JPanel messagePanel = new JPanel(new BorderLayout());
JTextField chatMessage = new JTextField("Send me");
JButton send = new JButton("Send");
messagePanel.add(chatMessage, BorderLayout.CENTER);
messagePanel.add(send, BorderLayout.EAST);
frame.add(textfield, BorderLayout.CENTER);
frame.add(messagePanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
Once you do that, you should get something like this:
But, as a few words of advice:
Don't rely on setSize of a JFrame. Instead, you should use setPreferredSize on a single component which the entire UI should size itself around. (Probably the main text area.) The size of a JFrame includes, for example, the title bar.
You should consider wrapping your JTextArea in a scroll pane. You can then instead setPreferredSize on the viewport.
After you have a component with a preferred size, call pack() on the JFrame before calling setVisible(true). This will size it automatically.
Something like:
frame = new JFrame();
// frame.setSize(600, 400);
...
JScrollPane pane = new JScrollPane(
textfield,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// specifying initial size for the
// visible portion of the scroll pane
pane.getViewport().setPreferredSize(new Dimension(320, 200));
frame.add(pane, BorderLayout.CENTER);
frame.add(messagePanel, BorderLayout.SOUTH);
// entire UI sizes around the scroll pane view
frame.pack();
frame.setVisible(true);
Try BoxLayout insted BorderLayout in messagePanel:
messagePanel.setLayout(new BoxLayout(messagePanel,BoxLayout.LINE_AXIS));
messagePanel.add(chatMessage);
messagePanel.add(send);
And for textField:
frame.add(textfield, BorderLayout.CENTER);
Try setting preferred size dimensions of the elements.
textfield.setText("Textfield");
textfield.setPreferredSize(new Dimension(600, 300));
//some other code
JTextField chatMessage = new JTextField();
chatMessage.setPreferredSize(new Dimension(500, 25));
//some other code
As pointed out by Sridhar, BorderLayout does not always respect the dimensions of sub-panels. To fix this, you should initialize your sub-panels (in this case textfield and messagePanel) using setPreferedSize() instead of setSize().
change your constructor to
public Gui() {
frame = new JFrame();
frame.setSize(600, 400);
textfield = new JTextArea();
textfield.setText("Textfield");
textfield.setSize(400, 300);
// set border layout to JPanel
JPanel messagePanel = new JPanel(new BorderLayout());
JTextField chatMessage = new JTextField();
chatMessage.setText("Send me");
JButton send = new JButton();
send.setText("Send");
// add JTextField to CENTER and button to EAST
messagePanel.add(chatMessage, BorderLayout.CENTER);
messagePanel.add(send, BorderLayout.EAST);
// add textArea to CENTER of JFrame
frame.add(textfield, BorderLayout.CENTER);
frame.add(messagePanel, BorderLayout.SOUTH);
frame.setVisible(true);
}
and it will work..

Setting orientation within a JPanel

I am trying to use a nested JPanel, which I can then reuse in different parts of my application, eg navigation bar at the top of the page. I am having trouble setting the orientation of the items, eg I want the button to be above the textfield.
If I create them individually and add them directly to the JPanel they come out one on top of the other as inteneded, as below:
final JFrame frame = new JFrame("Nested Layout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel gui = new JPanel(new BorderLayout(5,5));
gui.setBorder( new TitledBorder("BorderLayout(5,5)") );
JButton button = new JButton("Button");
JButton button1 = new JButton("Button1");
gui.add(button, BorderLayout.NORTH);
gui.add(button1, BorderLayout.SOUTH);
frame.setContentPane(gui);
frame.pack();
frame.setLocationRelativeTo(null);
try {
// 1.6+
frame.setLocationByPlatform(true);
frame.setMinimumSize(frame.getSize());
} catch(Throwable ignoreAndContinue) {
}
frame.setVisible(true);
However, if I create a nested JPanel and put it inside another JPanel, so I can reuse it, they come out side by side, as below:
final JFrame frame = new JFrame("Nested Layout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel gui = new JPanel(new BorderLayout(5,5));
gui.setBorder( new TitledBorder("BorderLayout(5,5)") );
JPanel container = new JPanel();
JButton button = new JButton("Button");
JButton button1 = new JButton("Button1");
container.add(button, BorderLayout.NORTH);
container.add(button1, BorderLayout.SOUTH);
gui.add(container);
frame.setContentPane(gui);
frame.pack();
frame.setLocationRelativeTo(null);
try {
// 1.6+
frame.setLocationByPlatform(true);
frame.setMinimumSize(frame.getSize());
} catch(Throwable ignoreAndContinue) {
}
frame.setVisible(true);
I have tried setting the componenetOrientation,
container.setComponentOrientation(ComponentOrientation.);
but there is no option for vertical
I have tried setting the componenetOrientation
Please note the problem has nothing to do with component orientation: it's a layout manager problem as explained below.
However, if I create a nested JPanel and put it inside another JPanel, so I can reuse it, they come out side by side
Here:
JPanel container = new JPanel();
...
container.add(button, BorderLayout.NORTH);
container.add(button1, BorderLayout.SOUTH);
The default layout manager for panels is FlowLayout and it will ignore BorderLayout constraints. You'll have to set BorderLayout as layout manager not only to gui panel but to container panel as well.
JPanel container = new JPanel(new BorderLayout());
...
container.add(button, BorderLayout.NORTH);
container.add(button1, BorderLayout.SOUTH);
Try setting a layout for your JPanel. There are many Layouts available in the package java.awt. Some of them are BorderLayout, GridBagLayout, CardLayout, FlowLayout, GridLayout.
I have just added One line to your code, and now, it puts the buttons in the way you want:
final JFrame frame = new JFrame("Nested Layout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel gui = new JPanel(new BorderLayout(5,5));
gui.setBorder( new TitledBorder("BorderLayout(5,5)") );
JPanel container = new JPanel();
container.setLayout(new GridLayout(2,1)); // This is the line that I have added.
JButton button = new JButton("Button");
JButton button1 = new JButton("Button1");
container.add(button, BorderLayout.NORTH);
container.add(button1, BorderLayout.SOUTH);
gui.add(container);
frame.setContentPane(gui);
frame.pack();
frame.setLocationRelativeTo(null);
try {
// 1.6+
frame.setLocationByPlatform(true);
frame.setMinimumSize(frame.getSize());
} catch(Throwable ignoreAndContinue) {
}
frame.setVisible(true);
If you want to add more buttons, you can edit that line. The first Parameter of the constructor method of GridLayout is the number of vertical columns, and the second is the number of horizontal columns.

Categories