Java - 监听变量的改变

9

首先,我是全新的Java用户:/

我已经尝试了两天来解决这个问题,但一直无法绕过它。问题是我正在尝试实现一个变量更改监听器。我曾经尝试过在项目中实现Observer和Observable,但没有成功过。最好的结果是将代码中的一些元素包装到while循环中,但仍然失败。

不管怎样,这是我的类,如果你看一下,我在构造函数之后定义了一些全局变量,我需要监听所有这些全局变量的变化,如果有一个变化,我希望执行一个方法。

我被告知JavaFX有可以监听变量的方法,请问是否属实?无论如何,在此提前感谢您的帮助。

public class Tower_Controller {

    public Tower_Controller() {
    }

    //Global variables
    String isSelected = null;
    int hasModules = 0;
    int cap_s = 0;
    int cpu_s = 0;
    int cap = 0;
    int cpu = 0;
    int shield = 0;
    int armor = 0;
    double em = 00.00;
    double th = 00.00;
    double ki = 00.00;
    double ex = 00.00;


    public void invoke() {
        Invoke_GUI runnable = new Invoke_GUI();
        final JLabel tower_name = runnable.tower_name;
        final JComboBox tower_select = runnable.tower_select;
        final JTree module_browser = runnable.module_browser;
        final JTree selected_modules = runnable.selected_modules;

        final JProgressBar cap_bar = runnable.cap_bar;
        final JProgressBar cpu_bar = runnable.cpu_bar;

        final JLabel em_res = runnable.em;
        final JLabel th_res = runnable.thermic;
        final JLabel ki_res = runnable.kinetic;
        final JLabel ex_res = runnable.explosive;

        tower_select.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (isSelected != null) {
                    Events evt = new Events();
                    evt.towerSelected(isSelected);
                } else {
                    tower_name.setText(tower_select.getSelectedItem().toString());
                    isSelected = tower_name.toString();
                }
            }
        });

        removeTower(tower_name);
        runnable.setVisible(true);

    }



    public void updateValues(final JProgressBar cap_bar, final JProgressBar cpu_bar, final JLabel em_res,
        final JLabel th_res, final JLabel ki_res, final JLabel ex_res){

        cap_bar.setMaximum(cap);
        cap_bar.setString(cap_s + " / " + cap);
        cap_bar.setStringPainted(true);

        cpu_bar.setMaximum(cpu);
        cpu_bar.setString(cpu_s + " / " + cpu);
        cpu_bar.setStringPainted(true);

        String em_v = String.valueOf(em); 
        em_res.setText(em_v);

        String th_v = String.valueOf(th); 
        th_res.setText(th_v);

        String ki_v = String.valueOf(ki); 
        ki_res.setText(ki_v);

        String ex_v = String.valueOf(ex); 
        ex_res.setText(ex_v);
    }

    public void updateList(final ArrayList<String> nodes, final JTree selected_modules) {
        DefaultMutableTreeNode nod = new DefaultMutableTreeNode();
        for (int i = 0; i < nodes.size(); i++) {
            nod.add(new DefaultMutableTreeNode(nodes.get(i)));
        }
        selected_modules.setModel(new DefaultTreeModel(nod));
    }

    public void removeTower(final JLabel tower_name) {
        tower_name.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (hasModules == 1 & isSelected != null) {
                    Events evt = new Events();
                    evt.towerHasModules();
                } else if (isSelected == null) {
                } else {
                    tower_name.setText("No Control Tower selected");
                    isSelected = null;
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
    }

    public JLabel setTowerName(JLabel a, String name) {
        a.setText(name);
        return a;
    }




}
1个回答

13

通知变量更改的一般过程如下:

  1. 首先,使变量私有化。
  2. 为每个变量创建两个方法:一个将其值设置为参数(通常称为 setX(),其中 X 是变量名),另一个获取其值(getX()
  3. 在需要读取或设置变量的任何地方,都要调用这些方法。
  4. setX() 方法中,在循环中调用你的 ObservernotifyObserver() 方法。

就这样!现在每次变量被更改时,已注册的 Observer 将被通知。这个解决方案的关键部分是变量必须是私有的,以便没有代码可以在不经过 setX() 方法的情况下设置它们的值。


2
是的,PropertyChangeListener 也可以正常工作,你可以使用 PropertyChangeSupport 来通知监听器。不过他特别提到了 Observer/Observable。 - Ernest Friedman-Hill
1
嗯,我的上面的指示看起来非常清晰简单。我能做些什么来改进它们吗?你有什么问题或疑问? - Ernest Friedman-Hill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接