How to Switch JPAnels Inside a Jframe

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();
}
}

Sample Image

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."

  1. Don't compare string with ==, it will not work. Use .equals.. if("runserver".equals(str)){

  2. You need to use the method .show from the CardLayout

    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



Leave a reply



Submit