Java 来自独立线程的GUI
尝试创建两个独立的forma,它们可以在不同的线程中运行代码。下面的代码创建了两个表单,但如果我按下其中一个表单上的按钮,我就无法对另一个表单执行相同的操作。它只是不执行代码。如何制作两个可以互不阻塞地运行的简单表单Java 来自独立线程的GUI,java,multithreading,swing,Java,Multithreading,Swing,尝试创建两个独立的forma,它们可以在不同的线程中运行代码。下面的代码创建了两个表单,但如果我按下其中一个表单上的按钮,我就无法对另一个表单执行相同的操作。它只是不执行代码。如何制作两个可以互不阻塞地运行的简单表单 public class MnemonicEx1 extends JFrame { public JeasiHandler jh = null; private Log log = Log.getLog(); public MnemonicEx1()
public class MnemonicEx1 extends JFrame
{
public JeasiHandler jh = null;
private Log log = Log.getLog();
public MnemonicEx1()
{
initUI();
}
private void initUI()
{
JButton btnAuth = new JButton("1");
btnAuth.addActionListener(new ActionListener()
{
// @Override
public void actionPerformed(ActionEvent e)
{
System.out.println("starting");
for (int i = 0; i < 1000; i++)
{
try
{
Thread.sleep(100);
System.out.println(Integer.toString(i));
} catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
System.out.println("finishing");
}
});
btnAuth.setMnemonic(KeyEvent.VK_B);
//createLayout(btnAuth);
createLayout(btnAuth);
setTitle("****");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void createLayout(JComponent authButn)
{
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
int i = 0;
gl.setHorizontalGroup(
gl.createSequentialGroup()
.addComponent(authButn)
);
gl.setVerticalGroup(gl.createParallelGroup()
.addComponent(authButn)
);
pack();
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
EventQueue.invokeLater(new Runnable()
{
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
}
}
@最低点或多或少是对的 您正在EventQueue表示的同一线程中启动两个窗口 我认为swing程序员更喜欢使用SwingUtilities来打开新的框架应用程序,但是改变方法可以实现您的目标
// @Override
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
System.out.println("starting");
for (int i = 0; i < 1000; i++)
{
try
{
Thread.sleep(100);
System.out.println(Integer.toString(i));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("finishing");
}
}.start();
您将它们添加到执行队列中,而不是分离线程。查看此帖子您可能希望更改
new Thread()
的EventQueue.invokeLater()
,然后使用Thread.start()
将其更改为Thread(),但得到了相同的结果。问题正文UPD中的更多详细信息。Swing是单线程的,您无法改变这一点,所有事件都被发布到事件队列并由事件调度线程处理,请参阅以获取更多详细信息,并至少查看一种可能的解决方案正如您所指出的,Swing是单线程的,但它也不是线程安全的,因此,如果要从事件调度线程的上下文之外更新UI的状态,请小心;)我早就知道了。几年前我就学会了。也许读一些你以前的答案:-)
// @Override
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
System.out.println("starting");
for (int i = 0; i < 1000; i++)
{
try
{
Thread.sleep(100);
System.out.println(Integer.toString(i));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("finishing");
}
}.start();
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
}