当前位置: 首页 > 面试题库 >

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

戚澄邈
2023-03-14
问题内容

我有一个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,现在一切都很好。感谢您的时间和建议。


问题答案:

我想SwingWorker用a
JProgressBar内追踪我的进度JDialog。但是,我的SwingWorker班级无法处理我的自定义DialogPanel班级。为了获得相同的结果,ProgressMonitor最好使用默认类。

我已通过构造函数将传递ProgressMonitorSwingWorker

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

任务propertyChangeListener更改如下:

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

感谢rashgod提供有关该state物业的答案和评论。



 类似资料:
  • 我想创建一个如下所示的自定义对话框 我试过以下几件事。 > 我创建了AlertDialog.Builder的子类,并使用了自定义标题和自定义内容视图,但结果不是预期的。 另一个尝试是子类DialogFragment并自定义onCreateDialog中的对话框,但结果并不像预期的那样。 然后我尝试使用一个普通的对话框类。结果不如预期。 在这三种情况下,问题是当我忽略标题视图时,对话框的大小不像预期

  • 当我打开显示对话框的文件时,我需要更改Java图像并添加我自己的图像。如何自定义对话框? 例如,我需要将编码添加到对话框以及如何将不同类型的文件添加到类型下拉框的文件中。例如,我将、、添加到框。 这是我的密码,

  • 我是初学者在android。我正在创建一个自定义对话框,它工作正常。但是这个对话框不移动。如何移动这个自定义对话框。例如在窗口中包含记事本,油漆等。当你点击这个(记事本,油漆等)标题栏你可以移动的位置。如果可能请发送信息如何移动对话框。否则如果不可能发送原因。请回复你的答案和意见是有价值的我。谢谢。

  • 本文向大家介绍Android 自定义对话框 showSetPwdDialog,包括了Android 自定义对话框 showSetPwdDialog的使用技巧和注意事项,需要的朋友参考一下 样式如下所示: 布局: layout   dialog_set_pwd.xml 状态选择器: drawable   btn_blue_selector.xml   btn_white_selector.xml 引

  • 问题内容: 我正在使用Node.js,Express和Redis构建一个用于会话管理的网站。无论出于何种原因,如果我有一个会话变量(在此示例中),并且刷新页面,则不会保存该变量,但是,如果我在设置了变量后调用,则确实会将其保存到Redis(redis- cli监视器显示此内容-不调用表示变量不存在,而调用则显示该变量)。 我正在使用它来设置和启动服务器: 然后,在那条路线中,我有: 由此,我应该能

  • 我是Android新手,正在开发自定义警报对话框 我想打开另一个对话框,点击编辑按钮,代码如下 但我得到了一个异常,我的日志cat输出如下 就连我的红色十字按钮也可以正常工作,我已经多次使用相同的代码用TextView显示AlertDialog,但我不知道代码出了什么问题。非常感谢您的帮助。提前谢谢。 现在我得到了我想要的,但是编辑和保存都有重叠。我想隐藏编辑(蓝色按钮)并使保存按钮清晰可见。