How do I display a JLabel over a JButton - java

I can see the button and when I get rid of the button, I can see the JLabelI'm using the Eclipse IDE and I'm trying to have a JLabel display over a JButton.
I already tried creating my JLabel above my JButton, still doesn't work

Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Laying Out Components Within a Container section.
Since you posted an image of your code fragment, I created the following GUI.
I should post an image of the code, but I'm going to be nice and post the complete runnable code.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JLabelOverJButtonGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JLabelOverJButtonGUI());
}
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
JLabel label = new JLabel("Label");
panel.add(label);
JButton button = new JButton("Button");
panel.add(button);
return panel;
}
}

Related

JLabel showing ellipses when is has space to show full label

JLabel showing ellipses when is has space to show full label
my code:
​import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.basic.BasicLookAndFeel;
import com.bulenkov.darcula.DarculaLaf;
public class GUI implements ActionListener {
private int count = 0;
private JLabel label;
private JFrame frame;
private JPanel panel;
public GUI() throws UnsupportedLookAndFeelException {
BasicLookAndFeel darcula = new DarculaLaf();
UIManager.setLookAndFeel(darcula);
frame = new JFrame();
JButton button = new JButton("Click Me");
button.addActionListener(this);
label = new JLabel("Number of clicks: 0");
panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(20, 100, -85, 100));
panel.setLayout(new GridLayout(5, 1));
panel.add(button);
panel.add(label);
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
///frame.setTitle("Cool GUI");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws UnsupportedLookAndFeelException {
new GUI();
}
#Override
public void actionPerformed(ActionEvent e) {
count++;
label.setText("Number of clicks: " + count);
}
}
Oracle has a good tutorial that teaches the basics of Swing, Creating a GUI With JFC/Swing. Skip the Netbeans section.
I created the following GUI.
Here's what I did.
I started my Swing GUI with a call to the SwingUtilities invokeLater method. This method ensures that all of the Swing components are created and executed on the Event Dispatch Thread.
I separated the code to construct the JFrame from the code to construct the JPanel. The JFrame methods have to be called in a certain order. This is the order I use for most of my Swing applications.
I construct the JPanel in Swing component order. I keep all methods having to do with a particular Swing component together.
I put the "Number of clicks:" text in one place.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BasicGUI implements ActionListener, Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new BasicGUI());
}
private int count;
private JLabel label;
public BasicGUI() {
this.count = 0;
}
#Override
public void run() {
JFrame frame = new JFrame("Cool GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JButton button = new JButton("Click Me");
button.addActionListener(this);
panel.add(button);
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
updateLabel(0);
panel.add(label);
return panel;
}
public void updateLabel(int count) {
label.setText("Number of clicks: " + count);
}
#Override
public void actionPerformed(ActionEvent event) {
updateLabel(++count);
}
}
BasicLookAndFeel darcula = new DarculaLaf();
UIManager.setLookAndFeel(darcula);
Don't use a 3rd party LAF when asking a basic question.
We don't know if the problem is related to the LAF or the standard classes of the JDK.
JLabel showing ellipses when is has space to show full label
Well actually it doesn't have space because you use the pack() method and all components are displayed at their preferred size based on the preferred size of the components and of the Borders applied to the components.
When I run your code (using the default LAF) the text displays correctly at startup.
This is because the width of the panel is controlled by the preferred width of the JButton since it is the larger component.
However, if I change the text of the button to be:
label.setText("Number of clicks made: " + count);
now the width of the panel is controlled by the preferred width of the label since it is greater than that of the button.
Again, at startup the text displays properly
However, if you click the button 10 times then the "count" changes from a one digit number to a two digit number which increases the preferred size of the label causing the "..." to appear.
A simple solution is to use:
count++;
label.setText("Number of clicks made: " + count);
frame.pack();
Now the frame will be resized to accommodate the newly calculated preferred size of the label.
panel.setLayout(new GridLayout(5, 1));
Also, don't hardcode the "rows" of the GridLayout. The above code reserves space for 5 components even though you only have 2.
Instead use:
panel.setLayout(new GridLayout(0, 1));
which indicates a single column with any number of components.
Then you can use the EmptyBorder properly to give it symmetry on all sides:
//panel.setBorder(BorderFactory.createEmptyBorder(20, 100, -85, 100));
panel.setBorder(BorderFactory.createEmptyBorder(20, 100, 20, 100));
I think GridBagLayout asks your JLabel about the required size when the UI is initialized. Then the JLabel is assigned the requested size.
During runtime the String that needs to be displayed by the JLabel changes, and actually it gets longer. But no re-layout is happening, therefore the JLabel is not allowed to use more space - even if on the screen it seems there is plenty of space.
The solution is to either tell GridBagLayout to reserve plenty of space for that component, or allow for dynamic scaling. Check the GridBagLayout tutorial for details.

