Java GUI won't display JLabel - java

I would like to create a simple GUI in Java. I know the basics of creating JLabel, etc. However, I cannot find why my JLabel is not displayed on the screen. Here is my code:
package test;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
public class A1Panel extends JPanel implements ActionListener {
JLabel firstInt;
public void init() {
makeComponents();
makeLayout();
}
private void makeComponents() {
firstInt = new JLabel("First argument");
firstInt.setFont(new Font("Helvetica", Font.BOLD, 16));
firstInt.setBackground(Color.lightGray);
firstInt.setVisible(true);
firstInt.setHorizontalAlignment(SwingConstants.CENTER);
}
private void makeLayout() {
add(firstInt);
}
public void actionPerformed(ActionEvent e) {
}
}
I then add my JPanel to my JFrame using a different class called GUI:
import test.A1Panel;
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame("Testing GUI");
frame.setLayout( new GridLayout(1,3));
JPanel panel = new A1Panel();
panel.setBorder( BorderFactory.createRaisedBevelBorder() );
frame.add( panel);
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
}
}
When I hit compile, what I get is a simple frame with three empty panels. I do not understand why my JLabel is not in the first panel since I have added it to my frame. Am I missing something?

The frame is not empty, the panel is. Nowhere in your code do I see a call to the methods init() or makeComponents(). In fact, I would turn your init() method into a constructor, like so:
public A1Panel() {
makeComponents();
makeLayout();
}
Another alternative to this would be to call panel.init() after declaring JPanel panel = new A1Panel()

After you instance A1Panel, you haven't called A1Panel.init()
I would suggest removing init() and adding all the code to the constructor of A1Panel. If, however, you wanted to keep the init() function, you would want to call it after JPanel panel = new A1Panel()

The code to add the label was not actually called in the main, was it? So look carefully, when is init actually called?
Look at the
private void makeLayout()
method.

If I replace public void init() by A1Panel(), it does the job. Thank you for your help.

Related

JButton and JTextField

What's wrong? ImageIcon and the frame's size are working properly.
But the JTextField and the JButton aren't.
I need the solution.
import javax.swing.*;
import javax.swing.ImageIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Frame {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("Alkalmazás");
frame.setVisible(true);
frame.setSize(500,500);
frame.setResizable(false);
JTextField field = new JTextField();
field.setBounds(40,250, 300,35);
JButton button = new JButton(new ImageIcon("table.png"));
button.setBounds(40,400, 250,25);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tf.setText(""something);
}
});
frame.add(field);
frame.add(button);
}
}
You didn't mention what's "not working properly", but there are a few errors with your code:
Don't call your class Frame, it may confuse you or others about java.awt.Frame, something that may work would be MyFrame
Right now all your class is inside the main method and it's not placed inside the Event Dispatch Thread (EDT), to fix this, create an instance of your class and call a method createAndShowGUI (or whatever you want to name it) inside SwingUtilities.invokeLater()
For Example:
public static void main(String args[]) {
SwingUtilities.invokeLater(new MyFrame()::createAndShowGUI)
}
Or if using Java 7 or lower, use the code inside this answer in point #2.
setVisible(true) should be the last line in your code, otherwise you may find some visual glitches that may be resolved until you move your mouse above your window or something that triggers the call to repaint() of your components.
Instead of calling setSize(...) directly, you should override getPreferredSize(...) of your JPanel and then call pack() on your JFrame, see this question and the answers in it: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
You're adding 2 components to the CENTER of BorderLayout, which is a JFrame's default layout manager, there are other layout managers and you can combine them to make complex GUI's.
setBounds(...) might mean that you're using null-layout, which might seem like the easiest way to create complex layouts, however you will find yourself in situations like this one if you take that approach, it's better to let Swing do the calculations for you while you use layout managers. For more, read: Why is it frowned upon to use a null layout in Swing?
With all the above tips now in mind, you may have a code similar to this one:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class MyFrame {
private JFrame frame;
private JPanel pane;
private JTextField field;
private JButton button;
public static void main(String[] args) {
SwingUtilities.invokeLater(new MyFrame()::createAndShowGUI);
}
private void createAndShowGUI() {
frame = new JFrame("Alkalmazás");
pane = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
field = new JTextField(10);
button = new JButton("Click me");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
field.setText("something");
}
});
pane.add(field);
pane.add(button);
frame.add(pane);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Now you have an output similar to this one:
What about you want the JTextField to have a more "normal" size? Like this one:
You'll have to embed field inside another JPanel (with FlowLayout (the default layout manager of JPanel)), and then add that second JPanel to pane, I'm not writing the code for that as I'm leaving that as an exercise to you so you learn how to use multiple layout managers

