参考java.util.concurrent包和Future接口,我注意到(除非我弄错了)启动冗长任务并能够查询进度的能力仅来自SwingWorker实现类.
这引出了以下问题:
有没有办法,在非GUI,非Swing应用程序(映像控制台应用程序)中在后台启动冗长的任务,并允许其他线程检查进度?在我看来,没有理由将此功能限制在swing/GUI应用程序中.否则,我看到的唯一可用选项是通过ExecutorService :: submit返回Future对象.但是,基本Future接口不允许监视进度.
说我有以下代码:
import java.lang.InterruptedException;
import javax.swing.SwingWorker;
public class Test
{
private JDialog window;
public Test
{
// instantiate window
}
private class Task extends SwingWorker<Void, Void>
{
public Void doInBackground()
{
try { Thread.currentThread().sleep(5000); }
catch(InterruptedException e) {}
return null;
}
}
public void doTask()
{
Task task = new Task();
task.execute();
}
protected void process()
{
// update various GUI components here
}
public static void main(String args[])
{
Test t = new Test();
t.doTask();
System.out.println("done");
}
}
Run Code Online (Sandbox Code Playgroud)
我需要等到t.doTask() …
我有两个SwingWorker类:FileLineCounterThread和FileDivisionThread
我将执行两个线程.当计数线程完成时,它会将结果传递给File Division线程.
我不知道如何将结果传递给已启动的线程.
我正在尝试获得一个进度条以准确反映我的SwingWorker.但我真的无法弄清楚该怎么做.我得到了一个静态动画,直到操作完成,但我想要一个真正的活动栏.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package frglauncher;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
/**
*
* @author KYLE-LAPTOP
*/
class DownloadWorker extends SwingWorker<String, Object> {
private String game;
private JProgressBar bar;
private JLabel label;
public …Run Code Online (Sandbox Code Playgroud) 我用来通过更新ProgressBar来监视长时间运行的任务.长时间运行的任务当然是在Swingworker线程中执行的.
我曾经编程过这样的事情:
public class MySwingWorkerClass extends SwingWorker<Void, Void> {
private JProgressBar progressBar;
public MySwingWorker(JProgressBar aProgressBar) {
this.progressBar = aProgressBar;
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setValue(0);
}
@Override
public Void doInBackground() {
//long running task
loop {
calculation();
progressBar.setValue(value);
}
return null;
}
@Override
public void done() {
progressBar.setValue(100);
progressBar.setStringPainted(false);
progressBar.setVisible(false);
}
}
Run Code Online (Sandbox Code Playgroud)
但最近我发现我可以通过使用"setProgress"并定义属性更改并执行类似的操作来实现
public class MySwingWorkerClass extends SwingWorker<Void, Void> {
private JProgressBar progressBar;
public MySwingWorker(JProgressBar aProgressBar) {
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer) evt.getNewValue());
}
}
}); …Run Code Online (Sandbox Code Playgroud) 我有一个swing应用程序,它存储一个对象列表.当用户点击按钮时
我想对列表中的每个对象执行两个操作,然后一旦完成,将结果绘制在JPanel中.我一直在尝试使用SwingWorker,Callable和Runnable进行处理,但无论我做什么,在处理列表时(可能需要几分钟,因为它是IO绑定的),GUI被锁定.
我有一种感觉,这可能是我调用线程或其他东西的方式,还是可能与图形函数有关?这不是线程,因为它非常快.
我必须按顺序完成两个处理阶段,那么确保第二个阶段在第一个阶段等待的最佳方法是什么?我已经使用了join(),然后
while(x.isAlive())
{
Thread.sleep(1000);
}
Run Code Online (Sandbox Code Playgroud)
尝试确保这一点,但我担心这也可能是我的问题的原因.
我一直在寻找一些指针,但由于我找不到任何东西,我确信我在这里做了些蠢事.
我正在为控制台应用程序实现GUI,我需要在指定的时间间隔内执行一些操作(例如,解析XML文件).我决定使用javax.swing.Timer和SwingWorker来确保这些操作不会使我的应用程序无响应.
我用这种方式实现了计时器:
public class DataUpdateTimer extends Timer {
private String dataFlowControllerXML = null;
private DataUpdateWorker dataUpdateWorker = null;
public class DataUpdateWorker extends SwingWorker {
private String dataFlowControllerXML = null;
DataUpdateWorker(String dataFlowControllerXML) {
super();
this.dataFlowControllerXML = dataFlowControllerXML;
}
@Override
protected Boolean doInBackground() throws Exception {
Thread.sleep(300);
return Boolean.TRUE;
}
}
public class DataUpdateIntervalListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
DataUpdateTimer timer = (DataUpdateTimer)e.getSource();
DataUpdateWorker dataUpdateWorker = timer.getDataUpdateWorker();
if (dataUpdateWorker != null)
if (dataUpdateWorker.isDone()) {
Boolean updateResult = Boolean.FALSE;
try …Run Code Online (Sandbox Code Playgroud) 我的电脑有4个内核,我正在运行Java swing gui程序.当我运行我的应用程序时,它只使用两个内核和大约30%的CPU利用率.我有大量要处理的文件,并希望将它们分成两个线程,以便使用更多的cpu更快地完成此任务.
我有一个名为PrepareTask的SwingWorker类,它有一个带有两个int的构造函数:
class PrepareTask extends SwingWorker<Void, Void> {
int start, end;
PrepareTask (int start, int end) { ... }
...
public Void doInBackground() {... }
public void done() { ... }
Run Code Online (Sandbox Code Playgroud)
我创建了两个这样的实例:
PrepareTask prepareTask = new PrepareTask(0,numberOfFiles/2);
prepareTask.execute();
PrepareTask prepareTask2 = new PrepareTask(numberOfFiles/2, numberOfFiles);
prepareTask2.execute();
Run Code Online (Sandbox Code Playgroud)
两者都启动(看起来)但是当它运行时我可以看到(打印stmts)第一个准备必须完成(在第二个开始之前打印内部).CPU利用率与以前相同,约为30%.它们当然都从同一个源中获取数据,即DefaultTableModel.
关于如何做到这一点或我做错了什么的想法?谢谢.
WatchService听起来像一个令人兴奋的想法...不幸的是,它似乎与教程/ api plus中警告的低水平并不真正适合Swing事件模型(或者我错过了一些明显的,非零概率
从教程中的 WatchDir 示例中获取代码(只是为了处理单个目录),我基本上结束了
通过使用已删除/创建的文件作为newValue触发propertyChangeEvents来处理块
@SuppressWarnings("unchecked")
public class FileWorker extends SwingWorker<Void, WatchEvent<Path>> {
public static final String DELETED = "deletedFile";
public static final String CREATED = "createdFile";
private Path directory;
private WatchService watcher;
public FileWorker(File file) throws IOException {
directory = file.toPath();
watcher = FileSystems.getDefault().newWatchService();
directory.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
}
@Override
protected Void doInBackground() throws Exception {
for (;;) {
// wait for key to be signalled
WatchKey key;
try {
key = …Run Code Online (Sandbox Code Playgroud)请考虑以下代码片段:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class TestApplet extends JApplet
{
@Override
public void init()
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
createGUI();
}
});
}
catch(InterruptedException | InvocationTargetException ex)
{
}
}
private void createGUI()
{
getContentPane().setLayout(new FlowLayout());
JButton startButton = new JButton("Do work");
startButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
JLabel label = new JLabel();
new Worker(label).execute();
}
});
getContentPane().add(startButton);
}
private class Worker extends SwingWorker<Void, …Run Code Online (Sandbox Code Playgroud) java ×10
swingworker ×10
swing ×8
concurrency ×2
file-io ×1
future ×1
jprogressbar ×1
nio ×1
progress ×1
progress-bar ×1
wait ×1
watchservice ×1