【问题标题】:Creating a custom Bound Property创建自定义绑定属性
【发布时间】:2014-05-23 11:34:24
【问题描述】:

说明

我已经创建了我当前项目的示例,但采用 SSCCE 形式。

代码已更新:

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test2 extends JFrame{
    private Panels panel1, panel2;
    
    public Test2(){
        init();
    }
    
    private void init(){
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new GridLayout(0,1));
        panel1 = new Panels("Test1");
        panel2 = new Panels("Test2");
        add(panel1.getPanel());
        add(panel2.getPanel());
        pack();
        setVisible(true);
        
    }
    public class Panels {
        private JSlider slider;
        private JPanel panel;
        private JLabel label;
        private ChangeListener changeListener;
        private PropertyChangeSupport changeSup;


        public Panels(String text){
            slider = new JSlider();
            slider.setMajorTickSpacing(50);
            slider.setMaximum(255);
            slider.setMinorTickSpacing(10);
            slider.setPaintLabels(true);
            slider.setPaintTicks(true);
            setSliderValue(0);
            label = new JLabel();
            label.setText("0");


            changeListener = new ChangeListener(){

                @Override
                public void stateChanged(ChangeEvent e) {
                    setLabelText(String.valueOf(getSliderValue()));
                }           
            }; 
            slider.addChangeListener(changeListener);
            
            
            panel = new JPanel();
            panel.add(label);
            panel.add(slider);
        }

        public final int getSliderValue() {
            return slider.getValue();
        }

        public final void setSliderValue(int value) {
            slider.setValue(0);
        }

        public final String getLabelText() {
            return label.getText();
        }

        public final void setLabelText(String text) {
            String oldLabelText = getLabelText();
            label.setText(text);
            changeSup.firePropertyChange("value", oldLabelText, getLabelText());
        }
        
        public void
        addPropertyChangeListener(PropertyChangeListener listener){
            changeSup.addPropertyChangeListener("value", listener);
        }
        
        public void
        removePropertyChangeListener(PropertyChangeListener listener){
            changeSup.removePropertyChangeListener("value", listener);
        }
               
        public final JPanel getPanel(){
            return panel;
        }
        
        
        
    }  
    
    public static void main(String[] args) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } 
        catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Test2.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Test2();
            }
        });
    }
   
    
    
}

再次注意,这是一个 SSCCE,非常准系统。这个想法是存在的。

基本上,上面的代码创建了一个带有 2 个 JSliders 的 JFrame,并用 Listener 更新了一个 JLabel。我要尝试的是根据JSliders 中的两个值更新另一个组件的某种方式。


我该怎么办

我想我应该创建一个Bound Property,但我对 Java 的那个领域不熟悉。

如果这不是解决问题的好方法,我愿意接受建议。

【问题讨论】:

  • 如何定义“绑定属性”?
  • @PM77-1 从 Java Doc 中找到 here,在“绑定属性”下。
  • 你真的有JavaBean吗?
  • @PM77-1 是的,虽然在 SSCCE 中我没有仔细检查,所以发布的代码目前没有。不过我现在会解决这个问题。
  • @PM77-1 我的 SSCCE 现在是一个 bean(除非我错过了一个方法)。我也在那里创建了PropertyChangeEvent,但不确定如何继续。

标签: java swing javabeans propertychangelistener


【解决方案1】:

您永远不会初始化或使用您的 PropertyChangeSupport 对象。你应该

  • 将 PropertyChangeSupport 变量更改为 SwingPropertyChangeSupport 变量,因为这是您正在使用的 Swing,因此您希望所有通知都在 EDT、Swing 事件线程上完成。
  • 初始化 PropertyChangeSupport 对象并传入其构造函数this,即当前对象。
  • 为您的班级提供addPropertyChangeListener(PropertyChangeListener listener)removePropertyChangeListener(PropertyChangeListener listener) 方法,以便其他班级可以添加侦听器并侦听更改。
  • 在上述方法中,向您的支持对象添加或删除监听器。
  • 您应该在一个或多个setXXX(...) 方法中触发支持对象,以将更改通知侦听器,并传入适当的属性名称以及新旧值。
  • 请注意,如果您的类扩展了 Swing 组件,则它已经支持 PropertyChange。检查 API,包括 addPropertyChangeListenerremovePropertyChangeListener 方法。
  • 话虽如此,您几乎永远不会想要扩展 JFrame。
  • 您应该阅读tutorials on this,因为只需稍加搜索即可找到它们(上面的链接是PropertyChangeListener tutorial Google 搜索的第一次点击)。

例如,请看这里的代码:

【讨论】:

  • 感谢您的回答!我很抱歉我不得不休息一下,然后才回来。我会执行你的建议。为了让我的代码看起来好多了,我只是匆忙地将 SSCCE 拼凑在一起,以了解它的本质。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 2012-12-20
相关资源
最近更新 更多