在 Java 中使用 JFrame 的侦听器
Listener using JFrame in Java
我现在正在学习 ActionListeners 的基础知识,我一直在这里寻求帮助,但不能完全find/figure我做错了什么。
我有一个 class(客户端)实现了主调用:
...
public static void main(String[] args) {
Myframe test = new Myframe();
N = test.setVisible(); // N is an integer
...
}
然后是我框架中的代码:
public class test extends JFrame {
private JPanel contentPane;
private int N;
public int setVisible(){
this.setVisible(true);
return N;
}
/**
* Create the frame.
*/
public test() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JButton btnOk = new JButton("OK");
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
N=5;
dispose();
}
});
contentPane.add(btnOk, BorderLayout.SOUTH);
}
}
问题是:程序在继续运行之前不等待按下按钮,N 导致一些垃圾值,从而产生错误。
我应该怎么做才能让它在不休眠线程的情况下正确处理它?
解决此问题的一些方法。使用 JDialog - 默认提供模态阻塞,Listener 机制 - 稍后用值回调,或者让你的代码阻塞
JDialog
public class test extends JDialog {
...
private int N;
public int setVisible() {
this.setVisible(true);
return N;
}
public test() {
super(null, ModalityType.APPLICATION_MODAL);
// <== pass parent window here if you have one, you don't seem to..
...
}
阻塞示例
- 使用java.util.concurrent.CountDownLatch
代码
public class test extends JFrame {
....
private CountDownLatch latch;
private int N;
public int setVisible() throws InterruptedException{
latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVisible(true);
}
});
latch.await(); // <== block until countDown called
return N;
}
public test() {
...
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
N=5;
latch.countDown(); <== will unblock await() call
dispose();
}
});
...
}
}
听众
public class test extends JFrame {
...
private Listener listener;
public static interface Listener {
void setN(int n);
}
public void setVisible(Listener listener) throws InterruptedException {
this.listener = listener; // <== save reference to listener
setVisible(true);
}
public test() {
...
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
listener.setN(5); // <== call listener
dispose();
}
});
}
使用模态 JDialog
而不是 JFrame
,它们被设计成在它们可见的地方阻塞,直到它们被关闭...
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JDialog frame = new JDialog();
TestPane testPane = new TestPane();
frame.setTitle("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(testPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
System.out.println("The value was - " + testPane.getValue());
}
});
}
public class TestPane extends JPanel {
private int n;
public TestPane() {
JButton btnOk = new JButton("OK");
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
n = 5;
SwingUtilities.windowForComponent(TestPane.this).dispose();
}
});
}
}
public int getValue() {
return n;
}
}
查看 How to Make Dialogs 了解更多详情
我现在正在学习 ActionListeners 的基础知识,我一直在这里寻求帮助,但不能完全find/figure我做错了什么。
我有一个 class(客户端)实现了主调用:
...
public static void main(String[] args) {
Myframe test = new Myframe();
N = test.setVisible(); // N is an integer
...
}
然后是我框架中的代码:
public class test extends JFrame {
private JPanel contentPane;
private int N;
public int setVisible(){
this.setVisible(true);
return N;
}
/**
* Create the frame.
*/
public test() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JButton btnOk = new JButton("OK");
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
N=5;
dispose();
}
});
contentPane.add(btnOk, BorderLayout.SOUTH);
}
}
问题是:程序在继续运行之前不等待按下按钮,N 导致一些垃圾值,从而产生错误。 我应该怎么做才能让它在不休眠线程的情况下正确处理它?
解决此问题的一些方法。使用 JDialog - 默认提供模态阻塞,Listener 机制 - 稍后用值回调,或者让你的代码阻塞
JDialog
public class test extends JDialog {
...
private int N;
public int setVisible() {
this.setVisible(true);
return N;
}
public test() {
super(null, ModalityType.APPLICATION_MODAL);
// <== pass parent window here if you have one, you don't seem to..
...
}
阻塞示例
- 使用java.util.concurrent.CountDownLatch
代码
public class test extends JFrame {
....
private CountDownLatch latch;
private int N;
public int setVisible() throws InterruptedException{
latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVisible(true);
}
});
latch.await(); // <== block until countDown called
return N;
}
public test() {
...
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
N=5;
latch.countDown(); <== will unblock await() call
dispose();
}
});
...
}
}
听众
public class test extends JFrame {
...
private Listener listener;
public static interface Listener {
void setN(int n);
}
public void setVisible(Listener listener) throws InterruptedException {
this.listener = listener; // <== save reference to listener
setVisible(true);
}
public test() {
...
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
listener.setN(5); // <== call listener
dispose();
}
});
}
使用模态 JDialog
而不是 JFrame
,它们被设计成在它们可见的地方阻塞,直到它们被关闭...
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JDialog frame = new JDialog();
TestPane testPane = new TestPane();
frame.setTitle("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(testPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
System.out.println("The value was - " + testPane.getValue());
}
});
}
public class TestPane extends JPanel {
private int n;
public TestPane() {
JButton btnOk = new JButton("OK");
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
n = 5;
SwingUtilities.windowForComponent(TestPane.this).dispose();
}
});
}
}
public int getValue() {
return n;
}
}
查看 How to Make Dialogs 了解更多详情