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

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

Java swing doInBackground, stopping program, and update GUI

问题

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

我是新手使用Java Swing,需要创建一些简单的Java桌面应用程序。
我有一个MainPanel,在其中有一个SwingWorker,其中有一个doInBackground方法,在其中调用了一个调用DAO的服务,该服务从数据库中查询数据。我还有一个停止按钮,单击该按钮会设置worker.cancel(true),但程序不会停止,甚至无法通过X按钮关闭窗口。
我猜测处理不会立即停止,因为数据库查询尚未结束,但为什么我不能关闭窗口?

这是代码:

worker = new SwingWorker() {

    @Override
    protected Object doInBackground() throws Exception {

        long startTime = System.nanoTime();
        textArea.append("Starting...\n");

        generatingFilesService.generateFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
                date1, date2);

        long endTime = System.nanoTime();
        double time = (double) ((endTime - startTime) / 1_000_000_000);
        if (ConnectionDBFirst.flag != false) {
            if (time < 60d) {
                textArea.append("Generating ended for " + time + " seconds\n");
                textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
            } else {
                textArea.append("Generating ended for " + (time / 60) + " minutes\n");
                textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
            }
        }
        return null;
    }		

    @Override
    protected void done() {
        if (isCancelled()) {
            textArea.append("Stopping generating files...\n");
            closeConnections();
            logger.info(Messages.PROCESS_INTERRUPTED);
        } else 
            closeConnections();
    }
};
worker.execute();

停止代码:

if (e.getSource() == stop) {

        worker.cancel(true);

        stop.setEnabled(false);
}

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:

worker = new SwingWorker() {

			@Override
			protected Object doInBackground() throws Exception {

				long startTime = System.nanoTime();
				textArea.append(&quot;Starting...\n&quot;);

				generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
						date1, date2);
	
				long endTime = System.nanoTime();
				double time = (double) ((endTime - startTime) / 1_000_000_000);
				if (ConnectionDBFirst.flag != false) {
					if (time &lt; 60d) {
						textArea.append(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
						textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
					} else {
						textArea.append(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
						textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
					}
				}
				return null;
			}		
			
			@Override
			protected void done() {
				if (isCancelled()) {
					textArea.append(&quot;Stopping generating files...\n&quot;);
					closeConnections();
					logger.info(Messages.PROCCESS_INTERUPTED);
				} else 
					closeConnections();
			}
		};worker.execute();

Stopping code:

if (e.getSource() == stop) {

		worker.cancel(true);

		stop.setEnabled(false);}

UPDATE:

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

public void genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
                        date1, date2) {

	List&lt;Person&gt; persons1 = daoFirst.getPersons(connectionDBFirst, date1, date2);
		
	//here i want to update the textArea() that the daoFirst.getPersons() is done
	//but how to that without MainPanel.textArea.append(...);
	
	List&lt;Person&gt; persons2 = daoSecond.getPersons(connectionDBSecond, date1, date2);
	
	//here i want to update the textArea() that the daoSecond.getPersons() is done
	//but how to that without MainPanel.textArea.append(...);
	
	//same with daoThird

	genereteFilesService.createFiles(persons1, persons2, persons3);

	//update textArea() again

}

DAO code:

public List&lt;Person&gt; getPersons(connectionDBFirst, date1, date2) {

	//executeing sql query and geting the Persons
	//this takes long time, and from here I calculate 
	//percentage of persons fetched and I want to show the prcentage in textArea()
	//but how to do that without MainPanel.textArea.append(...);
}

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):


	@Override
	protected Object doInBackground() throws Exception {
		long startTime = System.nanoTime();
		
		// textArea.append(&quot;Starting...\n&quot;);
		publish(&quot;Starting...\n&quot;);
		
		generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird, date1, date2);
		long endTime = System.nanoTime();
		double time = (double) ((endTime - startTime) / 1_000_000_000);
		if (ConnectionDBFirst.flag != false) {
			if (time &lt; 60d) {
				// textArea.append(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
				// textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
				publish(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
			} else {
				// textArea.append(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
				// textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
				publish(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
			}
		}
		return null;
	}       

	@Override
	protected void process(List&lt;String&gt; chunks) {
		for (String chunk : chunks) {
			textArea.append(chunk);
			textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
		}
	}

// ....
}
worker.execute();
英文:

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

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):

worker = new SwingWorker&lt;Void, String&gt;() {

	@Override
	protected Object doInBackground() throws Exception {
		long startTime = System.nanoTime();
		
		// textArea.append(&quot;Starting...\n&quot;);
		publish(&quot;Starting...\n&quot;);
		
		generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird, date1, date2);
		long endTime = System.nanoTime();
		double time = (double) ((endTime - startTime) / 1_000_000_000);
		if (ConnectionDBFirst.flag != false) {
			if (time &lt; 60d) {
				// textArea.append(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
				// textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
				publish(&quot;Genereting ended for &quot; + time + &quot; seconds\n&quot;);
			} else {
				// textArea.append(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
				// textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
				publish(&quot;Genereting ended for &quot; + (time / 60) + &quot; minutes\n&quot;);
			}
		}
		return null;
	}       

	@Override
	protected void process(List&lt;String&gt; chunks) {
		for (String chunk : chunks) {
			textArea.append(chunk);
			textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
		}
	}

// ....
}
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:

确定