Reputation: 325
Problem: My code is supposed to create a JPanel at the press of a button, but instead the JPanel is being created as soon as the code starts running.
I'm writing in Java SE7 on Eclipse Luna, and my operating system is Windows 8.1.
I've been trying to write a program that has a fixed 'window' (I'm using a JFrame) and can switch between 'screens' (JPanels). The switching is supposed to be done using buttons. At the moment I've got the first panel and the frame being created in my main function, as well as a button being added. Then I've added an actionPerformed method which makes the second panel. I've got my JFrame as a field variable so that the method recognizes it.
The problem is that the second panel is showing up the moment I run the code, with no sign of a button at all.
Here's my main class (including the actionPerformed method):
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
public class WindowOne implements ActionListener{
//A JFrame field is created
public static JFrame frame = new JFrame("JFrame");
public static void main(String[] args) {
//Not sure what this line does
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Sets dimensions of frame
frame.setBounds(100, 100, 600, 600);
//Create an instance of GamePanel (a separate class)
GamePanel gamePanel = new GamePanel();
//Set this panel to the frame
frame.setContentPane(gamePanel);
//Create new button panelButton
JButton panelButton = new JButton("Welcome");
//Create instance of WindowOne
WindowOne listener = new WindowOne();
//Adds action listener to panelButtom
panelButton.addActionListener(listener);
//Add panelButton to the panel
gamePanel.add(panelButton);
//Display frame AFTER adding all components to it
frame.setVisible(true);
}
//This method is called when the panelButton is clicked (at least, that's what's supposed to happen)
public void actionPerformed(ActionEvent e) {
GamePanel gamePanel2 = new GamePanel();
gamePanel2.paint(null);
frame.setContentPane(gamePanel2);
}
}
And here's another class, GamePanel, which I'm using to create and 'paint' the panels (my friend, a more experienced programmer, insisted I use this class rather than just make panels the basic way).
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
public GamePanel(){
}
public void paint(Graphics g){
//Use this method with instances of GamePanel to design different panels
g.fillRect(10,10,10,10);
}
}
Answered! I simplified everything down into one class, and here is the corrected code if anyone in the future ever finds it useful.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Color;
public class WindowOne{
//A JFrame field is created
public static JFrame frame = new JFrame("JFrame");
public static void main(String[] args) {
//FRAME STUFF
//Not sure what this line does
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Sets dimensions of frame
frame.setBounds(100, 100, 600, 600);
//PANEL STUFF
//Create the first panel
JPanel panelOne = new JPanel();
//Set this panel to the frame
frame.setContentPane(panelOne);
//BUTTON STUFF
//Create new button panelButton
JButton panelButton = new JButton("Welcome");
//Add anonymous action listener to panelButton
panelButton.addActionListener(new ActionListener(){
@Override public void actionPerformed(ActionEvent ae){
//What happens when button is clicked:
JPanel panelTwo = new JPanel();
panelTwo.setBackground(Color.black);
frame.setContentPane(panelTwo);
frame.setVisible(true);
}
});
//OTHER STUFF
//Add panelButton to the panel
panelOne.add(panelButton);
//Display frame AFTER adding all components to it
frame.setVisible(true);
}
}
Upvotes: 0
Views: 112
Reputation: 657
The first panel you add is also a GamePanel
instance, which is why you're seeing a square. It's because the first panel is also drawing a square, and not because the second panel is already on your JFrame
.
Edit: some extra tips:
-Never ever call the paint method of a component directly, the framework will do it for you. If you want to tell it you want a component to be painted again, call the repaint()
method.
-When overriding the paint(Graphics g)
method on a Component
, it's best practice to call the superclass' method first: super.paint(g)
. This will do things like paint a background already.
-Instead of overriding the paint(Graphics g)
method you should override the paintComponent(Graphics g)
class in swing components. More info here.
-You can create anonymous ActionListener
instances instead of having your component implement them like so:
panelButton.addActionListener(new ActionListener(){
@Override public void actionPerformed(ActionEvent ae){
//your code when button is clicked
}
});
(or even just a lambda if you're using java 8)
Upvotes: 2
Reputation: 36987
As stated in the coments, actionPerformed
most likely doesn't get called, because it would cause a NullPointerException
.
Instead, what you see is still gamePanel
. It draws that little square because the paint method gets called when you call frame.setVisible(true);
.
Unfortunately, the button doesn't get drawn, because by overwriting the paint
method, the children of gamePanel
don't receive their paint
call.
Try this in GamePanel:
public void paint(Graphics g){
super.paint(g);
//Use this method with instances of GamePanel to design different panels
g.fillRect(10,10,10,10);
}
Upvotes: 0