DefaultListModel是否超出了actionlistener中的操作顺序?

时间:2016-06-12 10:58:51

标签: java swing concurrency actionlistener

我有一个JAVA程序的一部分,你点击一个按钮,actionListener应该经历以下过程;

  1. 更改按钮上的文字"开始"到"待命"
  2. 向面板添加标签,说明流程已启动
  3. 执行一个方法(对数据进行排序并通过addelement将其返回到defaultListModel JList,最后
  4. 更改按钮上的文字"开始"到"完成"
  5. 按照以下

    uploadNotamButton.addActionListener((ActionEvent e) -> {
            if(e.getSource()==uploadNotamButton)
                uploadNotamButton.setText("STANDBY");
            progressLabel.setText("Process Has Begun, standby...");
            progressLabel.setVisible(true);
    
            uploadNotams();
    
            uploadNotamButton.setText("COMPLETE");
        });
    

    然而,当我按下按钮时,按钮文本不会改变,标签不会显示,但方法会执行。只有在方法完成后,按钮文本才会变为"完成" (从未显示" STANDBY")和标签陈述"过程已经开始,待机"显示(当过程完成时)。

    这是defaultlistmodel的一项功能,它优先考虑所有事情或我的编码缺乏经验吗?

    此外,在方法中分析的数据一次性显示在JList中,而不是一次显示在每个元素中。如果数据在分析时显示在列表中,它至少会显示正在发生的事情。这是不可能使用defaultListModel?

    非常感谢提前 PG

1 个答案:

答案 0 :(得分:2)

  

这是defaultlistmodel的一项功能,它优先考虑所有事情或我的编码缺乏经验吗?

这与DefaultListModel无关,而与Swing单线程无关。您正在Swing事件线程上运行长时间运行的进程,阻止此线程执行必要的操作,包括在GUI上绘制文本和图像以及与用户交互。

解决方案是使用后台线程,例如可以通过SwingWorker获取,在此后台​​线程中运行长时间运行的代码,向工作者添加PropertyChangeListener以在完成时通知,然后响应此通知

例如(代码未测试)

uploadNotamButton.addActionListener((ActionEvent e) -> {
    // if(e.getSource()==uploadNotamButton)
    uploadNotamButton.setText("STANDBY");
    progressLabel.setText("Process Has Begun, standby...");
    progressLabel.setVisible(true);

    // create worker to do background work
    SwingWorker<Void, Void> worker = new SwingWorker<>() {
        @Override
        protected Void doInBackground() throws Exception {
            // this is all done within a background thread
            uploadNotams();  // don't make any Swing calls from within this method
            return null;
        }
    };

    // get notified when the worker is done, and respond to it
    worker.addPropertyChangeListener(new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getNewValue == SwingWorker.StateValue.DONE) {
                uploadNotamButton.setText("COMPLETE");

                // the code below needs to be surrounded by a try/catch block
                // and you'll need to handle any exceptions that might be caught
                ((SwingWorker) evt.getSource()).get();
            }
        }
    });
    worker.execute();  // run the worker
});