Is it possible to create a panel with a class on the left and right side?

I have been practicing my code with Java Swing and have gotten decent on controlling where to place some items, such as labels and or buttons, but I was wondering if you can do the same with classes? I have just a simple class with enough code to put a button in it and that's it, that I am trying to create an instance of the class and then control for to put on the left and right side but when I do, all it does is create two separate windows with the button in the middle and that's it. Am I doing something wrong, or can you not do classes the same way?
The code:
import java.awt.Color;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Fun extends JFrame
{
private final int WIDTH = 500;
private final int HEIGHT = 400;
public Fun()
{
setTitle("Fun Management");
setSize(WIDTH, HEIGHT);
BuildPanel west = new BuildPanel(); /// BuildPanel is the name of the class that has just a button in it.
BuildPanel east = new BuildPanel(); ///
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(west, BorderLayout.WEST); /// I am doing the same thing with the instances as I would with buttons or labesl
add(east, BorderLayout.EAST);
setVisible(true);
}
public static void main(String[] args)
{
new Fun();
}
}
I took your code and created the following GUI.
Oracle has a rad tutorial, Creating a GUI With Swing, that will show you how to create Swing GUIs. Skip the Netbeans section.
Always start your Swing application with a call to the SwingUtilities invokeLater method. This method ensures that your Swing components are created and executed on the Event Dispatch Thread.
Use Swing components. Don't extend a Swing component unless you want to override one or more of the component methods.
The JFrame methods must be called in a specific order. This is the order I recommend for most Swing applications. Use the JFrame pack method and let the components size the JFrame.
I created a BuildPanel class to build a JPanel. There are good reasons to do this, but be careful. You have to manage each instance of the class you create. As an example, what if you want the text of the two buttons to be different? What if you want to assign two different ActionListener classes, one to each button?
Here's the complete runnable code. I made the BuildPanel class an inner class so I can post the code as one block.
import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TwoPanelExample implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new TwoPanelExample());
}
#Override
public void run() {
JFrame frame = new JFrame("Fun Management");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BuildPanel west = new BuildPanel();
BuildPanel east = new BuildPanel();
frame.add(west.getPanel(), BorderLayout.WEST);
frame.add(east.getPanel(), BorderLayout.EAST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class BuildPanel {
private final JPanel panel;
public BuildPanel() {
this.panel = createMainPanel();
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(5, 30, 5, 30));
JButton button = new JButton("Click Me");
panel.add(button);
return panel;
}
public JPanel getPanel() {
return panel;
}
}
}

JTextField.getText() inside of actionListener fails to return the proper String