When I click my JButton, the JLabel doesn't show on the window,

I tried to make a JButton that would put a JLabel in the window, but when I click the button, it doesn't seem to put the JLabel in the window. The button seems to work when I use it for the console, but not for putting the JLabel in the window. Why is this, and what should I do?
Here's my code:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AnimaleseTranslator implements ActionListener {
private static JPanel panel;
private static JLabel label;
public AnimaleseTranslator() {
JFrame frame = new JFrame();
panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(220, 391, 220, 391));
panel.setLayout(new GridLayout(0, 1));
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null); // centers the JFrame
frame.setTitle("Animalese Translator");
frame.setVisible(true);
JButton button = new JButton("Click me!");
button.setBounds(100, 100, 98, 55);
button.addActionListener(this);
panel.add(button);
label = new JLabel("lkdsajflksdjlaskdjf");
label.setBounds(200, 200, 50, 50);
}
public static void main(String[] args) {
new AnimaleseTranslator();
}
#Override
public void actionPerformed(ActionEvent e) {
panel.add(label);
}
}
but when I click the button, it doesn't seem to put the JLabel in the window.
The setBounds(...) statement does nothing. Swing uses layout managers by default and the layout manager will set the size/location of each component. So get rid of the setBounds() statement because it is confusing.
Components need to be added to the frame BEFORE the frame is made visible. The pack() or setVisible() statement will then invoke the layout manager.
After you add a component to panel on a visible frame you need to invoke panel.revalidate() to invoke the layout manager. So you need to add the revalidate() in the ActionListener.
Get rid of the setBorder(...) statement until you better understand what it does. The problem with your current code is the border is too big, so there is no room for the button and label to display properly.

No error shown but JButton and Label can't be seen

I'm new to coding and I am facing this problem where it doesn't show the JButton and JLabel that i added in the GUI. What have i done wrong and how do i fix it?
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
public class MainMenu {
public static void main (String []args) {
JFrame frame = new JFrame ("Main Menu");
frame.setSize(480,720);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,2,5,5));
JButton meals = new JButton ("Meals");
JLabel label = new JLabel ("Welcome back!");
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
panel.add(meals);
panel.add(label);
frame.add(panel);
}
}
That happens because you frame.setVisible(true); before adding any components to it. You should add the components to the frame first, and then, use the setVisible method.
panel.add(meals);
panel.add(label);
frame.add(panel);
frame.setVisible(true); //visible after components added
Fixed version of your code below. Hopefully it works. I tested it in my IDE.
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
public class MainMenu {
public static void main(String[] args) {
JFrame frame = new JFrame("Main Menu");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2, 5, 5));
JButton meals = new JButton("Meals");
JLabel label = new JLabel("Welcome back!");
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
panel.add(meals);
panel.add(label);
frame.add(panel);
frame.setSize(480, 720);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

swing and GUI components not appearing

