我正在尝试实现JprogressBar来显示数据插入进度。 基本上,用户选择将数据源导入数据库的数量。 使用此参数,主程序启动一个列出这些参数的方法,并使用foreach循环调用插入线程和ProgressBar更新线程。
connect-distributed.sh
线程有点自己工作,但结果不是我想要的,导致数据被导入并且进度条正在更新,但是在导入所有数据后它正在更新到100%。只要导入线程完成每个(Maquina i)对象的导入,我就需要更新进度条。
如果有必要,我可以提供线程代码......但我不知道这种调用方法是否可以提供我想要的结果。在论坛上搜索我发现了一些关于EDT的东西,我认为这个问题没有被更新。你能帮助我解决这个问题吗?
最小和可验证的例子: 我的代码很短。 netbeans生成的代码是巨大的,sry为此。
该代码模拟了我的问题。只有在for循环结束后才会刷新窗口。但是BarraDeProgresso线程和SysOut一样运行一些信息......
for (Maquina i : m.listar()) {
//Passing to Import Thread the object with the data and a Date parameter
ImportarDados imp = new ImportarDados(i, jDateInicial.getDate());
//Calling progress bar update Thread with the progressbar itself and progress parameter
BarraDeProgresso bp = new BarraDeProgresso(progresso, progImportacao);
imp.run();
bp.run();
}
组件初始化(Netbeans生成)
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
public class Minimo extends javax.swing.JFrame {
public Minimo() {
initComponents();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int progImportacao[] = {0};
progresso.setMaximum(15);
for (int i = 0; i <= 15; i++) {
ImportarDados imp = new ImportarDados(i,lblProgresso);
BarraDeProgresso bp = new BarraDeProgresso(progresso, progImportacao);
imp.run();
bp.run();
progImportacao[0] += 1;
}
}
可运行的课程
private void initComponents() {
progresso = new javax.swing.JProgressBar();
lblProgresso = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
lblProgresso.setText("...");
jButton1.setText("IMPORT DATA");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(60, 60, 60)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblProgresso)
.addComponent(progresso, javax.swing.GroupLayout.PREFERRED_SIZE, 382, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(47, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(191, 191, 191))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(32, 32, 32)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE)
.addComponent(lblProgresso)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(progresso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(37, 37, 37))
);
pack();
}// </editor-fold>
Main(Netbeans Generated)
class BarraDeProgresso implements Runnable {
public JProgressBar jProgressBar1;
public int progresso[];
public BarraDeProgresso(JProgressBar barra, int progresso[]) {
this.jProgressBar1 = barra;
this.progresso = progresso;
}
@Override
public void run() {
try {
Thread.sleep(0);
System.out.println("TBARRA PROG " + progresso[0]);
jProgressBar1.setValue(progresso[0]);
jProgressBar1.repaint();
} catch (InterruptedException e) {
}
}
}
class ImportarDados implements Runnable {
private int pi = 0;
JLabel x;
public ImportarDados(int i, JLabel tag) {
this.pi = i;
this.x = tag;
}
@Override
public void run() {
try {
Thread.sleep(500);
x.setText(Integer.toString(pi)+" /15");
} catch (InterruptedException ex) {
Logger.getLogger(Minimo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
答案 0 :(得分:1)
您当前的代码不会创建后台线程。是的,你有Runnables,但你在它们上面调用了run()
,这意味着你在Swing事件线程上调用它们。执行此操作时,您将阻止事件线程,从而有效地冻结您的程序。相反,你需要:
start()
来创建一个真正的后台线程。有关使用SwingWorker的示例,请参阅:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
@SuppressWarnings("serial")
public class Minimo2 extends JPanel {
private static final int EB_GAP = 15;
private static final int PROG_BAR_WDTH = 400;
public static final int MAX_DATA = 15;
private JProgressBar progresso;
private JLabel lblProgresso;
private JButton jButton1;
private Action importDataAction = new ImportDataAction("Import Data");
public Minimo2() {
initComponents();
}
private void initComponents() {
progresso = new JProgressBar(0, MAX_DATA);
lblProgresso = new JLabel(" ");
jButton1 = new JButton(importDataAction);
int progBarHeight = progresso.getPreferredSize().height;
progresso.setPreferredSize(new Dimension(PROG_BAR_WDTH, progBarHeight));
progresso.setStringPainted(true);
JPanel btnPanel = new JPanel();
btnPanel.add(jButton1);
JPanel labelPanel = new JPanel();
labelPanel.add(lblProgresso);
JPanel progressPanel = new JPanel();
progressPanel.add(progresso);
setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(btnPanel);
add(Box.createVerticalStrut(EB_GAP));
add(labelPanel);
add(Box.createVerticalStrut(EB_GAP));
add(progressPanel);
}
private class ImportDataAction extends AbstractAction {
public ImportDataAction(String name) {
super(name); // give the button text
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic); // give it a hot key
}
@Override
public void actionPerformed(ActionEvent e) {
setEnabled(false); // disable our button
ImportDataWorker worker = new ImportDataWorker(MAX_DATA);
worker.addPropertyChangeListener(new WorkerListener());
worker.execute();
}
}
private class WorkerListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int progValue = (int) evt.getNewValue();
progresso.setValue(progValue);
String text = String.format("%02d/15", progValue);
lblProgresso.setText(text);
} else if ("state".equals(evt.getPropertyName())) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
@SuppressWarnings("rawtypes")
SwingWorker worker = (SwingWorker)evt.getSource();
try {
worker.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
progresso.setValue(MAX_DATA);
String text = String.format("%02d/15", MAX_DATA);
lblProgresso.setText(text);
importDataAction.setEnabled(true);
}
}
}
}
private class ImportDataWorker extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 500;
private int max;
public ImportDataWorker(int max) {
this.max = max;
}
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < max; i++) {
setProgress(i);
Thread.sleep(SLEEP_TIME);
}
return null;
}
}
private static void createAndShowGui() {
Minimo2 mainPanel = new Minimo2();
JFrame frame = new JFrame("Minimo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}