Java 将事件从自定义组件传递到父级

Java 将事件从自定义组件传递到父级,java,swing,Java,Swing,我有一个扩展JComponent的自定义组件。当您单击它时,它会用鼠标侦听器捕捉事件。根据零部件的状态和单击的位置,存储在其中的数据会更新 如何在发生这种情况时通知父容器,同时保持其完全独立?我自己会使用JComponent附带的PropertyChangeSupport,然后在程序状态发生变化时启动notify方法 例如: import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.Action

我有一个扩展JComponent的自定义组件。当您单击它时,它会用鼠标侦听器捕捉事件。根据零部件的状态和单击的位置,存储在其中的数据会更新


如何在发生这种情况时通知父容器,同时保持其完全独立?

我自己会使用JComponent附带的PropertyChangeSupport,然后在程序状态发生变化时启动notify方法

例如:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class PropChangeEg {
   private static void createAndShowGui() {
      final JLabel counterLabel = new JLabel(" ", SwingConstants.CENTER);

      CustomComponent myCustomComponent = new CustomComponent();
      myCustomComponent.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent pcEvt) {
            if (pcEvt.getPropertyName().equals(CustomComponent.COUNTER)) {
               String text = "Counter: " + pcEvt.getNewValue();
               counterLabel.setText(text);
            }
         }
      });

      JFrame frame = new JFrame("PropChangeEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.add(myCustomComponent, BorderLayout.CENTER);
      frame.add(counterLabel, BorderLayout.PAGE_END);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

@SuppressWarnings("serial")
class CustomComponent extends JComponent {
   public static final String COUNTER = "counter";
   private int counter = 0;

   public CustomComponent() {
      setLayout(new FlowLayout());
      add(new JButton(new AbstractAction("Increment Counter") {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            setCounter(counter + 1);
         }
      }));
      add(new JButton(new AbstractAction("Decrement Counter") {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            setCounter(counter - 1);
         }
      }));
   }

   //@Override // not needed!!
   //public void addPropertyChangeListener(PropertyChangeListener listener) {
   //   super.addPropertyChangeListener(listener);
   //}

   //@Override // not needed!!
   //public void removePropertyChangeListener(PropertyChangeListener listener) {
   //   super.removePropertyChangeListener(listener);
   //}

   public void setCounter(int counter) {
      int oldValue = this.counter;
      int newValue = counter;
      this.counter = newValue;
      firePropertyChange(COUNTER, oldValue, newValue);
   }

   public int getCounter() {
      return counter;
   }


}
关于评论:


ChangeListener也可以很好地工作。1+到用户129。。。但我喜欢PCL的地方在于,我可以指定要侦听的属性的名称,以允许我侦听多个不同状态的更改,这样可以从MVC设计中创建一个完全与控件解耦的完整视图。所以我的建议是:如果你只听一个状态,那么一定要使用ChangeListener,但如果你听多个状态,则使用PCL。

你可以使用ChangeListener,它应该适合你

当然,或者只是实现ChangeListener@user:是的,只要我们尽量减少耦合,我很高兴。事实上,我的不好,若要扩展JComponent,就不需要创建自己的添加或删除PCL,因为它是super附带的。我非常习惯于在必要的地方通过组合进行扩展。我以前尝试过PropertyChangeSupport,但实现起来感觉非常笨拙。不过,幸运的是@user1291492-ChangeListener工作得很好,所以如果你回答这个问题,我会接受它。@Tharwen:那也可以。1+到用户129。。。我喜欢PCL的地方在于,我可以指定要侦听的属性的名称,这样就可以从MVC设计中创建一个与控件完全解耦的完整视图。所以我的建议是:如果你只听一个状态,那么一定要使用ChangeListener,但如果你听多个状态,则使用PCL。