I have run into the issue of not being able to collect the real text from my JTextField when calling getText(). I have provided a simplified version of the code I was running that includes only the aspects of the program to where it will reproduce the issue. I am attempting to collect the text from the JTextField upon the clicking of the button b.
The correct value returned from getText() should be what ever was input, but instead here it simply returns an empty String. In testing I have found that initializing the TJextField with a String will have it return that String no matter what, even if it is changed before pressing the button. and if one uses setText() inside of init() for example, it will continue to return an empty String.
public class TopClass {
public static void main(String[] args){
BottomClass bottom = new BottomClass();
bottom.init();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BottomClass implements ActionListener{
JFrame frame = new JFrame();
JTextField tf = new JTextField();
JButton b = new JButton("BUTTON");
public void init(){
BottomClass bc = new BottomClass();
b.addActionListener((ActionListener) bc);
frame.add(tf, BorderLayout.NORTH);
frame.add(b, BorderLayout.SOUTH);
frame.setSize(100,100);
frame.show();
}
public void actionPerformed(ActionEvent e) {
System.out.println("TEXT: "+tf.getText());
}
}
Several things aren't clean at all in this code, so I just rewrote most of BottomClass.
You can do it by implementing ActionListener, but BottomClass is more than just an EventListener, so (in the name of realistic responsibility) I just added a new instance of ActionListener to the component that needs it (JButton)
You create an instance bc of BottomClass inside the method init() IN BottomClass. This makes no sense at all and was simply deleted.
You initialize your components at the wrong point. They should either be initialized in the constructor, or inside your nice and fitting init() method. I'm 99% sure that the placement of your initializations is what caused your trouble.
I'm not sure how much of an error this is, but when adding your components you specify BorderLayout constraints despite never defining BorderLayout as the LayoutManager to use. I added the setLayout(new BorderLayout()) call.
It's usually good form to have a constructor, especially if you have a different class calling it. Even if it's empty, a written empty constructor is more easily readable and understandable than an invisible one.
All that said, here's a working version of BottomClass, TopClass doesn't need any adjustments:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BottomClass
{
JFrame frame;
JTextField tf;
JButton b;
public BottomClass()
{
// Empty constructor
}
public void init()
{
frame = new JFrame();
frame.setLayout(new BorderLayout());
tf = new JTextField();
b = new JButton("Button");
b.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
System.out.println("TEXT: " + tf.getText());
}
});
frame.add(tf, BorderLayout.NORTH);
frame.add(b, BorderLayout.SOUTH);
frame.setSize(100, 100);
frame.setVisible(true);
}
}

Swing code compilation error "missing ;"

How do I solve this compilation error? Note that I'm new to Swing.
http://prntscr.com/bpz2ve
package gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class GUI extends Frame {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello World - YaBoiAce");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 300);
// Layout //
frame.setLayout(new BorderLayout());
// Swing Component //
final JTextArea textarea = new JTextArea();
JButton jbutton = new JButton("Click me");
// Add Component to content pane
Container c = frame.getContentPane();
c.add(textarea,BorderLayout.CENTER);
c.add(jbutton, BorderLayout.SOUTH);
// Action Listener
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textarea.append("Hello");
} // Eclipse says 'missing ;' on this line.
}
private static void setDefaultCloseOperation(int exitOnClose) {
}
}
Eclipse says "Missing ;" But when I put that in, It highlights the ; saying "Missing ;" again. It keeps on doing that. Any help?
It is on the line marked with:
// Eclipse says 'missing ;' on this line.
There are many problems in your code:
As stated in the
comments
by #HovercraftFullOfEels:
You're not matching closing parenthesis on your addActionListener method too. Again good code formatting will help you see this.
// Action Listener
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textarea.append("Hello");
} // Eclipse says 'missing ;' on this line.
}); //HERE YOU NEED TO ADD: );
You're extending Frame (Maybe you were trying to extend JFrame)
and creating a JFrame object, choose which one you want to use
(Recommended to create the object instead of extending, because if
you extend a JFrame your class is a JFrame and cannot be
included somewhere else and you're not changing it's functionallity
either so, no need to extend).
You're creating a private static method
private static void setDefaultCloseOperation(int exitOnClose) {}
That method should be public and belongs to JFrame class, I guess your IDE wrote that when you extended Frame instead of JFrame.
Frame belongs to java.awt while JFrame belongs to javax.swing so, they are not the same.
You're creating your windows and every component inside your main
method instead of the constructor
You're adding your components to a Container but never add that container to your JFrame, so you need to call
frame.setContentPane(c);
So your code should look like this:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class GUI {
JFrame frame;
public GUI() {
frame = new JFrame("Hello World - YaBoiAce");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 300);
// Layout //
frame.setLayout(new BorderLayout());
// Swing Component //
final JTextArea textarea = new JTextArea();
JButton jbutton = new JButton("Click me");
frame.add(textarea,BorderLayout.CENTER);
frame.add(jbutton, BorderLayout.SOUTH);
// Add Component to content pane
Container c = frame.getContentPane();
c.add(textarea,BorderLayout.CENTER);
c.add(jbutton, BorderLayout.SOUTH);
frame.setContentPane(c);
// Action Listener
jbutton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textarea.append("Hello");
} // Eclipse says 'missing ;' on this line.
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new GUI());
}
}

