gpt4 book ai didi

java - 使用 SwingWorker java 在线程池中等待任务

转载 作者:行者123 更新时间:2023-12-03 12:45:26 25 4
gpt4 key购买 nike

我在一个线程内模拟多个任务 - 当所有任务都应该向 GUI 报告时。所以我有一个独特的表单,里面有 4 个面板,它们应该回复并执行不同的任务.. 他们每个人都应该继续汇集一个数据库并向 GUI 报告内容。在此示例中,我只是将数字写入文本区域。

public class FormMain extends JFrame {
private JButton btnStart;
private JPanel _panelTop, _panelMid, _panelBot;

private PanelFoo panelFooA, panelFooB, panelFooC, panelFooD;

private final List<String> ugsRj = Arrays.asList("AB");
private final List<String> ugsMg = Arrays.asList("CD", "EF");
private final List<String> ugsBA = Arrays.asList("GH", "IJ", "KL");
private final List<String> ugsPE = Arrays.asList("MN", "OP", "RS", "TU");

private void initialize() {
this._panelTop = new JPanel();
this._panelMid = new JPanel();
this._panelBot = new JPanel();

this.btnStart = new JButton("Start");
this._panelBot.add(this.btnStart);

this.panelFooA = new PanelFoo(this.ugsRj);
this.panelFooB = new PanelFoo(this.ugsMg);
this.panelFooC = new PanelFoo(this.ugsBA);
this.panelFooD = new PanelFoo(this.ugsPE);
_panelMid.setLayout(new BoxLayout(_panelMid, BoxLayout.X_AXIS));

this._panelMid.add(this.panelFooA);
this._panelMid.add(this.panelFooB);
this._panelMid.add(this.panelFooC);
this._panelMid.add(this.panelFooD);

}

public FormMain() {
initialize();
getContentPane().setLayout(new BorderLayout());
setSize(800, 516);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(this._panelTop, BorderLayout.NORTH);
getContentPane().add(this._panelMid, BorderLayout.CENTER);
getContentPane().add(this._panelBot, BorderLayout.SOUTH);

this.btnStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final AuthenticationUser auth = new AuthenticationUser();
auth.setUser("test");
auth.setPassword("p@ss");
//
final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
final WorkerDoSomething w1 = new WorkerDoSomething(panelFooA);
w1.addPropertyChangeListener(new ProgressListener(panelFooA.getProgressBar()));
final WorkerDoSomething w2 = new WorkerDoSomething(panelFooB);
w2.addPropertyChangeListener(new ProgressListener(panelFooB.getProgressBar()));
final WorkerDoSomething w3 = new WorkerDoSomething(panelFooC);
w3.addPropertyChangeListener(new ProgressListener(panelFooC.getProgressBar()));
final WorkerDoSomething w4 = new WorkerDoSomething(panelFooD);
w4.addPropertyChangeListener(new ProgressListener(panelFooD.getProgressBar()));

w1.execute();
w2.execute();
w3.execute();
w4.execute();

return null;
}

};
worker.execute();
}
});

}
}

public class ProgressListener implements PropertyChangeListener {
private JProgressBar bar;

ProgressListener() {
}

ProgressListener(final JProgressBar b) {
this.bar = b;
this.bar.setValue(0);
}

@Override
public void propertyChange(final PropertyChangeEvent evt) {
// Determine whether the property is progress type
if ("progress".equals(evt.getPropertyName())) {
this.bar.setValue((int) evt.getNewValue());
}
}
}

