Java Swing Jbutton访问另一个类的按下按钮?

时间:2015-03-15 18:50:23

标签: java swing jbutton

您好我在java中遇到此问题,尝试使用swing创建UI。我遇到了一个我无法弄清楚的问题,我需要一些帮助。

我想要发生的是当点击按钮时,它将它传递给方法run()中创建的对象ui。

public class MainTest{
    public static void main(String[] args){
        MainTest test = new MainTest();
        test.run();
    }

    public void run(){
        UITest ui = UITest();
        ui.start();

        while (true){
            if (ui.getClicked()) break;
        }

        System.out.println("Working this far");
}


public class UITest{
    private JFrame frame;
    private boolean clicked = false;

    public void start(){
        EventQueue.invokeLater(new JframeCreator());
    }

    private class JframeCreator implements Runnable{
        public void run(){
            createUI();
            frame.setVisible(true);
        }
    }

    private void createUI(){
        frame = new JFrame();
        frame.setResizable(false);
        frame.setSize(353, 264);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JButton btnNewButton = new JButton("test");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                clicked = true;
            }
        });
        btnNewButton.setBounds(118, 150, 89, 32);
        frame.getContentPane().add(btnNewButton);

    }

    public boolean getClicked(){
        return clicked;
    }
}       

对我而言,这看起来应该可行,但是它没有达到输出的代码#34;工作到目前为止#34;。我点击按钮没有任何反应

一旦我添加了输出值,它确实有效。现在,当我点击按钮时,它会运行。

public void run(){
    //previous code
    while(true){
        if (ui.getClicked()) break;
        System.out.println("Not working"); //Added
    }

    System.out.println("working this far");
}

我似乎无法弄清楚为什么它以这种方式工作以及我缺少的东西。

希望我说得够清楚。

3 个答案:

答案 0 :(得分:1)

一种方法是使用观察者设计模式并监听GUI中的状态变化。一种方法是通过调用firePropertyChange(...)方法触发Swing组件的固有PropertyChangeSupport来通知侦听器。然后,通过addPropertyChangeListener(...)向该组件注册的任何和所有侦听器都可以侦听此事件。例如:

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class MainTest{
   public static void main(String[] args){
      final MtNonGui nonGui = new MtNonGui();

      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            MtGuiPanel guiPanel = new MtGuiPanel();
            JFrame testFrame = new JFrame("Test");
            testFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            testFrame.add(guiPanel);
            testFrame.pack();
            testFrame.setLocationByPlatform(true);
            testFrame.setVisible(true);

            guiPanel.addPropertyChangeListener(MtGuiPanel.PRESS_ME_ACTION, new PropertyChangeListener() {

               @Override
               public void propertyChange(PropertyChangeEvent evt) {
                  nonGui.buttonPressed();
               }
            });
         }
      });
   }

}

class MtNonGui {

   public void buttonPressed() {
      System.out.println("Button Pressed");
   }

}

class MtGuiPanel extends JPanel {
   public static final String PRESS_ME_ACTION = "press me action";
   private JButton button = new JButton(new PressMeAction("Press Me"));

   public MtGuiPanel() {
      add(button);
   }

   private class PressMeAction extends AbstractAction {
      public PressMeAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         MtGuiPanel.this.firePropertyChange(PRESS_ME_ACTION, false, true);
      }
   }
}

缺点:

  1. 它提供了很多简单通知的代码
  2. 优点:

    1. 它们都解耦了 - GUI完全不知道谁在听它,非GUI对象也是如此。
    2. 不需要无限循环来轮询GUI的状态。
    3. 它很好地扩展,因此当你的程序变得更大更复杂时,这不应该破坏。

答案 1 :(得分:1)

单击按钮发生在与运行循环的线程不同的线程中。私有变量的更改对循环线程不可见,因此它会继续循环。

您应该制作clicked变量volatile。这将确保对其感兴趣的其他线程可以看到它的变化。

打印命令可能会导致内存模型允许新值对该线程可见,但当然,这不是正确的方法。

当然,在布尔变量上等待紧密循环也不是那么可取。

答案 2 :(得分:1)

使用某种模式对话框而不是JFrame,并在控件返回代码时检查UI的状态。

模态对话框将在其可见的位置阻止。

public class MainTest{
    public static void main(String[] args){
        MainTest test = new MainTest();
        test.run();
    }

    public void run(){
        EventQueue.invokeLater(new Runnable(){
            public void run() {
                UITest ui = UITest();
                boolean wasClicked = ui.start();

                System.out.println("Working this far");
            }
     }
}


public class UITest{
    private JDialog frame;
    private boolean clicked = false;

    public boolean start(){
        createUI();
        frame.setVisible(true);
        return clicked;
    }

    private void createUI(){
        frame = new JDialog();
        frame.setResizable(false);
        frame.setSize(353, 264);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Really, really bad idea
        frame.getContentPane().setLayout(null);

        JButton btnNewButton = new JButton("test");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                clicked = true;
                dispose();
            }
        });
        btnNewButton.setBounds(118, 150, 89, 32);
        frame.getContentPane().add(btnNewButton);

    }

    public boolean getClicked(){
        return clicked;
    }
}       

有关详细信息,请参阅How to use dialogs