如果没有自定义对话框面板中的Thread.sleep(),SwingWorker不会更新JProgressBar

我有一个SwingWorker类,它加载一个文本文件并将其切成块进行进一步处理.

这是SwingWorker类:

public class ConverterWorker extends SwingWorker<String, String>
{
private final File f;
private final JLabel label;

public ConverterWorker(File f, JLabel label)
{
    this.f = f;
    this.label = label;
}

@Override
protected String doInBackground() throws Exception 
{
    NMTMain.convertableData = getDataSets(f);

    if(!NMTMain.convertableData.isEmpty())
    {
        return "Done";
    }
    else
    {
        publish("Failed to load the file!");
        return "Failed";
    }
}

@Override
public void done() 
{
    try 
    {
        label.setText(get());
    } 
    catch (Exception e)
    {
        e.printStackTrace(System.err);
        System.out.println("error");
    }
}

@Override
protected void process(List<String> chunks)
{
    label.setText(chunks.get(chunks.size() - 1));
}

public ArrayList<ArrayList<Convertable>> getDataSets(File f)
{
    ArrayList<ArrayList<Convertable>> dataSets = new ArrayList<ArrayList<Convertable>>();

    publish("Loading file...");
    setProgress(0);

    String[] data = loadFile(f);

    for(int i = 0; i< NMTMain.nodes.size(); i++)
    {
        dataSets.add(splitByNode(data, NMTMain.nodes.get(i).getName()));
    }

    setProgress(100);

    return dataSets;
}

private ArrayList<Convertable> splitByNode(String[] data, String name)
{
    ArrayList<Convertable> temp = new ArrayList<Convertable>();

    for(int i = 0; i < data.length; i++)
    {
        if(data[i].contains(name))
        {
            temp.add(new Convertable(data[i]));
        }
    }

    Collections.sort(temp);

    return temp;
}

private String[] loadFile(File f)
{
    String data = "";
    String[] nodes; 

    long fileLength = f.length();
    int bytesRead = -1;
    int totalBytesRead = 0;

    try 
    {
        if(f.exists()) 
        {
            Scanner scan = new Scanner(f);

            while(scan.hasNextLine()) 
            {
                String line = scan.nextLine();
                data = data + line + "\n";
                bytesRead = line.getBytes().length;
                totalBytesRead += bytesRead;
                int progress = (int) Math.round(((double) totalBytesRead / (double) fileLength) * 100d);

               /* try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }*/

                //publish("loading... " + String.valueOf(progress));
                setProgress(progress);
            }

            scan.close();
        }

    }
    catch (FileNotFoundException e) 
    {
        // TODO Auto-generated catch block
                e.printStackTrace();
    }

    nodes = data.split("\n\"\n");

    return nodes;        
}

这在Thread.sleep(1)时工作正常;没有注释.但是,当我评论Thread.sleep(1);该类不会更新进度条.

我把我的班级称为按钮,这里是ActionListener:

loadInput.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent arg0)
        {   
            int returnval=NMTMain.fileChooser.showOpenDialog(NMTMain.MainFrame);

            if(returnval == 0)
            {
                File f=NMTMain.fileChooser.getSelectedFile();

                final ConverterWorker worker = new ConverterWorker(f, dialogPanel.getLabel());

                worker.addPropertyChangeListener(new PropertyChangeListener()
                {
                    @Override
                    public void propertyChange(final PropertyChangeEvent evt)
                    {
                        if("progress".equalsIgnoreCase(evt.getPropertyName())) 
                        {
                            dialogPanel.showProgressDialog("Conversion");
                            dialogPanel.setProgressBarValue((int) evt.getNewValue());
                        }

                        if(worker.isDone())
                        {
                            dialogPanel.showConfirmDialog("Conversion", "OK");
                        }
                    }
                });
                worker.execute();

            }
        }
    });

这应该可以在没有睡眠的情况下正常工作,那么我在这里做错了什么呢?

更新:

原来我的DialogPanel不是最好的,并导致这种行为.

这是DialogPanel类:

public class DialogPanel extends JDialog
{

private JLabel label;
private JPanel panel;
private JButton button;
private JProgressBar progressBar;

public DialogPanel()
{
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.insets = new Insets(5,10,5,10);

    panel = new JPanel();
    panel.setLayout(new GridBagLayout());

    progressBar = new JProgressBar(0,100);
    progressBar.setVisible(false);
    progressBar.setStringPainted(true);

    setLabel(new JLabel("def text", SwingConstants.CENTER));

    button = new JButton("OK");
    button.setVisible(false);

    button.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent arg0)
        {
            // TODO Auto-generated method stub
            dispose();
        }
    });

    gbc.gridx = 0;
    gbc.gridy = 0;
    panel.add(getLabel(), gbc);
    gbc.gridy = 1;
    panel.add(progressBar, gbc);
    panel.add(button, gbc);

    this.setContentPane(panel);
    this.setLocationRelativeTo(null);
    this.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
    this.setResizable(false);
}

public void setProgressBarValue(int value)
{
    progressBar.setValue(value);
}

public void setProgressBarVisibility(boolean value)
{
    progressBar.setVisible(value);
}

public void setText(String text)
{
    getLabel().setText(text);
}

public void showProgressDialog(String title)
{
    progressBar.setVisible(true);
    button.setVisible(false);
    this.setTitle(title);
    this.pack();

    if(!this.isVisible())
    {
        this.setVisible(true);
    }
}

public void showConfirmDialog(String title, String buttontext)
{
    progressBar.setVisible(false);
    button.setVisible(true);
    this.setTitle(title);
    button.setText(buttontext);
    this.pack();

    if(!this.isVisible())
    {
        this.setVisible(true);
    }       
}

public JLabel getLabel() 
{
    return label;
}

public void setLabel(JLabel label)
{
    this.label = label;
}

public JProgressBar getProgressBar() 
{
    return progressBar;
}

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

专业眼睛可能是一团糟.如何在对话框中显示进度条,该对话框将在完成此过程后有一个确认按钮来处理对话框?

解:

我已从DialogPanel类更改为ProgressMonitor,现在一切都很好.
感谢您的时间和建议.

setProgress() API注释:“出于性能目的,所有这些调用仅合并为一个调用,仅使用最后一个调用参数.”添加Thread.sleep(1)只是推迟合并;调用println()引入了类似的延迟.请记住您的文件系统如此之快;我不愿意引入人为的延迟.作为说明效果的具体示例,我在此完整的 example中添加了中间报告,如下所示.

private static class LogWorker extends SwingWorker<TableModel, String> {
    private long fileLength;
    private long bytesRead;
    ...
    this.fileLength = file.length();
    ...
    while ((s = br.readLine()) != null) {
        publish(s);
        bytesRead += s.length();
        int progress = (int)(100 * bytesRead / fileLength);
        // System.out.println(progress);
        setProgress(progress);
    }
    ...
}

lw.addPropertyChangeListener((PropertyChangeEvent e) -> {
    if ("progress".equals(e.getPropertyName())) {
        jpb.setValue((Integer)e.getNewValue());
    }
    if ("state".equals(e.getPropertyName())) {
        SwingWorker.StateValue s = (SwingWorker.StateValue) e.getNewValue();
        if (s.equals(SwingWorker.StateValue.DONE)) {
            jpb.setValue(100);
        }
    }
});
相关文章
相关标签/搜索