2012-01-17 54 views
2

我想显示模式对话框,这将阻止我的主窗口,我想通过方法showLoadingDialog(),hideLoadingDialog()和setLoadingMessage(String消息) - 我想这代码,但它不工作 - 加载对话框是可见的,但没有消息如何显示忙碌/工作/加载对话框动态消息

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

public class LoadingExample { 


private static class LoadingDialog extends JDialog { 

private JLabel label = new JLabel("working"); 

public LoadingDialog(JFrame owner) { 

    super(owner, ModalityType.APPLICATION_MODAL); 

    setUndecorated(true); 
    add(label); 
    pack(); 

    // move window to center of owner 
    int x = owner.getX() 
     + (owner.getWidth() - getPreferredSize().width)/2; 
    int y = owner.getY() 
     + (owner.getHeight() - getPreferredSize().height)/2; 
    setLocation(x, y); 



    repaint(); 


} 

public void setMessage(String message) { 
    label.setText(message); 
} 


} 



private static LoadingDialog loadingDialog; 


public static void main(String[] args) { 


final JFrame mainWindow = new JFrame("Main frame"); 
mainWindow.setLayout(new GridLayout(3, 3)); 


for (int i = 1; i <= 9; i++) { 

    final int workTime = i; 

    JButton workButton = new JButton("work for " + i + " second"); 

    //action listener, which had to show loading dialog and countdown seconds before finish 
    workButton.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     showLoadingDialog(mainWindow); 

     for (int j = 0; j < workTime; j++) 
     try { 

      // ... do some work here 

      setLoadingMessage("remain " + (workTime - j) 
       + " second(s)"); 
      loadingDialog.repaint(); 
      Thread.sleep(1000); 
     } catch (InterruptedException e1) { 
      e1.printStackTrace(); 
     } 

     hideLoadingDialog(); 
    } 
    }); 


    mainWindow.add(workButton); 

} 

mainWindow.pack(); 
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
mainWindow.setLocationRelativeTo(null); 



mainWindow.setVisible(true); 

} 




public static void showLoadingDialog(JFrame owner) { 
if (loadingDialog != null) 
    loadingDialog.dispose(); 



loadingDialog = new LoadingDialog(owner); 

new Thread() { 
    @Override 
    public void run() { 
    loadingDialog.setVisible(true); 
    }; 
}.start(); 

} 

public static void setLoadingMessage(String message) { 
loadingDialog.setMessage(message); 
} 


public static void hideLoadingDialog() { 

if (loadingDialog != null) { 
    loadingDialog.setVisible(false); 
    loadingDialog.dispose(); 
    loadingDialog = null; 
} 


} 

} 

感谢您的任何建议

+4

“*我试过这个代码,但它不工作*” - 什么不工作?你可以使用一个'SwingWorker'来在后台执行任务,然后更新GUI(即消息和可能的进度条)以反映其进度。 – mre 2012-01-17 14:05:33

+2

阅读http://docs.oracle.com/javase/tutorial/uiswing/concurrency/ – 2012-01-17 14:20:40

+0

如果我得到它的权利,SwingWorker可以帮助我在后台做任务,但我想在工作期间阻止用户界面,因为其他部分的应用程序。或者你是否建议使用SwingWorker来显示LoadingDialog?那么怎么看这些方法的方法showLoadingDialog(),hideLoadingDialog()和setLoadingMessage(String message)?谢谢:) – user1154034 2012-01-17 14:45:56

回答

0

无法从不同的线程比进行更改GUI与您试图更改的控件关联的调度程序线程。要做到这一点正确,您可以使用SwingUtilities.InvokeLater

new Thread() { 
    @Override 
    public void run() { 

     SwingUtilities.InvokeLater(new Runnable() { 
      public void run() { 
       loadingDialog.setVisible(true); 
      } 
     }); 

    }; 
}.start(); 
0

我想写一些示例代码,但我没有在优秀Swing concurrency tutorial一个小的搜索,不料烧了我的IDE之前,它究竟包含示例代码,您是寻找。你有什么是'task that has interim results'。所以当你有中间结果时,你可以调用SwingWorker#publish方法。在SwingWorker#process方法中,使用刚刚发布的新消息更新模态对话框。 SwingWorker#done方法允许您在之后删除模态对话框。

但是我建议您从头到尾阅读整个并发教程,因为示例代码显示您缺少一些基本的Swing线程知识。