如何在 1 class 中使用 2 个 propertyChange 方法?

How do I use 2 propertyChange methods in 1 class?

所以我有一个包含 3 个元素的程序:一个可重用的 StepPanel,它增加或减小图形的大小,一个可重用的 JavaBean InitialField,它显示当前大小,以及一个 Picture class 扩展 Canvas 并持有一个矩形和一个圆。外观如下:

目前两个 stepPanel 都更新 (increase/decrease) 圆形和方形的大小,因为我的 propertyChange 方法将它们设置在一起。我想要做的是让 stepPanel1 增加 Square,让 stepPanel2 增加 Circle。除了制作第二个 propertyChange 方法之外,我似乎想不出任何东西,但是你不能在同一个 class 中这样做,我必须只用 1 class 来做。这是我的照片 Canvas class:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

public class Picture extends Canvas implements VetoableChangeListener, PropertyChangeListener {
    private final int SIZE = 100;
    private int radius = 1;
    private int side = 1;

    public Picture() {
        setSize(SIZE,SIZE);
    }

    @Override
    public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
        if ((pce.getPropertyName()).equals("value")) {
            int v = (Integer)pce.getNewValue();
            if ((v <=0)||(v > SIZE/2))
                throw new PropertyVetoException ("Value out of bounds!", pce);        
        }   
    }


    @Override
    public void propertyChange(PropertyChangeEvent pce) {
        if ((pce.getPropertyName()).equals("value")) {
            setRadius((Integer)pce.getNewValue());
            setSide((Integer)pce.getNewValue());
            repaint();
        }
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    public int getRadius() {
        return this.radius;
    }

    public void setSide(int side) {
        this.side = side;
    }

    public int getSide() {
        return this.side;
    }

    @Override
    public void paint (Graphics g) {
        Dimension d = getSize();
        g.setColor(Color.GREEN);
        g.fillOval(d.width/2 - radius, d.height/2 - radius, radius*2, radius*2);
        g.setColor(Color.BLUE);
        g.drawRect(d.width/2 - side, d.height/2 - side, side*2, side*2);
    }

}

这是我的 StepPanel class:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class StepPanel extends javax.swing.JPanel implements ActionListener {

    private int step = 0;

    public StepPanel() {
        initComponents();
        btnUp.addActionListener(this);
        btnDown.addActionListener(this);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        btnDown = new javax.swing.JButton();
        btnUp = new javax.swing.JButton();

        btnDown.setText("<<");

        btnUp.setText(">>");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(2, 2, 2)
                .addComponent(btnDown)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnUp)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(btnUp)
                .addComponent(btnDown))
        );
    }// </editor-fold>                        

    public void setStep(int step){
        int oldStep = this.step;
        this.step = step;
        firePropertyChange("step", oldStep, this.step);
        this.step = 0;
    }

    public int getStep() {
        return this.step;
    }

    public void actionPerformed(ActionEvent e) {
        if ((e.getSource()).equals(btnUp)) 
            setStep(1); 
        if ((e.getSource()).equals(btnDown))
            setStep(-1);
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnDown;
    private javax.swing.JButton btnUp;
    // End of variables declaration                   
}

这是初始字段:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import javax.swing.JTextField;


public class InitialField extends JTextField  implements ActionListener,
                                                         PropertyChangeListener{
    private int value;

    /** Creates a new instance of InitialField */
    public InitialField() {
        addActionListener(this);
    }

    public void setValue (int value) {
        try {
            int oldValue = this.value;
            fireVetoableChange("value", oldValue, value); // Generates PropertyeChangeEvent
            this.value = value;
            firePropertyChange("value", oldValue, value); // Generates PropertyChangeEvent
        }
        catch (PropertyVetoException pve) {
            pve.printStackTrace();
        }
        setText(getValue() + "");
    }

    public int getValue () {
        return this.value;
    }

    // <Enter>
    public void actionPerformed (ActionEvent e) { 
         try {
             setValue(Integer.parseInt(getText())); // setValue()
         }
        catch (NumberFormatException ex) {
            ex.printStackTrace();                
        }           
    }

    public void propertyChange(PropertyChangeEvent pce) {
        if (pce.getPropertyName().equals("step"))
            setValue(getValue() + (Integer) pce.getNewValue());
    }
}

最后,这是表格:

public class Form extends javax.swing.JFrame {

    /**
     * Creates new form Form
     */
    public Form() {
        initComponents();
        initialField1.addVetoableChangeListener(picture1);
        initialField1.addPropertyChangeListener(picture1);
        initialField2.addVetoableChangeListener(picture1);
        initialField2.addPropertyChangeListener(picture1);
        stepPanel1.addPropertyChangeListener(initialField1);
        stepPanel2.addPropertyChangeListener(initialField2);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        stepPanel1 = new test.StepPanel();
        initialField1 = new test.InitialField();
        picture1 = new test.Picture();
        stepPanel2 = new test.StepPanel();
        initialField2 = new test.InitialField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        initialField1.setText("0");

        initialField2.setText("0");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(stepPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(initialField1, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(37, 37, 37)
                        .addComponent(picture1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(stepPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(initialField2, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(46, 46, 46)
                        .addComponent(initialField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(stepPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(picture1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(initialField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(stepPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Form.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Form.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Form.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Form.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Form().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private test.InitialField initialField1;
    private test.InitialField initialField2;
    private test.Picture picture1;
    private test.StepPanel stepPanel1;
    private test.StepPanel stepPanel2;
    // End of variables declaration                   
}

你能帮我指导一下如何让stepPanel1增加Rectangle,stepPanel2增加Circle吗?我还必须做到这一点,以便在那之后 Circle 不会变得比 Rectangle 大。预先感谢您的帮助!

What I want to do is make stepPanel1 increase the Square and stepPanel2 increase the Circle.

然后你可以有不同的属性变化事件。所以你可能有一个 "side" 和一个 "radius" 事件。

这就是正常的 Swing 组件的工作方式。它们为每个不同的 属性 更改生成不同的事件。

另外,setSide(...)setRadius() 方法中的代码应该是:

revalidate();
repaint();

set???(...) 方法有责任知道 属性 已更改并导致重新绘制组件。 repaint() 不应是侦听器代码的一部分。

感谢您的帮助和提示!我一定会解决这些问题,看看 Swing 中的事件是如何工作的。同时,这是我为绕过它所做的: 我创建了第二个 InitialField bean 并将其用于 Circle,将 "value" 更改为 "value2"。之后是在 propertyChange 方法中简单地添加第二个 if 语句。我知道这是一种俗气和糟糕的做法,但现在它有效。现在将研究如何以正确的方式做到这一点。