Unable to put buttons on frame? - java

I'm using currently Intellij to create a GUI with 3 buttons on the top of the main frame. I'm fairly new to GUI's and still learning as I go. When I try to run the code I get an error telling me that I cannot have the main method as static but if I remove the static I get an error saying I need it to be static. Is there a way to easily avoid this?
package CA3;
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;
public class Main extends JFrame{
public static void main(String[] args) {
// Attach window listener
addWindowListener(new WindowCloser()); // Just in-case it's needed
// Adding first customer panel
JPanel pCustomerL = new JPanel();
pCustomerL.setBounds(0,0,750,750);
pCustomerL.setBackground(Color.BLUE);
// Adding second customer panel
JPanel pCustomerR = new JPanel();
pCustomerR.setBounds(750,0,750,750);
pCustomerR.setBackground(Color.BLACK);
// Adding first invoice panel
JPanel pInvoiceL = new JPanel();
pInvoiceL.setBounds(0,0,750,750);
pInvoiceL.setBackground(Color.BLUE);
// Adding second product panel
JPanel pInvoiceR = new JPanel();
pInvoiceR.setBounds(750,0,750,750);
pInvoiceR.setBackground(Color.BLACK);
// Button Listener
ButtonListener listener = new ButtonListener();
// Adding "Customer" Button
JButton b = new JButton("Customer");
b.addActionListener(listener);
add(b);
b.setBounds(1300,10,150,35);
// Adding "Product" Button
b = new JButton("Product");
b.addActionListener(listener);
add(b);
b.setBounds(1150,10,150,35);
// Adding "Invoice" Button
b = new JButton("Invoice");
b.addActionListener(listener);
add(b);
b.setBounds(1000,10,150,35);
// Adding first product panel
JPanel pProductL = new JPanel();
pProductL.setBounds(0,0,750,750);
//pProductL.setBackground(Color.BLUE);
// Adding second product panel
JPanel pProductR = new JPanel();
pProductR.setBounds(750,0,750,750);
//pProductR.setBackground(Color.BLACK);
// Frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setSize(1500,750);
frame.setVisible(true);
// Add panels
frame.add(pCustomerL);
frame.add(pCustomerR);
frame.add(pProductL);
frame.add(pProductR);
frame.add(pInvoiceL);
frame.add(pInvoiceR);
// Customer Panel Settings
pCustomerL.setVisible(true);
pCustomerR.setVisible(true);
// Product Settings
pProductL.setVisible(false);
pProductR.setVisible(false);
// Invoice settings
pInvoiceL.setVisible(false);
pInvoiceR.setVisible(false);
}
// Listener for buttons
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
String buttonLabel = evt.getActionCommand();
}
}
// Listener for window
class WindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent evt) { System.exit(0);}
}
}

