Running a method after switching cards in cardlayout

混江龙づ霸主 提交于 2019-12-04 04:58:16

问题


I'm sure someone has asked this question before, but my google-fu is not strong today.

I have a JFrame that uses a CardLayout as its manager. How do I run a "Start" method when I switch to each JPanel without using a switch?

The code I use to add the frames to the layout is:

/**
 * Adds JPanels to the Card Layout.
 * @param panel is the JPanel to add to the layout.
 * @param windowName is the identifier used to recognise the Panel.
 */
 public final void addToCards(final JPanel panel, final WindowNames windowName) {
     view.getBasePanel().add(panel, windowName.getValue());
 }

The code I use to switch the layout is:

/**
 * Method to change the JPanel currently visible on the BasePanel.
 * @param windowName is the name of the JPanel to change to.
 */
 public final void changePanel(final WindowNames windowName) {
    view.getCardLayout().show(view.getBasePanel(), windowName.getValue());
 }

Currently I have an ActionListener set that will call the switch code, but I can't work out how to call the "Start" method within the screen that it will be switching to.

I have an interface setup for each of the JPanels so that the method name will be identical in each.


回答1:


You can just use a ComponentListener for the panel(s). When the panel becomes the view of the CardLayout, it will fire a component event and handled by componentShown in your listener (as well as the panel taken out of view, handling the componentHidden). Call your start() method there. This way you don't have to explicitly call the start() when the panel changes, as it be called for you.

See How to Write Component Listeners for more details.

Here is a simple example.

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

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

public class Main {

    private static final String PANEL_A = "panelA";
    private static final String PANEL_B = "panelB";

    CardLayout layout = new CardLayout();
    JPanel panel = new JPanel(layout);
    ComponentListenerPanel p1 = new ComponentListenerPanel(PANEL_A);
    ComponentListenerPanel p2 = new ComponentListenerPanel(PANEL_B);
    JButton b1 = new JButton(PANEL_A);
    JButton b2 = new JButton(PANEL_B);

    public Main() {
        panel.add(p1, PANEL_A);
        panel.add(p2, PANEL_B);

        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                show(PANEL_A);
            }
        });
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                show(PANEL_B);
            }
        });
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(b1);
        buttonPanel.add(b2);

        JFrame frame = new JFrame();
        frame.add(panel);
        frame.add(buttonPanel, BorderLayout.PAGE_END);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void show(String panelName) {
        layout.show(panel, panelName);
    }

    private class ComponentListenerPanel extends JPanel {
        private String panelName;

        public ComponentListenerPanel(String panelName) {
            this.panelName = panelName;
            addComponentListener(new ComponentAdapter() {
                @Override
                public void componentHidden(ComponentEvent evt) {
                    stop();
                }
                @Override
                public void componentShown(ComponentEvent evt) {
                    start();
                }
            });
        }

        public void start() {
            System.out.println(panelName + " started");
        }

        public void stop() {
            System.out.println(panelName + " stopped");
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Main();
            }
        });
    }
}

Note you haven't actually said where the start method is, so this code/answer is just assuming you have some start method in custom panel. Hope I guessed right. In the future, or even now, you should always post an MCVE so that we don't have to do all this guessing.




回答2:


I have an interface setup for each of the JPanels so that the method name will be identical in each

So then the problem is getting the current panel that is visible when the panels are swapped so you can invoke the method.

Check out Card Layout Focus for a class that extends CardLayout to provide a few helper methods to add additional functionality for the CardLayout. You would use the getCurrentCard() method.

So your changePane(...) method might be something like:

public final void changePanel(final WindowNames windowName) {
    //view.getCardLayout().show(view.getBasePanel(), windowName.getValue());
    RXCardLayout layout = view.getCardLayout();
    layout.show(view.getBasePanel(), windowName.getValue());
    MyInterface panel = (MyInterface)layout.getCurrentCard();
    panel.someMethod(...);
 }

Of course you would also need to use the RXCardLayout as the layout manager for your main panel.



来源:https://stackoverflow.com/questions/25338941/running-a-method-after-switching-cards-in-cardlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!