How do I change JPanel inside a JFrame on the fly?
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
How to switch JPanels in a JFrame from within the panel?
Like so :
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CardLayoutDemo extends JFrame {
public final String YELLOW_PAGE = "yellow page";
public final String RED_PAGE = "red page";
private final CardLayout cLayout;
private final JPanel mainPane;
boolean isRedPaneVisible;
public CardLayoutDemo(){
setTitle("Card Layout Demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
mainPane = new JPanel();
mainPane.setPreferredSize(new Dimension(250,150));
cLayout = new CardLayout();
mainPane.setLayout(cLayout);
JPanel yellowPane = new JPanel();
yellowPane.setBackground(Color.YELLOW);
JPanel redPane = new JPanel();
redPane.setBackground(Color.RED);
mainPane.add(YELLOW_PAGE, yellowPane);
mainPane.add(RED_PAGE, redPane);
showRedPane();
JButton button = new JButton("Switch Panes");
button.addActionListener(e -> switchPanes() );
setLayout(new BorderLayout());
add(mainPane,BorderLayout.CENTER);
add(button,BorderLayout.SOUTH);
pack();
setVisible(true);
}
void switchPanes() {
if (isRedPaneVisible) {showYelloPane();}
else { showRedPane();}
}
void showRedPane() {
cLayout.show(mainPane, RED_PAGE);
isRedPaneVisible = true;
}
void showYelloPane() {
cLayout.show(mainPane, YELLOW_PAGE);
isRedPaneVisible = false;
}
public static void main(String[] args) {
new CardLayoutDemo();
}
}
Switching between JPanels in a JFrame
"What do I need to put inside the if blocks to change panel views? I would have assumed jPanel1.something() but I don't know what that something is."
Don't compare string with
==
, it will not work. Use.equals
..if("runserver".equals(str)){
You need to use the method
.show
from theCardLayout
CardLayout.show(jPanel1, "whichPanel");
public void show(Container parent, String name)
- Flips to the component that was added to this layout with the specified name, using addLayoutComponent. If no such component exists, then nothing happens.void setPanel(String str){
CardLayout layout = (CardLayout)jPanel1.getLayout();
if("runserver".equals(str)){
layout.show(jPanel1, "card4");
}else if("connectserver".equals(str)){
layout.show(jPanel1, "card3");
} else{
layout.show(jPanel1, "card2");
}
}
See How to Use CardLayout for more details and see the API for more methods.
UPDATE
Try running this example and examine it with your code to see if you notice anything that will help
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestCardLayout {
PanelOne p1 = new PanelOne();
PanelTwo p2 = new PanelTwo();
PanelThree p3 = new PanelThree();
CardLayout layout = new CardLayout();
JPanel cardPanel = new JPanel(layout);
public TestCardLayout() {
JButton showOne = new JButton("Show One");
JButton showTwo = new JButton("Show Two");
JButton showThree = new JButton("Show Trree");
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(showOne);
buttonsPanel.add(showTwo);
buttonsPanel.add(showThree);
showOne.addActionListener(new ButtonListener());
showTwo.addActionListener(new ButtonListener());
showThree.addActionListener(new ButtonListener());
cardPanel.add(p1, "panel 1");
cardPanel.add(p2, "panel 2");
cardPanel.add(p3, "panel 3");
JFrame frame = new JFrame("Test Card");
frame.add(cardPanel);
frame.add(buttonsPanel, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if ("Show One".equals(command)) {
layout.show(cardPanel, "panel 1");
} else if ("Show Two".equals(command)) {
layout.show(cardPanel, "panel 2");
} else {
layout.show(cardPanel, "panel 3");
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TestCardLayout testCardLayout = new TestCardLayout();
}
});
}
}
class PanelOne extends JPanel {
public PanelOne() {
setBackground(Color.GREEN);
add(new JLabel("Panel one"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
class PanelTwo extends JPanel {
public PanelTwo() {
setBackground(Color.BLUE);
add(new JLabel("Panel two"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
class PanelThree extends JPanel {
public PanelThree() {
setBackground(Color.YELLOW);
add(new JLabel("Panel three"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
UPDATE 2
The problem is, the the button is in the ConfigurePanel
class. Trying to create a new StartUPGUI
in that class, won't reference the same components. What you need to do is pass a reference of the StartUPGUI
to the ConfigurePanel
. Something like this
public class ConfigurePanel extends JPanel {
StartUPGUI startup;
public ConfigurePanel(StartUPGUI startup) {
this.startup = startup;
}
....
public void actionPerformed(ActionEvent e) {
startup.setPanel("runserver");
}
}
And instantiate ConfigurePanel
from the StartUPGUI
like this
new ConfigurePanel(StartUPGUI.this);
Switching between JPanels on a JFrame
Other than the comment from @camickr to use CardLayout
, you need to revalidate
. Change:
super.repaint();
to
revalidate();
switching jpanels as a jframe contentpane while running
When components are created they have a size of 0, so there is nothing to paint.
When you dynamically add a component to a visible frame, the you need to revalidate()
the parent container you add the component to. This will invoke the layout manager on the parent container and the child components will be given a size/location.
Normally this would mean you revalidate()
the JPanel
you add the component to. However, in this case, since you are replacing the content pane, the easiest way to do that is to revalidate()
the frame:
public void switchPanel(JPanel pan) {
this.setContentPane(pan);
revalidate();
}
Multiple jPanels in a jFrame and switching the jPanels out
Yes you can switch panels in cardLayout. You should take the cardLayout directly from the component on which you defined it (probably JFrame#getLayout()) not from panel inside the cardLayout (from what you've written I assume that gamePanel is inside cardLayout).
Related Topics
How to Change a Textview's Style at Runtime
Keep Broadcast Receiver Running After Application Is Closed
Retrofit Expected Begin_Object But Was Begin_Array
How to Call JavaScript from Android
What Does Value & 0Xff Do in Java
How to Convert Int[] to Integer[] in Java
Is There a Java API That Can Create Rich Word Documents
Difference Between 'Optional.Orelse()' and 'Optional.Orelseget()'
Picking a Random Element from a Set
What's the Syntax for Mod in Java
How to Convert an Int Array to String with Tostring Method in Java
Execute Another Jar in a Java Program
Java' Is Not Recognized as an Internal or External Command
How to Add an Actionlistener Onto a Jbutton in Java