You have to move your code inside the main to another method not-static or you can put it on a Constructor. The errors are because you are using normal methods like addWindowsListener which inherits from JFrame. And you also have to remove:
JFrame frame = new JFrame();
That's not necessary because your class already inherits from JFrame so your code must be like this:
public class Main extends JFrame
{
public Main(){
// Attach window listener
addWindowListener(new WindowCloser()); // Just in-case it's needed
// Adding first customer panel
JPanel pCustomerL = new JPanel();
pCustomerL.setBounds(0,0,750,750);
pCustomerL.setBackground(Color.BLUE);
// Adding second customer panel
JPanel pCustomerR = new JPanel();
pCustomerR.setBounds(750,0,750,750);
pCustomerR.setBackground(Color.BLACK);
// Adding first invoice panel
JPanel pInvoiceL = new JPanel();
pInvoiceL.setBounds(0,0,750,750);
pInvoiceL.setBackground(Color.BLUE);
// Adding second product panel
JPanel pInvoiceR = new JPanel();
pInvoiceR.setBounds(750,0,750,750);
pInvoiceR.setBackground(Color.BLACK);
// Button Listener
ButtonListener listener = new ButtonListener();
// Adding "Customer" Button
JButton b = new JButton("Customer");
b.addActionListener(listener);
add(b);
b.setBounds(1300,10,150,35);
// Adding "Product" Button
b = new JButton("Product");
b.addActionListener(listener);
add(b);
b.setBounds(1150,10,150,35);
// Adding "Invoice" Button
b = new JButton("Invoice");
b.addActionListener(listener);
add(b);
b.setBounds(1000,10,150,35);
// Adding first product panel
JPanel pProductL = new JPanel();
pProductL.setBounds(0,0,750,750);
//pProductL.setBackground(Color.BLUE);
// Adding second product panel
JPanel pProductR = new JPanel();
pProductR.setBounds(750,0,750,750);
//pProductR.setBackground(Color.BLACK);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setSize(1500,750);
this.add(pCustomerL);
this.add(pCustomerR);
this.add(pProductL);
this.add(pProductR);
this.add(pInvoiceL);
this.add(pInvoiceR);
// Customer Panel Settings
pCustomerL.setVisible(true);
pCustomerR.setVisible(true);
// Product Settings
pProductL.setVisible(false);
pProductR.setVisible(false);
// Invoice settings
pInvoiceL.setVisible(false);
pInvoiceR.setVisible(false);
this.setVisible(true);
}
// Listener for buttons
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
String buttonLabel = evt.getActionCommand();
}
}
// Listener for window
class WindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent evt) { System.exit(0);}
}
public static void main(String[] args) {
new Main();
}
}

Related

Java Swing - Why is my first window not disposing/closing?

