简体   繁体   English

添加其他项目时无法从另一个线程更新 JProgressBar 的值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM