您好我在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");
}
我似乎无法弄清楚为什么它以这种方式工作以及我缺少的东西。
希望我说得够清楚。
答案 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 :(得分: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