简体   繁体   English

对话框框架中的JProgressBar无法正常工作

[英]JProgressBar in dialog frame not working properly

I have a java program that load a text file as input, read its content, modify some strings and then prints the result to a textarea. 我有一个Java程序,可将文本文件加载为输入,读取其内容,修改一些字符串,然后将结果打印到textarea。 Due to several seconds required by this operation i would like to show a JProgressBar during this activity in order to inform the user that the execution is in progress and when the activity is completed close the dialog containing the JprogressBar and print the results. 由于此操作需要几秒钟的时间,因此我想在此活动期间显示一个JProgressBar,以通知用户执行正在进行中,并且当活动完成时,关闭包含JprogressBar的对话框并打印结果。

Here is the code: 这是代码:

JButton btnCaricaFile = new JButton("Load text file");
        panel.add(btnCaricaFile);
        btnCaricaFile.setIcon(UIManager.getIcon("FileView.directoryIcon"));
        btnCaricaFile.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                //JFileChooser choice = null;
                final JFileChooser choice = new JFileChooser(userDir +"/Desktop");
                int option = choice.showOpenDialog(GUI.this);
                if (option == JFileChooser.APPROVE_OPTION) {
                    final JDialog dialog = new JDialog(GUI.this, "In progress", true);
                    JProgressBar progressBar = new JProgressBar(0, 100);
                    progressBar.setIndeterminate(true);
                    dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
                    dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
                    dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
                    dialog.setSize(300, 75);
                    dialog.setLocationRelativeTo(GUI.this);
                    Thread t = new Thread(new Runnable() {
                        public void run() {
                            dialog.setVisible(true);
                            File file = choice.getSelectedFile();
                            lista.clear();
                            textArea.setText("");
                            lista = loadFile.openFile(file);
                            for(int i=0; i<lista.size(); i++) {
                                textArea.append(lista.get(i)+"\n");
                            }
                            dialog.setVisible(false);
                        }
                    });
                    t.start();
                }
            }
        });

For this purpose i'm using a JDialog as container for the JProgressBar executed by an appropriate thread. 为此,我使用JDialog作为由适当线程执行的JProgressBar的容器。 The problem is that the progress bar is shown for an infinite time and is not printed anything to the textarea. 问题在于进度条显示的时间是无限的,并且没有将任何内容打印到文本区域。

Could you help me to solve this? 你能帮我解决这个问题吗? Thanks 谢谢

Yes, you're creating a background thread for your file reading, good, but you're also making Swing calls from within this same background thread, not good, and this is likely tying up the Swing event thread inappropriately. 是的,您正在创建一个用于读取文件的后台线程,很好,但是您还从同一后台线程内进行了Swing调用,效果不好,这很可能会不适当地占用Swing事件线程。 The key is to keep your threading separate -- background work goes in the background thread, and Swing work goes only in the Swing thread. 关键是使线程分开-后台工作在后台线程中进行,而Swing工作仅在Swing线程中进行。 Please read Lesson: Concurrency in Swing fore more on this. 请阅读“ 课程:Swing中的并发性”以了解更多有关此内容。

Myself, I would create and use a SwingWorker<Void, String> , and use the worker's publish/process method pair to send Strings to the JTextArea safely. 我本人将创建并使用SwingWorker<Void, String> ,并使用工作人员的发布/处理方法对将字符串安全地发送到JTextArea。

For example, something like... 例如,类似...

final JDialog dialog = new JDialog(GUI.this, "In progress", true);
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(300, 75);
dialog.setLocationRelativeTo(GUI.this);
lista.clear();
SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {

    @Override
    public Void doInBackground() throws Exception {
        // all called *off* the event thread
        lista = loadFile.openFile(file);
        for (int i = 0; i < lista.size(); i++) {
            publish(lista.get(i));
        }
        return null;
    }

    @Override
    protected void process(List<String> chunks) {
        // called on the event thread
        for (String chunk : chunks) {
            textArea.append(chunk + "\n");
        }
    }

    // called on the event thread
    public void done() {
        dialog.setVisible(false);
        // should call get() here to catch and handle
        // any exceptions that the worker might have thrown
    }
};
worker.execute();
dialog.setVisible(true); // call this last since dialog is modal

Note: code not tested nor compiled 注意:未经测试或编译的代码

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

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