代码之家  ›  专栏  ›  技术社区  ›  Fos

在cardlayout中切换卡后运行方法

  •  1
  • Fos  · 技术社区  · 11 年前

    我肯定以前有人问过这个问题,但我今天的谷歌功能不强。

    我有一个使用CardLayout作为管理器的JFrame。当我切换到每个JPanel而不使用开关时,如何运行“Start”方法?

    我用于将框架添加到布局的代码是:

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

    我用来切换布局的代码是:

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

    目前,我有一个ActionListener集,它将调用切换代码,但我无法确定如何在它将切换到的屏幕中调用“Start”方法。

    我为每个JPanel设置了一个接口,以便每个JPanels中的方法名都相同。

    2 回复  |  直到 11 年前
        1
  •  5
  •   Community Mohan Dere    9 年前

    你可以使用 ComponentListener 用于面板。当面板成为CardLayout的视图时,它将触发组件事件,并由 componentShown 在您的监听器中(以及从视图中取出的面板 componentHidden ). 致电您的 start() 方法。这样,您就不必显式调用 start() 当面板发生变化时,正如您所需要的那样。

    看见 How to Write Component Listeners 了解更多详情。

    这里有一个简单的例子。

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

    请注意,您实际上没有说明起始方法 ,所以这个代码/答案只是假设您在自定义面板中有一些start方法。希望我猜对了。在未来,甚至现在,你都应该发布 MCVE 这样我们就不用猜了。

        2
  •  1
  •   camickr    11 年前

    我为每个JPanel设置了一个接口,以便每个JPanels中的方法名都相同

    因此,问题是获取在交换面板时可见的当前面板,以便您可以调用该方法。

    退房 Card Layout Focus 对于一个扩展CardLayout的类,它提供了一些帮助器方法,为CardLayout添加附加功能。您可以使用 getCurrentCard() 方法

    因此,changePane(…)方法可能类似于:

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

    当然,您还需要使用 RXCardLayout 作为主面板的布局管理器。