[英]Can't update value of JProgressBar from another thread when adding another items
I have a problem with displaying current status(in JProgressBar) while adding another components to JPanel.在向 JPanel 添加另一个组件时,我在显示当前状态(在 JProgressBar 中)时遇到问题。
This operation is heavy and takes at about 2 seconds with 20 iterations (adding 20 items).这个操作很繁重,大约需要 2 秒,20 次迭代(添加 20 个项目)。 But it can be 100 items.
但它可以是 100 个项目。
So I need to achieve displaying current status of every iteration in JProgressBar, but I can't realize how to do it.所以我需要实现在JProgressBar中显示每次迭代的当前状态,但我不知道怎么做。 (In my code it is value perc )
(在我的代码中它是 value perc )
And can you explain how EDT works?你能解释一下 EDT 的工作原理吗? Is it adding events into queue to the end?
是否将事件添加到队列中到最后? Thank you!
谢谢!
My JProgressBar object: categoryStatus .我的 JProgressBar object: categoryStatus 。
Here is my code:这是我的代码:
categoryStatus = new LayoutProgressBar(150, 200, 800, 20, Color.decode("#F7F7F7"), 3, 0);
workPanel.add(categoryStatus);
LayoutPanel modsPanel = new LayoutPanel( 5, 64, 1090, 448, new Color(0,0,0,0));
modsPanel.setLayout(new BorderLayout());
LayoutPanel subModPanel = new LayoutPanel(8, 50, modsPanel.getWidth()-16, 300, new Color(0,0,0,0));
subModPanel.setPreferredSize(new Dimension(modsPanel.getWidth()-16, mods.size()*172 ));
Thread thrd1 = new Thread() {
public void run() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
long startTime = System.nanoTime();
for(int i = 0; i<mods.size(); i++){
String mod_url = mods.get("mod_"+i).get("mod_url").toString();
String title = mods.get("mod_"+i).get("name").toString();
String mod_type = mods.get("mod_"+i).get("type").toString();
LayoutPanel curModPanel = new LayoutPanel(10, i*172+5, 1060, 156, new Color(0,0,0,55));
LayoutLabel last_upd = new LayoutLabel(185, 112, 17, 17, true, false, Color.black, new ImageIcon(LoadingComp.class.getResource("/images/upd.png")), "", 12, "MullerBold.otf");
LayoutLabel vers_icon = new LayoutLabel(355, 112, 19, 19, true, false, Color.black, new ImageIcon(LoadingComp.class.getResource("/images/cube.png")), "", 12, "MullerBold.otf");
LayoutLabel vers = new LayoutLabel(385, 115, 130, 14, false, false, Color.decode("#00B9FF"), null, mods.get("mod_"+i).get("version").toString(), 12, "MullerMedium.otf");
LayoutLabel last_date = new LayoutLabel(215, 115, 130, 14, false, false, Color.decode("#00B9FF"), null, mods.get("mod_"+i).get("date").toString(), 12, "MullerMedium.otf");
LayoutLabel titleLabel = new LayoutLabel(185, 15, 130, 14, false, false, Color.white, null, title, 14, "MullerBold.otf");
LayoutLabel author1 = new LayoutLabel(185, 40, 130, 14, false, false, Color.decode("#8790a6"), null, "Автор:", 12, "MullerMedium.otf");
LayoutLabel author2 = new LayoutLabel(228, 40, 130, 14, false, false, Color.decode("#00B9FF"), null, mods.get("mod_"+i).get("author").toString(), 12, "MullerMedium.otf");
LayoutTextPane descr = new LayoutTextPane(185, 65, curModPanel.getWidth()-200, 40, "Roboto-Regular.ttf", mods.get("mod_"+i).get("descr").toString(), 12, Color.decode("#D3D4E4"), null, false, StyleConstants.ALIGN_LEFT);
String mod_action = "Установить";
String mod_btn = "install_btn";
if(lut.checkFileExistence( lut.setModDestination(mod_type, title) )) {
mod_action = "Удалить";
mod_btn = "delete_btn";
}
LayoutButton mod_btn_status = new LayoutButton(18, 103, 135, 34, false, mod_action, Color.WHITE, mod_btn, 14, "MullerBold.otf");
mod_btn_status.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
workWithMod(mod_btn_status, curModPanel, title, mod_url, mod_type);
workPanel.revalidate();
workPanel.repaint();
}
});
LayoutLabel img = new LayoutLabel(18, 15, 136, 72, true, false, Color.black, new ImageIcon(DefaultUtils.getWebImage(mods.get("mod_"+i).get("img_url").toString())), "", 12, "MullerBold.otf");
curModPanel.add(mod_btn_status);
curModPanel.add(last_upd);
curModPanel.add(vers_icon);
curModPanel.add(last_date);
curModPanel.add(img);
curModPanel.add(vers);
curModPanel.add(titleLabel);
curModPanel.add(author1);
curModPanel.add(author2);
curModPanel.add(descr);
subModPanel.add(curModPanel);
int perc = i * 100 / mods.size();
//new Worker(perc, categoryStatus).execute();
}
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
};
thrd1.start();
categoryStatus.setValue(50);
Thread thrd2 = new Thread() {
public void run() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
scrollPane = new JScrollPane(subModPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setOpaque(false);
scrollPane.setViewportView(subModPanel);
scrollPane.getViewport().putClientProperty("EnableWindowBlit", Boolean.TRUE);
scrollPane.getViewport().setOpaque(false);
scrollPane.setBorder(BorderFactory.createEmptyBorder());
scrollPane.getVerticalScrollBar().setOpaque(false);
scrollPane.getVerticalScrollBar().setUnitIncrement(5);
scrollPane.getVerticalScrollBar().setUI(new LayoutScrollPane(Color.white));
scrollPane.getVerticalScrollBar().setPreferredSize(
new Dimension(7, Integer.MAX_VALUE));
modsPanel.add(scrollPane);
workPanel.remove(categoryStatus);
workPanel.repaint();
workPanel.revalidate();
workPanel.add(modsPanel);
}
});
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
scrollPane.getVerticalScrollBar().setValue(0);
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
};
thrd2.start();
I wrote this to demonstrate what I think you are trying to do.我写这篇文章是为了证明我认为你正在尝试做的事情。 It creates two main panels.
它创建了两个主要面板。 The top one hosts the ProgressBar.
最上面的一个承载 ProgressBar。 The lower one hosts the smaller panels created in the thread.
较低的托管线程中创建的较小面板。 A Swing timer is used to simulate activity while the smaller panels are added.
Swing 计时器用于模拟活动,同时添加较小的面板。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ProgressDemo extends JPanel {
JProgressBar bar = new JProgressBar();
JFrame frame = new JFrame();
int n = 0;
int panelCount = 0;
JPanel subPanel = new JPanel();
public ProgressDemo() {
setPreferredSize(new Dimension(500, 500));
subPanel.setPreferredSize(new Dimension(500, 450));
frame.add(this);
add(bar);
add(subPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer timer = new Timer(0, new MyActionListener());
timer.setDelay(200);
bar.setMaximum(200);
timer.start();
}
public static void main(String[] args) {
new ProgressDemo().start();
}
public void start() {
for (int i = 0; i < 200; i++) {
try {
SwingUtilities.invokeAndWait(() ->
{
subPanel.add(new MyPanel());
revalidate();
frame.repaint();
});
sleep(500);
}
catch (InvocationTargetException | InterruptedException ite) {
ite.printStackTrace();
}
}
}
public static void sleep(int milli) {
try {
Thread.sleep(milli);
}
catch (InterruptedException ie) {
}
}
private class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
n++;
if (n > 200) {
n = 0;
}
bar.setValue(n);
}
}
Color[] colors = {
Color.red, Color.blue, Color.green, Color.yellow, Color.cyan,
Color.magenta
};
class MyPanel extends JPanel {
public MyPanel() {
setBackground(colors[panelCount % colors.length]);
int w = 25;
int h = 25;
setPreferredSize(new Dimension(w, h));
panelCount++;
setVisible(true);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.