Java SwingWorker不会在自定义对话框面板中没有Thread.sleep()的情况下更新JProgressBar

Java SwingWorker不会在自定义对话框面板中没有Thread.sleep()的情况下更新JProgressBar,java,swing,swingworker,thread-sleep,jprogressbar,Java,Swing,Swingworker,Thread Sleep,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; thi

我有一个
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;        
}
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);
}
}
如果没有睡眠,这应该可以正常工作,那么我做错了什么呢

更新:

事实证明,我的
对话框面板
不是最好的,并导致了这种行为

以下是
对话框面板
类:

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;        
}
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);
}
}
这对专业人士的眼睛来说可能是一团糟。如何在一个对话框中显示progressbar,该对话框将有一个确认按钮,用于在流程完成时处理该对话框

解决方案:

我已经从我的
对话框面板
类更改为,现在一切都很好。 感谢您的时间和建议。

API注意到:“出于性能目的,所有这些调用都合并到一个调用中,仅使用最后一个调用参数。”添加
Thread.sleep(1)
只是延迟合并;调用
println()
会引入类似的延迟。请放心,你的文件系统是如此之快;我不愿意人为地拖延。作为一个具体的例子来说明这种效果,我添加了中间报告,如下所示

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);
        }
    }
});
私有静态类LogWorker扩展SwingWorker{
私有长文件长度;
私人长拜读;
...
this.fileLength=file.length();
...
而((s=br.readLine())!=null){
出版;
字节读取+=s.长度();
int progress=(int)(100*字节读取/文件长度);
//系统输出打印项次(进度);
设定进度(进度);
}
...
}
lw.addPropertyChangeListener((PropertyChangeEvent e)->{
如果(“progress”.equals(例如getPropertyName())){
jpb.setValue((整数)e.getNewValue());
}
如果(“state”.equals(例如getPropertyName())){
SwingWorker.StateValue s=(SwingWorker.StateValue)e.getNewValue();
如果(s.equals(SwingWorker.StateValue.DONE)){
jpb.setValue(100);
}
}
});

我想用
JDialog
中的
JProgressBar
跟踪我的
SwingWorker
的进度。 但是,我的
SwingWorker
类无法处理我的自定义
对话框面板
类。为了获得相同的结果,使用默认类是最好的选择

我已通过其构造函数将
ProgressMonitor
传递给
SwingWorker

private final File f;
private final ProgressMonitor pm

public FileLoadWorker(File f, ProgressMonitor pm)
{
    this.f = f;
    this.pm = pm;
}
并改变了如下方式:

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

@Override
protected void process(List<String> chunks)
{
   pm.setNote(chunks.get(chunks.size() - 1));
}
final FileLoadWorker worker = new FileLoadWorker(f, pm);

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

        if("state".equals(evt.getPropertyName())) 
        {
            SwingWorker.StateValue s = (SwingWorker.StateValue) evt.getNewValue();
            if(s.equals(SwingWorker.StateValue.DONE))
            {
                pm.setProgress(100);
                pm.close();
                Toolkit.getDefaultToolkit().beep();
            }
        }

        if(pm.isCanceled())
        {
            pm.close();
            worker.cancel(true);
        }
    }
});
worker.execute();

感谢您对
state
属性的回答和评论。

您展示的方法完全超出了它在
SwingWorker
机制中的位置。如果没有进一步的信息,您将无法获得帮助。整个
SwingWorker
类现在可用。
SwingWorker.StateValue s
在哪里使用此变量?我在您链接的另一个示例中看到,当我们将pb设置为不确定时,会使用此选项。但是它在这里应该做什么呢?便于管理中间进度前后的不确定进度;我试过你的建议,我的进度条有时还是会冻结。然而,事实证明,只有当我加载只有几行(500-1000行)的文本文件时才会发生这种情况。进度条开始加载并在随机值处停止(如64%或9%)。根据小文件的不同,progressbar应该立即跳转到最终值,而不是以随机值冻结,不是吗?我看到了同样的随机效果;因为不能保证最终的进度,所以请使用
的“state”
属性。我也尝试过,但没有帮助。我糟糕的
对话框面板
就是问题所在,但从现在起我将使用
状态
属性。感谢您的帮助,我非常感谢^^.+1跳过短暂延迟的绝佳选择;更多信息。此外,如果您想降低
ProgressMonitor
的成本,以下内容非常有用。它帮助我更改了对话框的
取消按钮
、标题和图标。