简体   繁体   English

如何在线程内的JInternalFrame中执行可更新的JProgressBar?

[英]How to do an updateable JProgressBar in an JInternalFrame inside a thread?

This is what i have so far, It's probably totally wrong... 到目前为止,这就是我所拥有的,这可能是完全错误的...

The problem seems to be updating the percentage inside the loop and then calling it outside in the SwingUtilities.invokeLater program. 问题似乎是在循环内更新百分比,然后在SwingUtilities.invokeLater程序中外部调用它。

Also the JInternalFrame sits behind the rest of the program, Perhaps a JDialog would be better used. 同样, JInternalFrame位于程序的其余部分之后,也许最好使用JDialog

Will be here for anymore code needed, Also willing to post entire project on github if you need more information.(If that is allowed) 将在此处提供所需的更多代码,如果您需要更多信息,也愿意将整个项目发布在github上(如果允许)。

This is my first project with code so any help would be appreciated! 这是我的第一个带有代码的项目,因此将不胜感激!

package twoDMapEditor;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.BorderFactory;
import javax.swing.JInternalFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;

public class SaveActionListener implements ActionListener {
    public void actionPerformed(ActionEvent me) {
        final JProgressBar progressBar = new JProgressBar();
        progressBar.setValue(0);
        progressBar.setStringPainted(true);
        progressBar.setBorder(BorderFactory.createTitledBorder("Saving..."));
        final JInternalFrame loadingDialog = new JInternalFrame();
        loadingDialog.add(progressBar);
        loadingDialog.pack();
        loadingDialog.setVisible(true);
        TwoDMapEditor.frame.add(loadingDialog);
        TwoDMapEditor.frame.revalidate();
        TwoDMapEditor.frame.repaint();

        new Thread(new Runnable() {
              public void run() {
                  final int percentage = 0;
                  int i = 0, j;
                  while (i < TwoDMapEditor.size[0]) {
                      j = 0;
                        while(j < TwoDMapEditor.size[1]){
                            if (!TwoDMapEditor.mySql.updateMapPiece(i, j)) {
                                System.out.println("Something went wrong");
                            }
                            //percentage = ((i * TwoDMapEditor.size[1]) + j+1) * 100 / (TwoDMapEditor.size[0] * TwoDMapEditor.size[1]);
                            j++;
                        }
                        i++;
                  }

                  try {
                    SwingUtilities.invokeAndWait(new Runnable() {
                        public void run() {
                            progressBar.setValue(percentage);
                        }
                      });
                } catch (InvocationTargetException | InterruptedException e1) {
                    e1.printStackTrace();
                }

                  try {
                    java.lang.Thread.sleep(100);
                  }
                  catch(Exception e) { }
              }
        }).start();
    }
}

edit: got this now: 编辑:现在得到这个:

package twoDMapEditor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.BorderFactory;
import javax.swing.JInternalFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

public class SaveActionListener implements ActionListener, PropertyChangeListener {
JProgressBar progressBar;
ProgressBar progressBarClass;
JInternalFrame loadingDialog;

SaveActionListener(){
    progressBar = new JProgressBar();
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    progressBar.setBorder(BorderFactory.createTitledBorder("Saving..."));
    loadingDialog = new JInternalFrame();
    loadingDialog.add(progressBar);
    loadingDialog.pack();
    loadingDialog.setVisible(true);
    TwoDMapEditor.frame.add(loadingDialog);
    TwoDMapEditor.frame.revalidate();
    TwoDMapEditor.frame.repaint();          
}

class ProgressBar extends SwingWorker<Void, Void>{
    public int percentage = 1;
    protected Void doInBackground(){
        int i = 0, j;
          while (i < TwoDMapEditor.size[0]) {
              j = 0;
                while(j < TwoDMapEditor.size[1]){
                    if (!TwoDMapEditor.mySql.updateMapPiece(i, j)) {
                        System.out.println("Something went wrong");
                    }
                    percentage = ((i * TwoDMapEditor.size[1]) + j+1) * 100 / (TwoDMapEditor.size[0] * TwoDMapEditor.size[1]);
                    progressBar.setValue(percentage);
                    System.out.println(percentage);
                    j++;
                }
                i++;
          }

        return null;
    }

    public void done(){
        loadingDialog.dispose();
    }
}

public void actionPerformed(ActionEvent me) {
    progressBarClass = new ProgressBar();
    progressBarClass.addPropertyChangeListener(this);
    progressBarClass.execute(); 
}

public void propertyChange(PropertyChangeEvent pce) {
    System.out.println(TwoDMapEditor.saveActionListener.progressBarClass.percentage);
    progressBar.setValue(TwoDMapEditor.saveActionListener.progressBarClass.percentage);
}

} }

Without a completely runnable example, it's kind of hard to know where problems might be. 如果没有一个完全可运行的示例,那么很难知道问题可能出在哪里。

You should defiantly be updating the progress within the loop. 您应该严格地更新循环中的进度。 If you could guarantee that every TwoDMapEditor.size[1] was the same value, it would be easier. 如果您可以保证每个TwoDMapEditor.size[1]都具有相同的值,那么会更容易。

You basically need to know two things, the total number of possible iterations and the number of iterations you've completed, but I don't see any information in your snippet which might provide that information. 您基本上需要知道两件事,可能的迭代总数和已完成的迭代数量,但是我在您的代码片段中看不到任何可以提供该信息的信息。

Anyway, I would also suggest using a SwingWorker , as it provides the ability to notify the UI of a progress state change quite easily, for example... 无论如何,我也建议使用SwingWorker ,因为它提供了很容易地通知UI进度状态更改的功能,例如...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestProgress {

    public static void main(String[] args) {
        new TestProgress();
    }

    public TestProgress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JDesktopPane dp = new JDesktopPane() {

                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(400, 400);
                    }

                };
                JInternalFrame inf = new JInternalFrame("Progressing", true, false, false, false);
                inf.add(new TestPane());
                inf.pack();
                dp.add(inf);
                inf.setVisible(true);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(dp);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JProgressBar pb;

        public TestPane() {
            setLayout(new GridBagLayout());
            pb = new JProgressBar();
            add(pb);

            LongRunningProcessWorker worker = new LongRunningProcessWorker();
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    String name = evt.getPropertyName();
                    SwingWorker worker = (SwingWorker) evt.getSource();
                    switch (name) {
                        case "progress":
                            System.out.println(worker.getProgress());
                            pb.setValue(worker.getProgress());
                            break;
                        case "state":
                            switch (worker.getState()) {
                                case DONE:
                                    // Close the window or something
                                    break;
                            }
                            break;
                    }
                }
            });
            worker.execute();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class LongRunningProcessWorker extends SwingWorker {

        @Override
        protected Object doInBackground() throws Exception {

            Random rnd = new Random();
            int outterMax = rnd.nextInt(150) + 50;
            int innerMax = rnd.nextInt(150) + 50;

            System.out.println(outterMax + "/" + innerMax);

            for (int outter = 0; outter < outterMax; outter++) {
                for (int inner = 0; inner < innerMax; inner++) {
                    float progress = (float)((outter * innerMax) + inner) / (float)(innerMax + outterMax);
                    Thread.sleep(10); // Simulate some processing
                }
            }
            return null;
        }

    }

}

Take a look at Concurrency in Swing and Worker Threads and SwingWorker for more details 查看SwingWorker线程中的并发性 以及SwingWorker,以了解更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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