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

Java Swing Jbutton从另一个类访问按下的按钮?,java,swing,jbutton,Java,Swing,Jbutton,嗨,我在java中遇到了这个问题,试图使用swing创建UI。我遇到了一个我无法解决的问题,需要一些帮助 我希望在单击按钮时将其传递给在run()方法中创建的对象ui 对我来说,这看起来应该是可行的,但它没有达到输出“工作到目前为止”的代码。我点击按钮,什么也没发生 不过,一旦我添加了输出值,它就可以工作了。现在,当我点击按钮时,它就会运行 public void run(){ //previous code while(true){ if (ui.getClic

嗨,我在java中遇到了这个问题,试图使用swing创建UI。我遇到了一个我无法解决的问题,需要一些帮助

我希望在单击按钮时将其传递给在run()方法中创建的对象ui

对我来说,这看起来应该是可行的,但它没有达到输出“工作到目前为止”的代码。我点击按钮,什么也没发生

不过,一旦我添加了输出值,它就可以工作了。现在,当我点击按钮时,它就会运行

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

    System.out.println("working this far");
}
我只是想不出为什么它会这样,我错过了什么


希望我能说得足够清楚。

一种方法是使用观察者设计模式,并在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);
      }
   }
}
缺点:

  • 对于一个简单的通知,有很多代码
  • 优点:

  • 它是完全解耦的——GUI完全不知道谁在听它,非GUI对象也是如此
  • 不需要无限循环来轮询GUI的状态
  • 它可以很好地扩展,所以当您的程序变得更大、更复杂时,这不应该破坏一切

  • 一种方法是使用观察者设计模式并监听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);
          }
       }
    }
    
    缺点:

  • 对于一个简单的通知,有很多代码
  • 优点:

  • 它是完全解耦的——GUI完全不知道谁在听它,非GUI对象也是如此
  • 不需要无限循环来轮询GUI的状态
  • 它可以很好地扩展,所以当您的程序变得更大、更复杂时,这不应该破坏一切

  • 一种方法是使用观察者设计模式并监听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);
          }
       }
    }
    
    缺点:

  • 对于一个简单的通知,有很多代码
  • 优点:

  • 它是完全解耦的——GUI完全不知道谁在听它,非GUI对象也是如此
  • 不需要无限循环来轮询GUI的状态
  • 它可以很好地扩展,所以当您的程序变得更大、更复杂时,这不应该破坏一切

  • 一种方法是使用观察者设计模式并监听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);
          }
       }
    }
    
    缺点:

  • 对于一个简单的通知,有很多代码
  • 优点:

  • 它是完全解耦的——GUI完全不知道谁在听它,非GUI对象也是如此
  • 不需要无限循环来轮询GUI的状态
  • 它可以很好地扩展,所以当您的程序变得更大、更复杂时,这不应该破坏一切

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

    您应该使
    被单击
    变量
    volatile
    。这将确保对它感兴趣的其他线程可以看到其中的更改

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


    当然,让一个紧循环等待一个布尔变量也不是那么可取。

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

    您应该使
    被单击
    变量
    volatile
    。这将确保对它感兴趣的其他线程可以看到其中的更改

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


    当然,让一个紧循环等待一个布尔变量也不是那么可取。

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

    您应该使
    被单击
    变量
    volatile
    。这将确保对它感兴趣的其他线程可以看到其中的更改

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


    当然,让一个紧循环等待一个布尔变量也不是那么可取。

    按钮的点击发生在与运行循环的线程不同的线程中。私有制的变化