如何在多个 Class Java Swing 项目中处理事件?

How to Handle Events in a multiple Class Java Swing Project?

比如我有两个 Java 类:

public class MainFrame extend JFrame implements ActionListener{
    public SouthPanel SPanel = new SouthPanel();
    public int foo = 0;
    MainFrame() {
        
        //MainFrame config
         this.add(SPanel);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        
    }

}


public class SouthPanel extend Panel {
   public JButton openNewWindow = new JButton();
   public JLabel label = new Label();
   SouthPanel() {
      //button and label config
      //adding component
      }
}

当我从 SouthPanelfoo 中单击按钮时,我可以做些什么来制作一个功能? MainFrame 会改变。

因此,在大多数 UI 框架中,您有一个“观察者模式”的概念,这是让感兴趣的各方注册感兴趣的方式,以便在对象发生某些事情时得到通知。

Swing 使用“侦听器”来促进这一基本概念。您不必拘泥于使用 Swing 定义的侦听器,您可以创建自己的侦听器,例如...

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventListener;
import java.util.EventObject;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                SouthPane southPane = new SouthPane();
                southPane.addSourceListener(new SouthListener() {
                    @Override
                    public void somethingDidHappen(SouthEvent evt) {
                        System.out.println("Something important this way did happen");
                    }
                });
                frame.add(southPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    // So you can attach additional properties about the event itself
    public class SouthEvent extends EventObject {

        public SouthEvent(SouthPane source) {
            super(source);
        }

    }

    // Describes what actions the SouthPane might generate
    public interface SouthListener extends EventListener {
        public void somethingDidHappen(SouthEvent evt);
    }

    public class SouthPane extends JPanel {

        public SouthPane() {
            JButton btn = new JButton("Click me");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fireSomethingDidHappen();
                }
            });
            add(btn);
        }

        public void addSourceListener(SouthListener listener) {
            listenerList.add(SouthListener.class, listener);
        }

        public void removeSouthListener(SouthListener listener) {
            listenerList.remove(SouthListener.class, listener);
        }

        protected void fireSomethingDidHappen() {
            SouthListener[] listeners = listenerList.getListeners(SouthListener.class);
            if (listeners.length == 0) {
                return;
            }
            SouthEvent event = new SouthEvent(this);
            for (SouthListener listener : listeners) {
                listener.somethingDidHappen(event);
            }
        }

    }
}

这个例子故意啰嗦,因为你并不“总是”需要创建一个事件对象,但它是将信息传回观察者的好方法,因为它实际上可能没有直接引用反对它的监控。