So I'm creating an application. I want main to initialize a login window, which I've done. And for now I want the login window to close whenever I click on the button, and when it closes, a new window (called MainWindow) opens with different buttons/info/text.
All these classes are separate, but in the same package.
The problem is: The main window opens when I click login, however the login window doesn't terminate/close.
My main method, from which I call the login window:
import javax.swing.*;
public class Main {
// Display Login Window
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new LoginWindow();
LoginWindow.createAndShowLoginGUI();
});
}
}
My login window class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LoginWindow extends JFrame implements ActionListener {
public void prepareLoginGUI() {
// Frame with GridBagLayout
JFrame loginFrame = new JFrame("Login Window");
loginFrame.setSize(1200, 800);
loginFrame.setLayout(new GridBagLayout());
// Button for logging in, with respective GridBagConstraint
// setFocusable is set to false to take out the border around the text
JButton loginButton = new JButton("Login");
loginButton.addActionListener(this::actionPerformed);
loginButton.setActionCommand("Open");
GridBagConstraints lButtonC = new GridBagConstraints();
loginButton.setFocusable(false);
// Username text-field and JLabel with respective GridBagConstraints
JTextField tfUsername = new JTextField(15);
GridBagConstraints tfUserC = new GridBagConstraints();
JLabel txtUser = new JLabel("Username: ");
GridBagConstraints txtUserC = new GridBagConstraints();
// Password text-field and JLabel with respective GridBagConstraints
JPasswordField tfPassword = new JPasswordField(15);
GridBagConstraints tfPassC = new GridBagConstraints();
JLabel txtPassword = new JLabel("Password: ");
GridBagConstraints txtPassC = new GridBagConstraints();
// Add all components to the JFrame
// Making sure to add the text before the text-fields
loginFrame.add(txtUser, txtUserC);
loginFrame.add(tfUsername, tfUserC);
loginFrame.add(txtPassword, txtPassC);
loginFrame.add(tfPassword, tfPassC);
loginFrame.add(loginButton, lButtonC);
// Show and set close parameters
loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loginFrame.setVisible(true);
}
// Instructions for when the login button is clicked
// Close this window, if button == open, which it does
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals("Open")) {
this.dispose();
this.setVisible(false);
new MainWindow();
MainWindow.createAndShowMainWGUI();
}
}
// Callable from Main class
public static void createAndShowLoginGUI() {
LoginWindow loginW = new LoginWindow();
loginW.prepareLoginGUI();
}
}
My Main Window Class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MainWindow extends JFrame implements ActionListener {
public void prepareMainWGUI(){
// Frame with GridBagLayout
JFrame loginFrame = new JFrame("Main Window");
loginFrame.setSize(1200, 800);
loginFrame.setLayout(new GridBagLayout());
// Username text-field and JLabel with respective GridBagConstraints
JLabel txtUser = new JLabel("It worked!");
GridBagConstraints txtUserC = new GridBagConstraints();
loginFrame.add(txtUser, txtUserC);
loginFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
loginFrame.setVisible(true);
}
// Callable from Main class
public static void createAndShowMainWGUI() {
MainWindow mainWind = new MainWindow();
mainWind.prepareMainWGUI();
}
}
If you use this code, when the main window opens, the login window will be right behind it.
You can use when pressing button
System.exit(0);
This will terminate your application. To close one window use(if you have open multiple windows) without affecting to others,
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
Then, to open new one,
new frameName().setvisible(true);
Example:
JButton closeButton = new JButton("Close");
closeButton .addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
this.dispose();//current(close only this) frame
new frameName().setvisible(true);
}
});
Take a look at this question.
UPDATE:
In below line you have extends JFrame but you didnot use it.
public class LoginWindow extends JFrame implements ActionListener {
Rather than that you have create new object from JFrame
JFrame loginFrame = new JFrame("Login Window");
All the component you are adding to the loginFrame. But when actionPerformed trying to this.dispose(), since you are not using extended JFrame nothing will happen.
Solution:
Declare your JFrame as a instance variable:
public class LoginWindow implements ActionListener {
JFrame loginFrame;
public void prepareLoginGUI() {
Then change,
this.dispose();
To:
loginFrame.dispose();
In this this.dispose(); call to the extended JFrame, no effect for your JFrame object(loginForm).
And one last thing, make sure to remove extends JFrame. Because you are not doing anything with extended JFrame. Read this post about extended JFrame.

Dynamic JPanels error

I hava CardLayout and want to have changing panels on it. For that I wrote my JFrame Class:
public class GUI_NewList extends javax.swing.JFrame {
CardLayout layout = new CardLayout();
public GUI_NewList() {
initComponents();
this.setLayout(layout);
JPanel paChoose = new Choose();
layout.addLayoutComponent(paChoose, "1");
layout.show(paChoose, "1");
}
The class Choose:
public class Choose extends JPanel {
public Choose() {
setLayout(new GridLayout(3, 1));
JButton btnPractice = new JButton("Practice");
add(btnPractice);
JButton btnNewList = new JButton("Create a new List");
add(btnNewList);
JButton btnEditList = new JButton("Edit a List");
add(btnEditList);
}
}
If I run this I get an error:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: wrong parent for CardLayout
Could you please tell me what I have done wrong?
Here is an MCVE that fixes the problem. See code comments for details of the problem(s).
import java.awt.*;
import javax.swing.*;
public class GUI_NewList extends JFrame {
CardLayout layout = new CardLayout();
public GUI_NewList() {
this.setLayout(layout);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel paChoose = new Choose();
// this only adds it to the layout, not the container.
layout.addLayoutComponent(paChoose, "1");
// this adds it to the container (the content pane)
add(paChoose);
// the container of interest is the content pane.
layout.show(this.getContentPane(), "1");
pack();
setVisible(true);
}
public static void main(String[] args) {
Runnable r = () -> {
new GUI_NewList();
};
SwingUtilities.invokeLater(r);
}
}
class Choose extends JPanel {
public Choose() {
setLayout(new GridLayout(3, 1));
JButton btnPractice = new JButton("Practice");
add(btnPractice);
JButton btnNewList = new JButton("Create a new List");
add(btnNewList);
JButton btnEditList = new JButton("Edit a List");
add(btnEditList);
}
}
Note: There is no good case here for extending either JFrame or JPanel.

Why launching does it random?

When i run this program sometimes shows me all buttons, but sometimes only 2 or 3 or 4 or 5 or even just 1.. why is that??
I really do not get it. There should always be 6 buttons, but it doesnt show them. Is there any logical reason?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class testnet
{
public static void main (String[] args)
{
JFrame frame = new JFrame("Knjigarna");
frame.setVisible(true);
frame.setSize(800,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JButton button1 = new JButton("Prikazi vse");
panel.add(button1);
button1.addActionListener (new Action1());
JButton button2 = new JButton("Prikazi knjigo");
panel.add(button2);
button2.addActionListener (new Action2());
JButton button3 = new JButton("Dodaj knjigo");
panel.add(button3);
button3.addActionListener (new Action3());
JButton button4 = new JButton("Brisi knjigo");
panel.add(button4);
button4.addActionListener (new Action4());
JButton button5 = new JButton("Uredi knjigo");
panel.add(button5);
button5.addActionListener (new Action5());
JButton button6 = new JButton("Izhod");
panel.add(button6);
button6.addActionListener (new Action6());
}
static class Action1 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
JFrame frame2 = new JFrame("Pikaz vseh knjig");
frame2.setVisible(true);
frame2.setSize(500,800);
JLabel label = new JLabel("Seznam vseh knjig:");
JPanel panel = new JPanel();
JTextField text1=new JTextField("Naslov: ");
JTextField text2=new JTextField("Avtor: ");
frame2.add(panel);
panel.add(label);
panel.add(text1);
panel.add(text2);
}
}
static class Action2 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
JFrame frame3 = new JFrame("Prikaz knjige");
frame3.setVisible(true);
frame3.setSize(600,300);
JLabel label = new JLabel("Vpisi naslov knjige:");
JPanel panel = new JPanel();
frame3.add(panel);
panel.add(label);
}
}
static class Action3 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
JFrame frame4 = new JFrame("Dodajanje knjige");
frame4.setVisible(true);
frame4.setSize(600,300);
JLabel label = new JLabel("Vpisi podtke o knjigi");
JPanel panel = new JPanel();
frame4.add(panel);
panel.add(label);
}
}
static class Action4 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
JFrame frame5 = new JFrame("Brisanje knjige");
frame5.setVisible(true);
frame5.setSize(600,300);
JLabel label = new JLabel("Vpisi naslov knjige, ki jo zelis brisati");
JPanel panel = new JPanel();
frame5.add(panel);
panel.add(label);
}
}
static class Action5 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
JFrame frame6 = new JFrame("Urejanje knjige");
frame6.setVisible(true);
frame6.setSize(600,300);
JLabel label = new JLabel("Vpisi naslov knjige, ki jo zelis urejati");
JPanel panel = new JPanel();
frame6.add(panel);
panel.add(label);
}
}
static class Action6 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
System.exit(0);
}
}
}
try something with layout. JFrame and or remove managed by inside with a content pane. content pane default layout is BorderLayout. so you need to try border layout stuff.
or you can try this code in you main method
frame.setLayout(new FlowLayout());
this will add component by one by one.
for more about layout you can get in here
This is just a fix and not really an explanation of why the problem is occurring.
Call frame.revalidate() after adding all the buttons.
From the Java Docs,
public Component add(Component comp)
This method
changes layout-related information, and therefore, invalidates the
component hierarchy. If the container has already been displayed, the
hierarchy must be validated thereafter in order to display the added
component.

