[英]JDialog Stops execution of parent JFrame
我有一個gif動畫圖像,顯示jDialog內的無限圓加載進度...但是問題是當我加載此jDialog時,父框架代碼停止了嗎? 怎么做..這是我的代碼..
ProgressDialouge pbDialog = new ProgressDialouge(this);
pbDialog.setVisible(true);
pbDialog.toFront();
postPairs.add(new BasicNameValuePair("PATH","authenticateUser.idoc"));
postPairs.add(new BasicNameValuePair("user_email",email));
postPairs.add(new BasicNameValuePair("user_password",password));
JSONArray jArray = asyncService.sendRequest(postPairs);
if(jArray != null){
new NewJFrame().setVisible(true);
this.setVisible(false);
}
如果我更改JDiaog的ModalityType.MODELESS,它不會停止執行代碼,但不會顯示進度條。
很可能您遇到了線程問題,即您在Swing事件線程上運行了長時間運行的任務,從而阻止了事件線程更新GUI。 解決方案是使用后台線程,例如SwingWorker提供的后台線程。
我的猜測是,令人討厭的一句話就是:
JSONArray jArray = asyncService.sendRequest(postPairs);
因此,再次在后台線程中執行此操作。 有關更多信息,請查看此鏈接: Swing中的並發
例如:
import java.awt.Point;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ShowSwingWorker {
private JPanel mainPanel = new JPanel();
private JButton myBtn = null;
private ProgressDialouge pbDialog = null;
public ShowSwingWorker() {
myBtn = new JButton(new AbstractAction("Push Me") {
@Override
public void actionPerformed(ActionEvent evt) {
JButton source = (JButton) evt.getSource();
source.setEnabled(false); // disable button
Window win = SwingUtilities.getWindowAncestor(source);
new MySwingWorker().execute(); // start background thread
if (pbDialog == null) {
pbDialog = new ProgressDialouge(win);
pbDialog.pack();
pbDialog.setLocationRelativeTo(win);
Point loc = pbDialog.getLocation();
pbDialog.setLocation(loc.x - 100, loc.y - 100);
}
pbDialog.setVisible(true);
// pbDialog.toFront();
}
});
mainPanel.add(myBtn);
}
public JComponent getMainPanel() {
return mainPanel;
}
private class MySwingWorker extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
Thread.sleep(4000); // emulate a long-running task
// postPairs.add(new BasicNameValuePair("PATH",
// "authenticateUser.idoc"));
// postPairs.add(new BasicNameValuePair("user_email", email));
// postPairs.add(new BasicNameValuePair("user_password", password));
// JSONArray jArray = asyncService.sendRequest(postPairs);
// if (jArray != null) {
// new NewJFrame().setVisible(true);
//
// this.setVisible(false);
// }
return null;
}
@Override
protected void done() {
// Here you change your display.
// you were swapping JFrames, but I recommend that you instead change views.
myBtn.setEnabled(true);
pbDialog.setVisible(false);
}
}
private class ProgressDialouge extends JDialog {
public ProgressDialouge(Window win) {
super(win, "MyDialog", ModalityType.APPLICATION_MODAL);
JProgressBar pBar = new JProgressBar();
pBar.setIndeterminate(true);
add(pBar);
}
}
private static void createAndShowGUI() {
ShowSwingWorker paintEg = new ShowSwingWorker();
JFrame frame = new JFrame("ShowSwingWorker");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
在模式對話框的情況下,行pbDialog.setVisible(true)將阻塞,直到關閉該對話框為止。 如果要打開對話框而不阻塞,則必須使其為非模態對話框。 使動畫無法正常工作的原因可能是由於編寫了同步代碼以重畫對話框。 您需要利用EventQueue定期重繪幀。 您可以使用單獨的線程,也可以使用不需要以下線程的更簡單的代碼:
public void paintComponent(Graphics g) {
if( animate ) {
Graphics2D g2d = (Graphics2D)g;
BufferedImage frame = frames[currentFrame];
g2d.drawImage(frame, null, x, y);
frame.draw( g );
currentFrame = (currentFrame + 1) % frames.length;
repaint(); // this call will schedule a repaint at some point later.
}
}
不需要線程,這在資源方面是一件好事,並且不太可能搞砸和違反swing的單線程規則。 您還可以查看:
用於在動畫gif之類的東西上執行動畫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.