添加另一个项目时,无法从另一个线程更新 JProgressBar 的值 [英] Can't update value of JProgressBar from another thread when adding another items

查看:27
本文介绍了添加另一个项目时,无法从另一个线程更新 JProgressBar 的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在向 JPanel 添加另一个组件时,我在显示当前状态(在 JProgressBar 中)时遇到问题.

I have a problem with displaying current status(in JProgressBar) while adding another components to JPanel.

这个操作很繁重,大约需要 2 秒,20 次迭代(添加 20 个项目).但它可以是 100 个项目.

This operation is heavy and takes at about 2 seconds with 20 iterations (adding 20 items). But it can be 100 items.

所以我需要实现在 JProgressBar 中显示每次迭代的当前状态,但我不知道如何去做.(在我的代码中它是 value perc)

So I need to achieve displaying current status of every iteration in JProgressBar, but I can't realize how to do it. (In my code it is value perc)

你能解释一下 EDT 是如何工作的吗?是否将事件添加到队列中?谢谢!

And can you explain how EDT works? Is it adding events into queue to the end? Thank you!

我的 JProgressBar 对象:categoryStatus.

My JProgressBar object: categoryStatus.

这是我的代码:

    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();

推荐答案

我写这篇文章是为了展示我认为您正在尝试做的事情.它创建了两个主要面板.最上面的一个承载 ProgressBar.下层承载线程中创建的较小面板.Swing 计时器用于在添加较小面板时模拟活动.

I wrote this to demonstrate what I think you are trying to do. It creates two main panels. The top one hosts the 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.


    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);
          }

       }
    }

这篇关于添加另一个项目时,无法从另一个线程更新 JProgressBar 的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