1

I'm designing a GUI in Swing. I want a particular area of my gui - the center view - to be able to change its display in response to action events. The center view must never change in size no matter what it displays.

Now when I have a JPanel panel1 with a preffered size and put it into panel2 without any specified size, panel2 will display exactly as panel1 would; You can't even see the double JPanel layer. But since my center frame (panel2) should not change in size, I tried setting panel2 to a specific size and giving it a BorderLayout. Now if I call panel2.add(panel1,BorderLayout.center) where panel1 has the exact same dimension as panel2, the double JPanel layer is visible and the center view displays bad.

How can I add panel1 to panel2, where both have same dimension, so panel2 isn't visible? Or better yet, how should I actually be doing this? (With simple LayoutManagers)

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
user2651804
  • 1,464
  • 4
  • 22
  • 45
  • 2
    Use a CardLayout. Google will get you to the tutorial. – Hovercraft Full Of Eels Mar 26 '14 at 22:14
  • For examples, please see this near duplicate question: [Creating a GUI with multiple panels and one frame](http://stackoverflow.com/questions/8275728/creating-a-gui-with-multiple-panels-and-one-frame) – Hovercraft Full Of Eels Mar 26 '14 at 22:15
  • @HovercraftFullOfEels I may have been to unspecific. Card examples won't work for me as JButtons will the be the elements to handle the changes. – user2651804 Mar 26 '14 at 22:17
  • ??? why should that matter one jot? Answer: It doesn't. You can swap cards in a CardLayout with JButtons just fine. You are making assumptions that shouldn't be made, since a CardLayout view structure can work with pretty much any control structure that you throw at it. – Hovercraft Full Of Eels Mar 26 '14 at 22:17
  • And a CardLayout would be perfect for making sure that the center JPanel, the card-holder JPanel, won't change size. – Hovercraft Full Of Eels Mar 26 '14 at 22:19
  • @HovercraftFullOfEels I was under the impression that it had to be a JComboBox. But I will have 1 seperate button for each display. Does that not defeat the purpose of CardLayout? – user2651804 Mar 26 '14 at 22:21
  • Nope, not at all. There are several great examples that use JComboBox, don't get me wrong, but using the same basic principles will work fine with JButtons/ActionListeners. – Hovercraft Full Of Eels Mar 26 '14 at 22:22
  • Example code posted that uses JButtons and a CardLayout. – Hovercraft Full Of Eels Mar 26 '14 at 22:36

1 Answers1

4

I'll make it an answer since it is the canonical answer to this question:

Use a CardLayout. You can find the tutorial here. A CardLayout would be perfect for making sure that the center JPanel, the card-holder JPanel, won't change size. You can swap cards from pretty much any control structure, be it an ActionListener held by a JButton or from a JComboBox.

For example:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class CardExample extends JPanel {
   enum MyColor {
      RED("Red", Color.RED), YELLOW("Yellow", Color.YELLOW), BLUE("Blue",
            Color.BLUE);
      private String name;
      private Color color;

      private MyColor(String name, Color color) {
         this.name = name;
         this.color = color;
      }

      public String getName() {
         return name;
      }

      public Color getColor() {
         return color;
      }
   }

   private static final int GAP = 3;

   private CardLayout cardlayout = new CardLayout();
   private JPanel cardHolderPanel = new JPanel(cardlayout);

   public CardExample() {
      JPanel btnPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
      for (MyColor myColor : MyColor.values()) {
         JPanel cardPanel = new JPanel();
         cardPanel.setPreferredSize(new Dimension(200, 200));
         cardPanel.setBackground(myColor.getColor());
         cardHolderPanel.add(cardPanel, myColor.getName());

         btnPanel.add(new JButton(new ButtonAction(myColor)));
      }

      setLayout(new BorderLayout(GAP, GAP));
      setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
      add(cardHolderPanel, BorderLayout.CENTER);
      add(btnPanel, BorderLayout.SOUTH);
   }

   private class ButtonAction extends AbstractAction {
      private MyColor myColor;

      public ButtonAction(MyColor myColor) {
         super(myColor.getName());
         this.myColor = myColor;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         cardlayout.show(cardHolderPanel, myColor.getName());
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("CardExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new CardExample());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • "A CardLayout would be perfect for making sure that the center JPanel, the card-holder JPanel, won't change size." In your own example you set the dimension of all JPanels you add to 'cardHolderPanel'. And those docs trails aren't always as informative as I'd like. So how does it hold true that cardHolderPane doesn't change size if I add different sized elements to it? Will it just have the size of the first added/displayed item? For general purposes, where do I get the answer to these questions, SO aside? – user2651804 Mar 27 '14 at 00:08
  • 1
    @user2651804: I know that this layout uses the largest width and height of all the cards combined as the preferred size of its container from experience. To know that it's a fact, check out the source code for CardLayout's `preferredLayoutSize(Container parent)` method, and you'll see that this is in fact true. You can find the source code for this class [here](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/awt/CardLayout.java). – Hovercraft Full Of Eels Mar 27 '14 at 00:55