Java 如果for循环在EDT内完成,GUI将被卡住
我有以下代码:Java 如果for循环在EDT内完成,GUI将被卡住,java,multithreading,user-interface,Java,Multithreading,User Interface,我有以下代码: Thread T=new Thread(new Runnable(){ public void run(){ SwingUtilities.invokeLater(new Runnable(){ public void run(){ for (int i=0;i<18;i++){ int percent=(int)(((i+1)*100)/18);
Thread T=new Thread(new Runnable(){
public void run(){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
for (int i=0;i<18;i++){
int percent=(int)(((i+1)*100)/18);
try {
lblNewLabel.setText("Loading... ("+percent+"%)");
Thread.sleep(1000);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
});
它将被调用18次。这是一个好方法吗?或者最好不要多次调用invokeLater方法
感谢您以下作品:
public class UIThreadTest {
private JFrame mainFrame;
private JLabel labelStatus;
private JButton buttonProcess;
public static void main(String[] args) {
final UIThreadTest ui = new UIThreadTest();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ui.initGUI();
}
});
}
public void initGUI() {
mainFrame = new JFrame("View");
mainFrame.getContentPane().setLayout(new BorderLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(200, 200);
mainFrame.setVisible(true);
mainFrame.setLocationRelativeTo(null);
labelStatus = new JLabel("Status...");
mainFrame.getContentPane().add(labelStatus, BorderLayout.NORTH);
buttonProcess = new JButton("Start");
buttonProcess.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Runnable startLoop = new StartLoop();
Thread startLoopThread = new Thread(startLoop);
startLoopThread.start();
}
});
mainFrame.getContentPane().add(buttonProcess, BorderLayout.SOUTH);
}
private void updateStatus(final int val) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
labelStatus.setText("Loading... (" + val + "%)");
}
});
}
private void runForLoop() {
for (int i = 0; i < 18; i++) {
int percent = (int) (((i + 1) * 100) / 18);
updateStatus(percent);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private class StartLoop implements Runnable {
@Override
public void run() {
runForLoop();
}
}
}
公共类UIThreadTest{
专用JFrame主机;
私人JLabel labelStatus;
私有JButton按钮进程;
公共静态void main(字符串[]args){
最终UIThreadTest ui=新UIThreadTest();
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
ui.initGUI();
}
});
}
public void initGUI(){
大型机=新JFrame(“视图”);
mainFrame.getContentPane().setLayout(新的BorderLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
大型机。设置大小(200200);
mainFrame.setVisible(true);
mainFrame.setLocationRelativeTo(空);
labelStatus=新的JLabel(“状态…”);
mainFrame.getContentPane().add(labelStatus,BorderLayout.NORTH);
buttonProcess=新按钮(“开始”);
buttonProcess.addActionListener(新建ActionListener()){
@凌驾
已执行的公共无效操作(操作事件e){
Runnable startoop=新的startoop();
线程startOOP线程=新线程(startOOP);
startoopthread.start();
}
});
mainFrame.getContentPane().add(按钮进程,BorderLayout.SOUTH);
}
私有void updateStatus(最终int val){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
setText(“加载…(“+val+”)”);
}
});
}
私有void runForLoop(){
对于(int i=0;i<18;i++){
整数百分比=(整数)((i+1)*100)/18);
更新状态(百分比);
试一试{
睡眠(1000L);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
私有类startoop实现了Runnable{
@凌驾
公开募捐{
runForLoop();
}
}
}
非常感谢您的帮助,我也很接近这个解决方案。。然而。。给invokeLater打这么多次电话是个好主意吗?这会是低效的吗?或者这样做是个好主意?在这段代码中,它被调用了18次……我认为它和调用任何其他方法18次一样好。invokeLater文档说:“导致在AWT事件调度线程上异步执行doRun.run()。这将在处理所有挂起的AWT事件后发生。“为什么您认为这可能是低效的。”此外,我们没有阻止EDT。您可能还认为您似乎使用了EDT
标记来执行”“事件调度线程”但这并不是它的实际用途。看一看。我编辑以将其从这个问题中删除(在审阅后将可见)。对不起,我不知道。
public class UIThreadTest {
private JFrame mainFrame;
private JLabel labelStatus;
private JButton buttonProcess;
public static void main(String[] args) {
final UIThreadTest ui = new UIThreadTest();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ui.initGUI();
}
});
}
public void initGUI() {
mainFrame = new JFrame("View");
mainFrame.getContentPane().setLayout(new BorderLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(200, 200);
mainFrame.setVisible(true);
mainFrame.setLocationRelativeTo(null);
labelStatus = new JLabel("Status...");
mainFrame.getContentPane().add(labelStatus, BorderLayout.NORTH);
buttonProcess = new JButton("Start");
buttonProcess.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Runnable startLoop = new StartLoop();
Thread startLoopThread = new Thread(startLoop);
startLoopThread.start();
}
});
mainFrame.getContentPane().add(buttonProcess, BorderLayout.SOUTH);
}
private void updateStatus(final int val) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
labelStatus.setText("Loading... (" + val + "%)");
}
});
}
private void runForLoop() {
for (int i = 0; i < 18; i++) {
int percent = (int) (((i + 1) * 100) / 18);
updateStatus(percent);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private class StartLoop implements Runnable {
@Override
public void run() {
runForLoop();
}
}
}