[英]Java Swing Jbutton accessing a pressed button from another class?
嗨,我在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;
}
}
对我来说,这看起来应该可以工作,但是并不能到达输出“到目前为止的工作”的代码。 我单击按钮,但没有任何反应
但是,一旦我添加了输出值,它确实可以工作。 现在,当我单击该按钮时,它将运行。
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);
}
}
}
缺点:
好处:
该按钮的单击发生在与运行循环不同的线程中。 私有变量的更改对循环线程不可见,因此它将继续循环。
您应该使clicked
变量volatile
。 这将确保对它感兴趣的其他线程可以看到其中的更改。
打印命令可能会导致内存模型允许该线程看到新值,但是当然,这不是正确的方法。
当然,也不建议让布尔值变量紧闭循环。
使用某种模式对话框而不是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;
}
}
有关更多详细信息,请参见如何使用对话框 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.