I'm a complete noobie with swing. I'm trying to set a few JPanels and TextAreas to show up but after spending 2 days reading the APIs and trying to add panels to frames and textareas to panels and nothing is showing up.. I'm utterly confused. If anyone could explain how is the best way to do this I would be very grateful
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(new FlowLayout()); // J FRAME
JPanel panel = new JPanel(); // first panel on the left
panel.setLayout(new BoxLayout(panel, 1));
// frame.getContentPane().setBackground(Color.red);
frame.add(panel);
JLabel surname = new JLabel();
JLabel initial = new JLabel();
JLabel ext = new JLabel();
surname.setOpaque(true);
initial.setOpaque(true);
ext.setOpaque(true);
frame.add(surname);
panel.add(initial);
panel.add(ext);
JTextArea table = new JTextArea();
table.setEditable(false);
panel.add(table);
table.setVisible(true);
You're adding stuff to the JFrame after it's already visible. If you do that, you need to revalidate your JFrame so it knows to redo its layout.
You could also just wait to show your JFrame until after you've added everything.
Edit: Here is an example program that shows what I'm talking about. Try running this, then take out the call to revalidate() to see the difference.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Test {
public static void main(String[] args) {
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JButton show = new JButton("Show");
show.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent showE) {
frame.add(new JLabel("Test"), BorderLayout.SOUTH);
frame.revalidate(); //tell the JFrame to redo its layout!
}
});
frame.add(show);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
You are adding an empty elements like:
JLabel surname = new JLabel();
Your elements is already added but have nothing to be display.
Try :
JLabel surname = new JLabel("UserName");
JLabel initial = new JLabel("Iinitial");
JLabel ext = new JLabel("Ext");
JTextArea table = new JTextArea(10, 5);

Toggling/navigating jpanels in java swings

> I have a jframe defined in a package 'abc'. this jframe acts as a main class too.
> the same package 'abc' also contain 4 jpanels(panel1,panel2,panel3,panel4) defined in different java classes.
how one should call/show these different jpanels from main jframe class at user clicks on different buttons ?
what if I've got 40-50 such jpanels.what would be the most efficient way to toggle these panels from the main class ?
This is a very simple example that uses next() and one button to change panels.
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.border.Border;
public class TestCards extends JFrame {
private final CardLayout cl = new CardLayout();
private final JPanel cards = new JPanel(cl);
private final Border border = BorderFactory.createEmptyBorder(60, 60, 60, 60);
public TestCards() {
JPanel contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
JPanel panel1 = new JPanel(new GridBagLayout());
panel1.setBorder(border);
panel1.setBackground(Color.RED);
panel1.add(new JLabel("Card 1"));
cards.add(panel1, "First Panel");
JPanel panel2 = new JPanel(new GridBagLayout());
panel2.setBorder(border);
panel2.setBackground(Color.GREEN);
panel2.add(new JLabel("Card 2"));
cards.add(panel2, "Second Panel");
JPanel panel3 = new JPanel(new GridBagLayout());
panel3.setBorder(border);
panel3.setBackground(Color.BLUE);
panel3.add(new JLabel("Card 3"));
cards.add(panel3, "Third Panel");
JButton controlButton = new JButton("Switch");
controlButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cl.next(cards);
}
});
JPanel controlPanel = new JPanel();
controlPanel.setBackground(Color.LIGHT_GRAY);
controlPanel.add(controlButton);
contentPane.add(cards);
contentPane.add(controlPanel);
cl.show(cards, "First Panel");
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
TestCards frame = new TestCards();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
An alternative (among many) would be to use 3 buttons where each one shows a specific panel (by using show instead of next).
See this for more info.
CardLayout's previous and next methods can be used to navigate forward & back respectively through the card components. To make it easier to navigate the components non-consecutively, you could place the card names in a String array:
private static final String[] CARD_NAMES = { "name_2996062106101", ... };
Then, to display a specific cardIndex, you could simply use:
CardLayout layout = (CardLayout) contentPane.getLayout();
layout.show(contentPane, CARD_NAMES[cardIndex]);
For more see How to Use CardLayout.

Categories