Java JFrame在单独的类中,ActionListener呢?
我试图将Swing GUI与实际代码分离。简而言之,我希望用户启动一个流程(基于用户的选择);在这种情况下,将不再需要JFrame 我不明白的是如何将用户从GUI.class中选择的内容与Main.class共享 你对我有什么建议吗 这是我的密码:Java JFrame在单独的类中,ActionListener呢?,java,swing,actionlistener,Java,Swing,Actionlistener,我试图将Swing GUI与实际代码分离。简而言之,我希望用户启动一个流程(基于用户的选择);在这种情况下,将不再需要JFrame 我不明白的是如何将用户从GUI.class中选择的内容与Main.class共享 你对我有什么建议吗 这是我的密码: public class Main { public static void main(String[] args) { // Show GUI java.awt.EventQueue.invokeLater(new Runnab
public class Main {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI(templates);
gui.setVisible(true);
}
});
// Kick off a process based on the user's selection
}
}
public class GUI extends JFrame {
private static final long serialVersionUID = 1L;
public GUI(Object[] objects) {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 100);
setLocationRelativeTo(null);
JPanel cp = new JPanel();
cp.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(cp);
JLabel lbl = new JLabel("Selection:");
cp.add(lbl);
final JComboBox<String> comboBox = new JComboBox<String>(new String[] { "One", "Two", "Three" });
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
}
});
cp.add(comboBox);
}
}
公共类主{
公共静态void main(字符串[]args){
//显示图形用户界面
invokeLater(new Runnable()){
公开募捐{
GUI=新GUI(模板);
setVisible(true);
}
});
//根据用户的选择启动流程
}
}
公共类GUI扩展JFrame{
私有静态最终长serialVersionUID=1L;
公共GUI(对象[]对象){
setTitle(“GUI”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
立根(100100350100);
setLocationRelativeTo(空);
JPanel cp=新的JPanel();
cp.setboorder(新的空订单(10,10,10,10));
setContentPane(cp);
JLabel lbl=新的JLabel(“选择:”);
cp.add(lbl);
最终JComboBox组合框=新的JComboBox(新字符串[]{“一”、“二”、“三”});
comboBox.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
setVisible(假);
处置();
//与Main.class共享所选项目
}
});
cp.add(组合框);
}
}
您可以创建一个对象来存储选择结果,并将其传递给GUI类的构造函数。在关闭UI之前,在该对象中设置选择结果,然后您的主类可以访问该值:
public class SelectionResult {
private String selectionResult;
public void setSelectionResult(final String selectionResult) {
this.selectionResult = selectionResult;
}
public String getSelectionResult() {
return this.selectionResult;
}
}
然后,您可以这样修改GUI构造函数:
private final SelectionResult selectionResult;
public GUI(Object[] objects, SelectionResult selectionResult) {
this.selectionResult = selectionResult;
...
在主类中创建SelectionResult对象,并将其传递给GUI类的构造函数。在GUI类ActionListener中,可以使用所选值调用setSelectionResult()方法,该值将从主类中可用
在等待在UI中设置值时,需要添加代码使主方法等待,然后根据选择继续执行逻辑。这样做的一个好方法是使用
回调
机制
要遵循的步骤:
- 创建一个回调接口
interface Callback { void execute(Object result); }
类将实现GUI
接口,但不提供任何实现回调
- 制作
classGUI
abstract
abstract class GUI extends JFrame implements Callback
- 现在创建一个
类的对象,提供GUI
接口的实际实现回调
- 在这里您可以使用匿名类
GUI gui = new GUI() { @Override public void execute(Object result) { System.out.println("You have selected " + result); } };
- 您可以在
回调的
方法中传递任何内容execute()
comboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setVisible(false); dispose(); // Share the selected item with Main.class // Callback execute(comboBox.getSelectedItem()); } });
Main
类负责捕获GUI
类指示的Callback
的响应
代码如下:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
// Show GUI
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI() {
@Override
public void execute(Object result) {
System.out.println("You have selected " + result);
}
};
gui.setVisible(true);
}
});
// Kick off a process based on the user's selection
}
}
interface Callback {
void execute(Object result);
}
abstract class GUI extends JFrame implements Callback {
private static final long serialVersionUID = 1L;
public GUI() {
setTitle("GUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 350, 100);
setLocationRelativeTo(null);
JPanel cp = new JPanel();
cp.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(cp);
JLabel lbl = new JLabel("Selection:");
cp.add(lbl);
final JComboBox comboBox = new JComboBox(new String[] { "One", "Two", "Three" });
comboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
// Share the selected item with Main.class
execute(comboBox.getSelectedItem());
}
});
cp.add(comboBox);
}
}
保持框架;用.Djomrton更改内容,非常感谢!事实上,我没有考虑过传递一个物体!但是,让主要方法等待的好方法是什么?有什么比while(true){if(gui==null){break;}}}更合适的吗?您可以使用信号量,并将其作为构造函数参数传递:信号量信号量=新信号量(0);设置选择结果后,在GUI类中对其调用.release()方法,并在希望等待的主方法中对其调用.aquire()方法。非常感谢您的精彩解释!这确实为我提供了一个新的视角。我可以扩展我的问题吗?同样来自设计模式Perspektive:如果我想根据用户的选择进行一些计算并动态更新GUI,我的第一个想法是简单地嵌套另一个计算对象并使GUI对象保持静态(以便计算对象可以访问GUI对象)。你有什么建议吗?除非我完全理解你的代码,否则我不能说。尽量用最小的修改来编写代码,以避免回归。显然,您指的是我的评论的早期版本。我想要避免的(尽管回归可能是错误的术语)是:public void run(){gui=new gui(){(a)Override public void execute(对象结果){Calculations calc=new Calculations(结果){(a)Override public void execute(对象结果){gui.update(结果)}是的,有很多方法可以做到这一点。如果整个应用程序中只有一个
GUI
实例,那么您可以将其设置为静态。我认为计算
也可以被视为实用程序类,因此您可以在其中定义静态方法。为什么要为计算
实现回调
接口?当源收到来自目标的更改通知时,请使用回调
。