Home > Mobile >  Search JPanel by name
Search JPanel by name

Time:02-18

I was following the How to use CardLayout Java Swing tutorial and I got to the point where the panel is added to the layout:

JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";

//Create the "cards".
JPanel card1 = new JPanel();

//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);

Also they say:

To add a component to a container that a CardLayout object manages, specify a string that identifies the component being added. For example, in this demo, the first panel has the string "Card with JButtons"

So if that string is used to identify the component being added I was wondering if there was a way to get a specific panel in the layout from an AssertJ Swing FrameFixture or directly from the JFrame object, passing the string.

I see that the add method is inherited from java.awt.Container. I was expecting to find a method that would allow me to do something like frame.getComponent(BUTTONPANEL) but that method expects an index as parameter. Did I overlook something?

Also I'm aware of the fact that I could just do card1.setName(BUTTONPANEL) and then in my tests retrieve it with:

window = new FrameFixture(view);
window.panel(BUTTONPANEL);

But what's the point of setting that string in the add method if there is no use for it. Thanks.

Edit:

I had missed the fact that of course the string BUTTONPANEL it it is used to change the panel from the card layout, like this:

cardLayout.show(getContentPane(), BUTTONPANEL);

And so obviously that string has a use.

However I was looking for a way to be able to get the JPanel object by calling a method on the JFrame or FrameFixture object, passing the string. Something like this:

JPanel buttonPanelPanel = frame.getPanelFromName(BUTTONPANEL);

This is because within the tests I don't have a direct access to the panels, but only to the frame. In order to make assertions on a particular panel I wanted to be able to perform a get of the panel with the string used in add. But maybe this is not possible.

CodePudding user response:

I added a method to the MainPanel class to return a JPanel when you pass a String. I don't use the method, but it's there.

I made all the additional classes inner classes so I could post the code as one block.

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CardPanelExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CardPanelExample());
    }
    
    private final MainPanel mainPanel;
    
    public CardPanelExample() {
        this.mainPanel = new MainPanel(this);
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("CardPanel Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(mainPanel.getPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    public void setNextPanel() {
        mainPanel.setNextPanel();
    }
    
    public JPanel getPanelFromName(String name) {
        return mainPanel.getPanelFromName(name);
    }
    
    public class MainPanel {
        
        private final CardLayout cardLayout;
        
        private final JPanel panel;
        private JPanel yellowPanel, orangePanel, whitePanel;
        
        private final String[] panelStrings;
        private String currentPanelString;
        
        public MainPanel(CardPanelExample view) {
            this.cardLayout = new CardLayout();
            this.panelStrings = new String[] { "alpha", "beta", "gamma" };
            this.currentPanelString = panelStrings[0];
            this.panel = createMainPanel(view, cardLayout, panelStrings);
        }
        
        private JPanel createMainPanel(CardPanelExample view, 
                CardLayout cardLayout, String[] panelStrings) {
            this.yellowPanel = new ColorPanel(view, Color.YELLOW).getPanel();
            this.orangePanel = new ColorPanel(view, Color.ORANGE).getPanel();
            this.whitePanel = new ColorPanel(view, Color.WHITE).getPanel();
            
            JPanel panel = new JPanel(cardLayout);
            panel.add(yellowPanel, panelStrings[0]);
            panel.add(orangePanel, panelStrings[1]);
            panel.add(whitePanel, panelStrings[2]);
            
            return panel;
        }
        
        public JPanel getPanelFromName(String name) {
            if (name.equals(panelStrings[0])) {
                return yellowPanel;
            } else if (name.equals(panelStrings[1])) {
                return orangePanel;
            } else if (name.equals(panelStrings[2])) {
                return whitePanel;
            } else {
                return null;
            }
        }
        
        
        public void setNextPanel() {
            for (int index = 0; index < panelStrings.length; index  ) {
                if (currentPanelString.equals(panelStrings[index])) {
                    index =   index % panelStrings.length;
                    currentPanelString = panelStrings[index];
                    cardLayout.show(panel, currentPanelString);
                    return;
                }
            }
        }

        public JPanel getPanel() {
            return panel;
        }
        
    }
    
    public class ColorPanel {
        
        private final JPanel panel;
        
        public ColorPanel(CardPanelExample view, Color backgroundColor) {
            this.panel = createMainPanel(view, backgroundColor);
        }
        
        private JPanel createMainPanel(CardPanelExample view, Color backgroundColor) {
            JPanel panel  = new JPanel(new FlowLayout());
            panel.setBackground(backgroundColor);
            panel.setBorder(BorderFactory.createEmptyBorder(25, 150, 25, 150));
            
            JButton button = new JButton("Next Panel");
            button.addActionListener(new ButtonListener(view));
            panel.add(button);
            
            return panel;
        }

        public JPanel getPanel() {
            return panel;
        }
        
    }
    
    public class ButtonListener implements ActionListener {
        
        private final CardPanelExample view;

        public ButtonListener(CardPanelExample view) {
            this.view = view;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            view.setNextPanel();
        }
        
    }

}
  • Related