change JLabel of a panel depending on Jbutton of another panel in the same Jframe

I have constructed a class for the JPanel with several JButtons.Inside this class I want to construct another JPanel with JLabels that will change depending on the actionPerformed on the JButtons of the first JPanel.Finally, I want to add these 2 panels on the same Jframe. Can all these be done within the class of the first Panel?Otherwise, which is a better approach for this problem?
Yes, you can. One way you could accomplish this is with anonymous inner classes (saves keystrokes):
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
public class Foo {
JLabel one;
JLabel two;
public static void main(String[] args) {
(new Foo()).go();
}
public void go() {
JFrame frame = new JFrame("Test");
// Panel with buttons
JPanel buttonPanel = new JPanel();
JButton changeOne = new JButton("Change One");
changeOne.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
one.setText("New text for one");
}
}
buttonPanel.add(changeOne);
JButton changeTwo = new JButton("Change Two");
changeTwo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
two.setText("New text for two");
}
}
buttonPanel.add(changeTwo);
frame.add(buttonPanel, BorderLayout.NORTH);
// Panel with labels
JPanel labelPanel = new JLabel();
one = new JLabel("One");
labelPanel.add(one);
two = new JLabel("Two");
labelPanel.add(two);
// Set up the frame
frame.add(labelPanel, BorderLayout.SOUTH);
frame.setBounds(50, 50, 500, 500);
frame.setDefaultCloseAction(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

Execute a JFrame program

how to execute this program?
// Resolve class BorderLayout
import java.awt.*;
// Resolve class JFrame and JButton
import javax.swing.*;
// Definition of class FrameWithBorderLayout
public class FrameWithBorderLayout extends JFrame {// Attribute
private JButton buttonEast; // The east button
private JButton buttonSouth; // The south button
private JButton buttonWest; // The west button
private JButton buttonNorth; // The north button
private JButton buttonCenter; // The center button
// Constructor
public FrameWithBorderLayout() {
// Call super class constructor with a title
super("Frame With Multiple Buttons");
// Create JButton objects
buttonEast = new JButton("East");
buttonSouth = new JButton("South");
buttonWest = new JButton("West");
buttonNorth = new JButton("North");
buttonCenter = new JButton("Center");
// Add the JButton objects
add(buttonEast, BorderLayout.EAST);
add(buttonSouth, BorderLayout.SOUTH);
add(buttonWest, BorderLayout.WEST);
add(buttonNorth, BorderLayout.NORTH);
add(buttonCenter, BorderLayout.CENTER);
// Set when the close button is clicked, the application exits
setDefaultCloseOperation(EXIT_ON_CLOSE);
// Reorganize the embedded components
pack();
}
}
---------------------------------current source-------------------------------------
// Resolve class BorderLayout
import java.awt.*;
// Resolve class JFrame and JButton
import javax.swing.*;
// Definition of class FrameWithBorderLayout
public class test extends JFrame {
// Attribute
private JButton buttonEast; // The east button
private JButton buttonSouth; // The south button
private JButton buttonWest; // The west button
private JButton buttonNorth; // The north button
private JButton buttonCenter; // The center button
// Constructor
public test() {
// Call super class constructor with a title
super("Frame With Multiple Buttons");
// Create JButton objects
buttonEast = new JButton("East");
buttonSouth = new JButton("South");
buttonWest = new JButton("West");
buttonNorth = new JButton("North");
buttonCenter = new JButton("Center");
// Add the JButton objects
add(buttonEast, BorderLayout.EAST);
add(buttonSouth, BorderLayout.SOUTH);
add(buttonWest, BorderLayout.WEST);
add(buttonNorth, BorderLayout.NORTH);
add(buttonCenter, BorderLayout.CENTER);
// Set when the close button is clicked, the application exits
setDefaultCloseOperation(EXIT_ON_CLOSE);
// Reorganize the embedded components
pack();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
FrameWithBorderLayout frame = new FrameWithBorderLayout();
frame.setVisible(true);
}
});
}
}
Every Java program starts from a main method:
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
FrameWithBorderLayout frame = new FrameWithBorderLayout();
frame.setVisible(true);
}
});
}
Add this to your frame class.
FrameWithBorderLayout frameTest = new FrameWithBorderLayout();
frameTest.setVisible(true);

Categories