Java 从第一个JFrame调用的方法在第二个JFrame中不执行任何操作
我在MainGUI类中将JTextField rfid设置为setEnabledfalse,并创建了方法setRfidEnabled,以便能够从另一个名为CardLayout的类中启用textfield。 当我试图通过按钮事件监听器从CardLayout调用它时,它什么也不做,我的意思是textfield,因为System.out.printLOL;很好。MainGUI包含JFrame,通过按钮调用CardLayout类中的另一个JFrame 当我初始化MainGUI类时,它有线程[Thread-2,6,main],但当我调用CardLayout时,它变成线程[AWT-EventQueue-0,6,main],与CardLayout本身相同。我试图使rfid不稳定,但没有成功 --编辑代码-- MainGUI:Java 从第一个JFrame调用的方法在第二个JFrame中不执行任何操作,java,multithreading,swing,jframe,jtextfield,Java,Multithreading,Swing,Jframe,Jtextfield,我在MainGUI类中将JTextField rfid设置为setEnabledfalse,并创建了方法setRfidEnabled,以便能够从另一个名为CardLayout的类中启用textfield。 当我试图通过按钮事件监听器从CardLayout调用它时,它什么也不做,我的意思是textfield,因为System.out.printLOL;很好。MainGUI包含JFrame,通过按钮调用CardLayout类中的另一个JFrame 当我初始化MainGUI类时,它有线程[Thread
public class MainGUI {
JTextField rfid;
JButton button;
final JFrame frame;
final JPanel pane;
LayoutChanger layout = new LayoutChanger();
public MainGUI() {
rfid = new JTextField("", 10);
button = new JButton("CardLayoutSwitch");
frame = new JFrame("Main GUI Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout(5,5));
pane = new JPanel(new GridLayout(5, 5));
frame.add(pane,BorderLayout.CENTER);
pane.add(rfid);
pane.add(button);
rfid.setEnabled(false);
button.setEnabled(true);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed (ActionEvent e){
layout.changeLayout(1);
}
});
}
public void setRfidEnabled() {
System.out.println("LOL");
rfid.setEnabled(true);
button.setEnabled(false);
}
}
布局变换器类别:
public class LayoutChanger {
public static void main(String[] args) {
MainGUI gui = new MainGUI();
}
public void changeLayout(int i){
if (i == 1) {
CardLayout card = new CardLayout();
}
}
}
卡片布局类:
public class CardLayout {
JFrame frame;
JButton manual;
final JPanel pane;
MainGUI gui = new MainGUI();
public CardLayout() {
manual = new JButton("UID MANUAL");
frame = new JFrame("Card Scan Panel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new BorderLayout(5, 5));
pane = new JPanel(new BorderLayout(5, 5));
manual.setPreferredSize(new Dimension(50, 25));
frame.add(pane, BorderLayout.CENTER);
pane.add(manual);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
manual.addActionListener(new ActionListener() {
@Override
public void actionPerformed (ActionEvent e){
gui.setRfidEnabled();
}
});
}
}
如@matt在上述评论中所述 每次单击manual按钮时,您都在创建一个新的MainGUI 您需要在构造函数或ActionListener中创建一个实例,并询问您是否已经拥有它的一个实例,即单例并使用它 如果决定使用第一个变量,请将gui声明为全局变量:
MainGUI gui = new MainGUI();
在您的ActionListener上,将其更改为:
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(currentThread());
gui.setRfidEnabled();
//frame.dispose();
}
然后你就有了它的一个实例
正如@Sergiy所说,你并不真的需要所有这些线程
以下是一些有关如何使用ActionListeners的示例:
这一个包括一个计时器,另一个线程处理动画,但不阻止EDT
正如您在上述所有示例中所看到的,它们都不需要另一个线程来处理操作,使用线程的线程仅用于执行动画,而不用于对用户单击做出反应
推荐教程:请提供一个可运行的示例aka,这样我们也可以重现您的错误行为并调试您的代码。请不要发布您当前的代码,而是尝试创建一个小的可运行示例来演示您的问题。如我所见,您使用线程来修改Swing小部件。这是个坏主意。所有修改必须在摆动螺纹中执行。欲了解更多信息,请阅读。您是否阅读过?当我在Swing代码中看到Thread.sleep2000时,我得到了红色警报。为什么在代码中使用线程?有必要吗?当需要在后台线程中执行某些操作时,我使用SwingWorker。但是在你的情况下,你并不需要它。为什么你要用一个单独的线程来添加一个动作监听器呢?应在EDT上添加操作侦听器。此外,当它们因操作事件而被调用时,无论您使用哪个线程添加操作侦听器,都会在EDT上发生。MainGUI=new MainGUI;创建一个新的主gui,然后在调用gui.setRfidEnabled时;如果我声明MainGUI=newmaingui为全局变量,我在线程main java.lang.StackOverflowerRory中会出现异常。您需要创建一个新程序,将其发布为,删除所有这些线程并使其尽可能简单,那么我们可以提供更好的答案。用演示您的问题的MCVE编辑您的问题。如果你有问题,可以在这里问我。但是以这个答案中链接中的所有例子为基础,这些都是MCVE,你可以复制粘贴到你的IDE中,看到相同的UI,具有相同的行为,而无需修改任何内容。你是对的,无用的线程毁掉了一切,我发布了MCVE,现在主要的问题是,手动按钮点击会带来新的整个MainGUI窗口,而启用按钮的旧窗口仍然存在,我如何才能更新现有的MainGUI窗口?阅读此答案的第一部分。这仍然不是一个问题,请正确缩进代码。现在你可以调用第二个JFrame,这个问题就解决了。如果您仍然需要帮助发布另一个问题,但一定要准备好MCVE,正如我所说,我可以在关于如何创建MCVE的具体问题中指导您,我已经解释了我们需要什么,1个单一类,新程序,而不是您当前的程序。