1

我想知道在另一个动作之后修改对象的最佳方法是什么。

示例:我有一个带有一些组件的 JPanel,其中一个打开了一个新的 JPanel。在这个新的 JPanel 中,我有一个按钮来修改第一个 JPanel。

我发现了 2 个可行的解决方案,我想知道两者中哪一个是最好的(或另一个)。

第一个是在第一类中添加一个 Actionlistener:

public class SomePanel extends JPanel{

    private JButton button = new JButton("Open New Frame");
    private SomeOtherPanel otherPanel = new SomeOtherPanel();
    private int value = 0;

    public SomePanel(){            
        // initialization code            
        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                otherPanel.setVisible(true);
            }                
        });

        otherPanel.getButton().addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                value = 1;
            }                
        });            
    }


public class SomeOtherPanel extends JPanel{

private JButton button = new JButton("Modify First Panel value");

    public SomeOtherPanel(){

    }
    public JButton getButton() {
        return button;
    }        
}

第二个通过将第一个 JPanel 作为第二个的参数传递:

public class SomePanel extends JPanel{

    private JButton button = new JButton("Open New Frame");
    private SomeOtherPanel otherPanel = new SomeOtherPanel(this);
    private int value = 0;

    public SomePanel(){            
        // initialization code ... size, color ...            
        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                otherPanel.setVisible(true);
            }                
        });             
    }

    public void setValue(int value) {
        this.value = value;
    }   
}

public class SomeOtherPanel extends JPanel{

    private JButton button = new JButton("Modify First Panel value");
    public SomePanel somePanel;

    public SomeOtherPanel(SomePanel panel){
        this.somePanel = panel;
        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                somePanel.setValue(1);
            }                
        });
    }

    public JButton getButton() {
        return button;
    } 
}

这是正确的吗 ?

4

2 回答 2

2

除了您的解决方案不正确之外,这些对象之间会产生高耦合,所以我会给您另一个解决方案。

您可以采用观察者模式,然后解耦视觉组件,actionListener 充当控制器/“调解器”。

我不知道你的价值是做什么的,但我把它作为一个可观察的属性并在它上面注册一个观察者。

public class SomePanel extends JPanel{

private JButton button = new JButton("Open New Frame");
private int value;


public SomePanel(){

    // initialization code ... size, color ...

    button.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
              setValue(1);
        }

    });    
}

public void setValue(int value) {
    int oldValue= this.value;
    this.value = value;
    firePropertyChangeValue("value",oldValue,this.value);
}

}

在其他一些面板中

public class SomeOtherPanel extends JPanel {

     private PropertyChangeListener listener = new ValueListener();

      public PropertyChangeListener getListener(){
                  return listener;
      }

     private class ValueListener implements PropertyChangeListener{
            @Override
            public void propertyChange(PropertyChangeEvent evt){
                        if(evt == null)
                            return;

               if(evt.getPropertyName().equals("value") && ((int) evt.getNewValue()) == 1 ){
                    SomeOtherPanel.this.setVisible(true);
               }        
            }        
     }        
 }

在您初始化两个面板的客户端代码中。

例子:

  JPanel panel = new SomePanel();
  SomeOtherPanel otherPanel = new SomeOtherPanel();
  panel.addPropertyChangeListener("value",otherPanel.getListener());

更新

因为我不明白你想要实现什么你的解决方案很容易,只是简单不要使用匿名类

public class SomePanel extends JPanel{

private ActionListener myAction = new ActionListener(){
       @Override
       public void actionPerformed(ActionEvent evt){
           value =1;//or what you want
       }

}; 

public ActionListener getMyAction{
    return myAction;
}


}

在另一个面板中..

public class SomeOtherPanel extends JPanel {

private JButton button = new JButton();

public void addButtonAction(ActionListener listener){
   button.addActionListener(listener);
}

}

在客户端代码中:

 JPanel panel = new SomePanel();
  SomeOtherPanel otherPanel = new SomeOtherPanel();
  otherPanel .addButtonAction(panel .getMyAction());
于 2013-09-20T14:27:30.667 回答
0

两种方法都可以。如果您寻找最干净的方法来做到这一点,我会说这取决于。

这是一个凝聚力问题。你必须问自己,每节课的目的是什么。

如果您认为 SomeOtherPanel 的目的只是在按下按钮时对 SomePanel 应用更改(无论更改是什么),那么第一种方法是好的方法,因为无需触及 SomeOtherPanel 中的任何代码,您可以选择该类将产生的影响一些面板。

如果您认为 SomeOtherPanel 的目的是将实例变量 Value 设置为 1,那么第二种解决方案是不错的解决方案。

于 2013-09-20T14:28:09.530 回答