I'm attempting to create a small GUI application, but the contents of the JFrame are not showing on screen. How can I fix my code?

As of late I've been developing a (very) small GUI application in Java. I'm extremely new to Swing and Java in general, but up until now I have been able to get everything to work the way I want it to. However, after cleaning up my code, when I run the program nothing but the border of the window appears. What am I doing wrong and how can I fix my code? Thanks ahead of time!
For the sake of saving space I've made Pastebin links to all of my classes (besides Main).
Main Class
package me.n3rdfall.ezserver.main;
public class Main {
public static GUI g = new GUI();
public static void main(String[] args) {
g.showWindow(800, 500);
}
}
GUI Class
http://pastebin.com/gDMipdp1
ButtonListener Class
http://pastebin.com/4XXm70AD
EDIT: It appears that calling removeAll() directly on 'frame' actually removed essential things other than what I had added. By calling removeAll() on getContentPane(), the issue was resolved.
Quick hack: Remove the removeAll() functions.
public void homePage() {
// frame.removeAll();
// mainpanel.removeAll();
// topbar.removeAll();
I'm not sure what you're trying to achieve, but that will at least show some items. If I were you I would rebuild this GUI by extending JFrame. It will make your code a little easier to read.
I also think what you are trying to achieve with the buttons is to switch layouts, you can do this in an easier way by using CardLayout
Example (has nothing to do with your code, but to demonstrate):
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame implements ActionListener {
private JButton leftButton;
private JButton rightButton;
private CardLayout cardLayout = new CardLayout();
JPanel cards = new JPanel(cardLayout);
final static String LEFTPANEL = "LEFTPANEL";
final static String RIGHTPANEL = "RIGHTPANEL";
JPanel card1;
JPanel card2;
public Example() {
JPanel topPanel = new JPanel();
addButtons(topPanel);
add(topPanel, BorderLayout.NORTH);
add(cards, BorderLayout.CENTER);
//Initiates the card panels
initCards();
setTitle("My Window");
setSize(300, 300);
setLocationRelativeTo(null);
setVisible(true);
}
private void initCards() {
card1 = new JPanel();
card2 = new JPanel();
card1.setBackground(Color.black);
card2.setBackground(Color.red);
cards.add(card1, LEFTPANEL);
cards.add(card2, RIGHTPANEL);
}
private void addButtons(Container con) {
leftButton = new JButton("Left Button");
leftButton.addActionListener(this);
rightButton = new JButton("Right Button");
rightButton.addActionListener(this);
con.add(leftButton, BorderLayout.WEST);
con.add(rightButton, BorderLayout.EAST);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(leftButton)) {
//Change cardlayout
cardLayout.show(cards, LEFTPANEL);
} else if(e.getSource().equals(rightButton)) {
//Change cardlayout
cardLayout.show(cards, RIGHTPANEL);
}
}
public static void main(String[] args) {
new Example();
}
}

Categories