public class PanelFoo extends JPanel {

/**
*
*/
private static final long serialVersionUID = -1400188281877395934L;
private JLabel label;
private JTextArea textArea;
private JScrollPane scrollPanel;
private JProgressBar progressBar;

public PanelFoo(final List<String> listOfStates) {
setLayout(new FlowLayout());
setSize(180, 400);
final ImageIcon icon = createImageIcon("/images/waiting-list.png", "waiting start");
this.label = new JLabel(listOfStates.get(0), icon, SwingConstants.HORIZONTAL);
add(this.label);

this.textArea = new JTextArea("Numbers: \n");
this.textArea.setWrapStyleWord(true);
this.scrollPanel = new JScrollPane(this.textArea);
this.scrollPanel.setPreferredSize(new Dimension(150, 350));

this.progressBar = new JProgressBar(0, 100);

add(this.scrollPanel);
add(this.progressBar);

setVisible(true);
}

/** Returns an ImageIcon, or null if the path was invalid. */
public ImageIcon createImageIcon(final String path, final String description) {
if (path != null) {
ImageIcon imageIcon = new ImageIcon(getClass().getResource(path));
final Image image = imageIcon.getImage();
final Image newimg = image.getScaledInstance(30, 30, Image.SCALE_SMOOTH);
imageIcon = new ImageIcon(newimg, description);
return imageIcon;

} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}

public final JLabel getLabel() {
return this.label;
}

public final void setLabel(final JLabel label) {
this.label = label;
}

public final JTextArea getTextArea() {
return this.textArea;
}

public final void setTextArea(final JTextArea textArea) {
this.textArea = textArea;
}

public final JProgressBar getProgressBar() {
return this.progressBar;
}

public final void setProgressBar(final JProgressBar progressBar) {
this.progressBar = progressBar;
}

}

public class WorkerDoSomething extends SwingWorker<Void, Void> {

private JTextArea txtArea;
private JLabel label;
private Random r = new Random();

WorkerDoSomething() {
}

public WorkerDoSomething(final PanelFoo panelFooInstance) {
this.txtArea = panelFooInstance.getTextArea();
this.label = panelFooInstance.getLabel();
}

private Integer randomInt(final int min, final int max) {
final Integer randomNumber = this.r.nextInt((max - min) + 1) + min;

return randomNumber;
}

@Override
protected Void doInBackground() throws Exception {
final Integer randomNumber = randomInt(10000000, 1000000000);
long j;
int progress = 0;
final int onePerCent = randomNumber / 100;
final int onePerMillion = onePerCent / 10;
for (j = 0; j <= randomNumber; j++) {
if (j % onePerCent == 0) {
progress = (int) j / onePerCent;
setProgress(progress);
}
if (j % onePerMillion == 0) {
publish(j);
}
//Thread.sleep(randomInt(1000, 5000));
}


return null;
}

private void publish(final long num) {
this.txtArea.append(num + "\n");
this.txtArea.setCaretPosition(this.txtArea.getDocument().getLength());
}

}

毕竟这是主要的 GUI:

Main Gui

这是执行:

Running without sleep

我只需要在每个 WorkerDoSomething 的任务上等待一段时间,添加该行(之前注释掉):Thread.sleep(randomInt(1000, 5000));

但是当我这样做时.. 整个执行会卡住,当然..因为它使用单个线程来运行所有任务 - 我想。

Running with sleep

有解决办法吗?

哦...业务上得用java 1.8:

java version "1.8.0_251"
Java(TM) SE Runtime Environment (build 1.8.0_251-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.251-b08, mixed mode)

整个项目在我个人git

---首先使用调试视角进行编辑

debug

最佳答案

执行不会卡住,因为 Swing 使用 10 个线程的线程池来运行 worker。
如果您注释掉这部分,您可以看到它正常工作:

if (j % onePerMillion == 0) {
publish(j);
}

PS - 为什么要在 actionPerformed 方法中创建一个新的 SwingWorker?
为什么不简单地这样写:

    this.btnStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final WorkerDoSomething w1 = new WorkerDoSomething(panelFooA);
w1.addPropertyChangeListener(new ProgressListener(panelFooA.getProgressBar()));
final WorkerDoSomething w2 = new WorkerDoSomething(panelFooB);
w2.addPropertyChangeListener(new ProgressListener(panelFooB.getProgressBar()));
final WorkerDoSomething w3 = new WorkerDoSomething(panelFooC);
w3.addPropertyChangeListener(new ProgressListener(panelFooC.getProgressBar()));
final WorkerDoSomething w4 = new WorkerDoSomething(panelFooD);
w4.addPropertyChangeListener(new ProgressListener(panelFooD.getProgressBar()));

w1.execute();
w2.execute();
w3.execute();
w4.execute();
}
});

关于java - 使用 SwingWorker java 在线程池中等待任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63970091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com