Java swing doInBackground,停止程序,和更新GUI

huangapple go评论117阅读模式
英文:

Java swing doInBackground, stopping program, and update GUI

问题

Here's the translated code parts without the code sections:

  1. 我是新手使用Java Swing,需要创建一些简单的Java桌面应用程序。
  2. 我有一个MainPanel,在其中有一个SwingWorker,其中有一个doInBackground方法,在其中调用了一个调用DAO的服务,该服务从数据库中查询数据。我还有一个停止按钮,单击该按钮会设置worker.cancel(true),但程序不会停止,甚至无法通过X按钮关闭窗口。
  3. 我猜测处理不会立即停止,因为数据库查询尚未结束,但为什么我不能关闭窗口?
  4. 这是代码:
  5. worker = new SwingWorker() {
  6. @Override
  7. protected Object doInBackground() throws Exception {
  8. long startTime = System.nanoTime();
  9. textArea.append("Starting...\n");
  10. generatingFilesService.generateFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
  11. date1, date2);
  12. long endTime = System.nanoTime();
  13. double time = (double) ((endTime - startTime) / 1_000_000_000);
  14. if (ConnectionDBFirst.flag != false) {
  15. if (time < 60d) {
  16. textArea.append("Generating ended for " + time + " seconds\n");
  17. textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  18. } else {
  19. textArea.append("Generating ended for " + (time / 60) + " minutes\n");
  20. textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  21. }
  22. }
  23. return null;
  24. }
  25. @Override
  26. protected void done() {
  27. if (isCancelled()) {
  28. textArea.append("Stopping generating files...\n");
  29. closeConnections();
  30. logger.info(Messages.PROCESS_INTERRUPTED);
  31. } else
  32. closeConnections();
  33. }
  34. };
  35. worker.execute();
  36. 停止代码:
  37. if (e.getSource() == stop) {
  38. worker.cancel(true);
  39. stop.setEnabled(false);
  40. }

If you have more specific questions or need further assistance with this code, please feel free to ask.

英文:

I'm new to java Swing, and I need to make some simple Java desktop app.
I have MainPanel in which I have SwingWorker with doInBackgroung in which I call service which calls a DAO that make a quering data from database. I also have a stop button which on click set worker.cancel(true), but the program is not stopping and I can not even close the window with X button.
I suppose that the proccessing is not stoped imidietly because the querying to database is not ended yet, but why cant I close the window?

This is the code:

  1. worker = new SwingWorker() {
  2. @Override
  3. protected Object doInBackground() throws Exception {
  4. long startTime = System.nanoTime();
  5. textArea.append(&quot;Starting...\n&quot;);
  6. generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
  7. date1, date2);
  8. long endTime = System.nanoTime();
  9. double time = (double) ((endTime - startTime) / 1_000_000_000);
  10. if (ConnectionDBFirst.flag != false) {
  11. if (time &lt; 60d) {
  12. textArea.append(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
  13. textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  14. } else {
  15. textArea.append(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
  16. textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  17. }
  18. }
  19. return null;
  20. }
  21. @Override
  22. protected void done() {
  23. if (isCancelled()) {
  24. textArea.append(&quot;Stopping generating files...\n&quot;);
  25. closeConnections();
  26. logger.info(Messages.PROCCESS_INTERUPTED);
  27. } else
  28. closeConnections();
  29. }
  30. };worker.execute();

Stopping code:

  1. if (e.getSource() == stop) {
  2. worker.cancel(true);
  3. stop.setEnabled(false);}

UPDATE:

Based on the answer and comments, here is the rest of the code:

  1. public void genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
  2. date1, date2) {
  3. List&lt;Person&gt; persons1 = daoFirst.getPersons(connectionDBFirst, date1, date2);
  4. //here i want to update the textArea() that the daoFirst.getPersons() is done
  5. //but how to that without MainPanel.textArea.append(...);
  6. List&lt;Person&gt; persons2 = daoSecond.getPersons(connectionDBSecond, date1, date2);
  7. //here i want to update the textArea() that the daoSecond.getPersons() is done
  8. //but how to that without MainPanel.textArea.append(...);
  9. //same with daoThird
  10. genereteFilesService.createFiles(persons1, persons2, persons3);
  11. //update textArea() again
  12. }

DAO code:

  1. public List&lt;Person&gt; getPersons(connectionDBFirst, date1, date2) {
  2. //executeing sql query and geting the Persons
  3. //this takes long time, and from here I calculate
  4. //percentage of persons fetched and I want to show the prcentage in textArea()
  5. //but how to do that without MainPanel.textArea.append(...);
  6. }

Now, beside initial question, how can I use publish() and proccess() methods to update the textArea() from generateFiles() and DAO methods?

答案1

得分: 1

You're making Swing mutational calls from within the doInBackground method:

And this breaks the threading rules and your program.

The solution is to not do this, and instead to publish the data that needs to be displayed and then process the information that was published via the publish/process method pair of the SwingWorker.

e.g., (code not tested):

  1. @Override
  2. protected Object doInBackground() throws Exception {
  3. long startTime = System.nanoTime();
  4. // textArea.append(&quot;Starting...\n&quot;);
  5. publish(&quot;Starting...\n&quot;);
  6. generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird, date1, date2);
  7. long endTime = System.nanoTime();
  8. double time = (double) ((endTime - startTime) / 1_000_000_000);
  9. if (ConnectionDBFirst.flag != false) {
  10. if (time &lt; 60d) {
  11. // textArea.append(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
  12. // textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  13. publish(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
  14. } else {
  15. // textArea.append(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
  16. // textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  17. publish(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
  18. }
  19. }
  20. return null;
  21. }
  22. @Override
  23. protected void process(List&lt;String&gt; chunks) {
  24. for (String chunk : chunks) {
  25. textArea.append(chunk);
  26. textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  27. }
  28. }
  29. // ....
  30. }
  31. worker.execute();
英文:

You're making Swing mutational calls from within the doInBackground method:

  1. textArea.append(...);

And this breaks the threading rules and your program.

The solution is to not do this, and instead to publish the data that needs to be displayed and then process the information that was published via the publish/process method pair of the SwingWorker.

e.g., (code not tested):

  1. worker = new SwingWorker&lt;Void, String&gt;() {
  2. @Override
  3. protected Object doInBackground() throws Exception {
  4. long startTime = System.nanoTime();
  5. // textArea.append(&quot;Starting...\n&quot;);
  6. publish(&quot;Starting...\n&quot;);
  7. generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird, date1, date2);
  8. long endTime = System.nanoTime();
  9. double time = (double) ((endTime - startTime) / 1_000_000_000);
  10. if (ConnectionDBFirst.flag != false) {
  11. if (time &lt; 60d) {
  12. // textArea.append(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
  13. // textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  14. publish(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
  15. } else {
  16. // textArea.append(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
  17. // textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  18. publish(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
  19. }
  20. }
  21. return null;
  22. }
  23. @Override
  24. protected void process(List&lt;String&gt; chunks) {
  25. for (String chunk : chunks) {
  26. textArea.append(chunk);
  27. textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
  28. }
  29. }
  30. // ....
  31. }
  32. worker.execute();

huangapple
  • 本文由 发表于 2023年4月13日 19:17:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76004791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定