How to make two JPanels listen to the same event?

后端 未结 4 1633
你的背包
你的背包 2020-12-17 05:56

I have a JFrame and, inside this JFrame there are two JPanels. When I press a key, both of them must listen to this key event and act.

相关标签:
4条回答
  • 2020-12-17 06:09

    Instead of KeyListener, use Key Bindings and have distinct Action implementations for each panel. By using the WHEN_ANCESTOR_OF_FOCUSED_COMPONENT input map, both panels can respond.

    Addendum: Because the search ends after finding a valid binding for the key, the example below forwards the event to the elements of a List<MyPanel>, each of which can respond differently via an available Action.

    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import java.util.Arrays;
    import java.util.List;
    import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.KeyStroke;
    
    /** @see http://stackoverflow.com/q/10011564/230513 */
    public class TwoPanelsTest extends JFrame {
    
        private MyPanel one = new MyPanel("One");
        private MyPanel two = new MyPanel("Two");
        private List<MyPanel> list = Arrays.asList(one, two);
    
        public TwoPanelsTest() {
            super("TwoPanelsTest");
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            JPanel panel = new JPanel(new GridLayout(0, 1, 10, 10));
            panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            panel.add(one);
            panel.add(two);
            panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
                .put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
            panel.getActionMap().put("up", new AbstractAction() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    for (MyPanel panel : list) {
                        panel.getAction().actionPerformed(e);
                    }
                }
            });
            this.add(panel);
            this.pack();
            this.setLocationRelativeTo(null);
            this.setVisible(true);
        }
    
        private static class MyPanel extends JPanel {
    
            private String string = " will be updated though its action.";
            private Action action = new UpdateAction(this);
            private String name;
            private JLabel label;
    
            public MyPanel(String name) {
                this.name = name;
                this.label = new JLabel(name + string, JLabel.CENTER);
                this.setLayout(new GridLayout());
                this.setFocusable(true);
                this.add(label);
            }
    
            public Action getAction() {
                return action;
            }
    
            private void update() {
                label.setText(name + ": " + System.nanoTime());
            }
    
            private static class UpdateAction extends AbstractAction {
    
                private MyPanel panel;
    
                public UpdateAction(MyPanel panel) {
                    this.panel = panel;
                }
    
                @Override
                public void actionPerformed(ActionEvent ae) {
                    panel.update();
                }
            }
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    TwoPanelsTest t = new TwoPanelsTest();
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-17 06:16

    You should create a XXListener implementation and add that listener by .addXXListener to all the components you need.

    0 讨论(0)
  • 2020-12-17 06:19

    One of the ways is use methods from SwingUtilities for Java6 (notice SwingUtilities for Java7 have got a few changes, but not important in this case) is possible to redirect, distribute, multiple events that came from Standard Swing Listeners, simple example about redirect mouse events from one container to the another,

    0 讨论(0)
  • 2020-12-17 06:31

    You can use the observer pattern for this. http://en.wikipedia.org/wiki/Observer_pattern

    MyKeyEventListener listener = new MyKeyEventListener();
    JPanel one = new JPanel();
    one.addKeyListener(listener);//method might be wrong
    JPanel two = new JPanel();
    two.addKeyListener(listener);
    listener.addObserver(one);
    listener.addObserver(two);
    
    0 讨论(0)
提交回复
热议问题