gpt4 book ai didi

java - 如何从操作监听器调用方法,而不会使 JFrame 卡住并等待操作监听器完成?

转载 作者:行者123 更新时间:2023-12-01 18:18:55 24 4
gpt4 key购买 nike

如何在 JFrame 运行时设置 JTextArea 的文本,并刷新 JFrame 以显示来自另一个类的更改?

我有一个带有 JTextArea 的 JFrame,它充当日志,并且它打印的字符串我会定期使用另一个类的新 Activity 进行更新。我的 JFrame 类 (EnablePage) 如下所示:

package bot;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class EnablePage extends JFrame {
public static String enablePane;
private static JPanel contentPane;
public static JTextArea txtrHello = new JTextArea();

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
EnablePage frame = new EnablePage();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public EnablePage() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 594, 474);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setToolTipText("");
scrollPane.setBounds(6, 89, 582, 357);
contentPane.add(scrollPane);
txtrHello.setEditable(false);
txtrHello.setText(enablePane);
txtrHello.setWrapStyleWord(true);
txtrHello.setLineWrap(true);
scrollPane.setViewportView(txtrHello);

JButton btnNewButton = new JButton("Enable");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
navigator.navigator();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
btnNewButton.setBounds(59, 29, 117, 29);
contentPane.add(btnNewButton);
}
public static void update(String x) {
txtrHello.setText(enablePane+"\n"+x);

}
}

在我的导航器类中,我一直在尝试使用这行代码来更新 JtextArea,同时它操纵网站。我没有包含此代码,但在此处替换为“Thread.sleep(100000);”来说明问题:

 package bot;


import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JOptionPane;

public class navigator {

public static DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy(HH:mm:ss)");
public static void navigator() throws Exception {
Date date1 = new Date();
Thread.sleep(100000);


EnablePage.update("Bot enabled: "+dateFormat.format(date1));
}
}

但是,这并没有用新文本更新 JFrame,因为 EnablePage 类一直在等待 navigator() 方法完成。最终发生的情况是“启用”按钮保持蓝色,因为 actionlistener 方法永远不会中断,因为 nagivator() 方法从未完成。我该怎么做才能仍然从启用按钮调用 navigator() 但不让 EnablePage 类卡住在这一行?

最佳答案

这是一个简单的例子。时钟 JTextField 从线程更新。

如您所见,没有更新、验证或无效方法调用。

编辑添加:对 SwingUtilities invokeLater 方法的调用非常重要,以确保在 Event Dispatch thread (EDT) 上创建和更新 Swing 组件。 .

我还修改了 Clock 示例,以便在处理 JFrame 之前彻底停止 Timer 线程。

package com.ggl.testing;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Clock implements Runnable {

private JFrame frame;

private JTextField clockDisplay;

private Timer timer;

@Override
public void run() {
frame = new JFrame("Clock");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});

JPanel panel = new JPanel();

clockDisplay = new JTextField(12);
clockDisplay.setEditable(false);
clockDisplay.setHorizontalAlignment(JTextField.CENTER);

panel.add(clockDisplay);

frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);

timer = new Timer(this);
new Thread(timer).start();
}

public void exitProcedure() {
timer.setRunning(false);
frame.dispose();
System.exit(0);
}

public void setText(String text) {
clockDisplay.setText(text);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Clock());
}

public class Timer implements Runnable {

private volatile boolean running;

private Clock clock;

private SimpleDateFormat timeFormat;

public Timer(Clock clock) {
this.clock = clock;
this.running = true;
this.timeFormat = new SimpleDateFormat("h:mm:ss a");
}

@Override
public void run() {
while (running) {
displayTime();
sleep();
}

}

public void displayTime() {
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
final String s = timeFormat.format(date);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
clock.setText(s);
}
});
}

public void sleep() {
try {
Thread.sleep(200L);
} catch (InterruptedException e) {
}
}

public synchronized void setRunning(boolean running) {
this.running = running;
}

}

}

关于java - 如何从操作监听器调用方法,而不会使 JFrame 卡住并等待操作监听器完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28129896/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com