Java DefaultListModel是否凌驾于actionlistener中的操作顺序之上?

Java DefaultListModel是否凌驾于actionlistener中的操作顺序之上?,java,swing,concurrency,actionlistener,Java,Swing,Concurrency,Actionlistener,我的JAVA程序中有一个部分,您可以单击一个按钮,actionListener应该完成以下过程 将按钮上的文本从“开始”更改为“待机” 向面板添加标签,说明进程已启动 执行一个方法(该方法对数据进行排序,并通过addelement将其返回到defaultListModel JList,最后 将按钮上的文本从“开始”更改为“完成” 如下 uploadNotamButton.addActionListener((ActionEvent e) -> { if(e.getSourc

我的JAVA程序中有一个部分,您可以单击一个按钮,actionListener应该完成以下过程

  • 将按钮上的文本从“开始”更改为“待机”
  • 向面板添加标签,说明进程已启动
  • 执行一个方法(该方法对数据进行排序,并通过addelement将其返回到defaultListModel JList,最后
  • 将按钮上的文本从“开始”更改为“完成”
  • 如下

    uploadNotamButton.addActionListener((ActionEvent e) -> {
            if(e.getSource()==uploadNotamButton)
                uploadNotamButton.setText("STANDBY");
            progressLabel.setText("Process Has Begun, standby...");
            progressLabel.setVisible(true);
    
            uploadNotams();
    
            uploadNotamButton.setText("COMPLETE");
        });
    
    但是,当我按下按钮时,按钮文本不会更改,标签不会显示,但方法会执行。只有当方法完成时,按钮文本才会更改为“完成”(从未显示“待机”),并显示说明“流程已开始,待机”的标签(流程完成时)

    这是defaultlistmodel优先于一切的特性还是我的编码经验不足

    此外,在方法中分析的数据会一次性显示在JList中,而不是一次显示在每个元素中。如果数据在分析时显示在列表中,则至少会显示发生了什么。对于defaultListModel,这是不可能的吗

    非常感谢您的光临
    PG

    这是defaultlistmodel优先于一切的特性还是我的编码经验不足

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

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

    例如(未测试的代码)

    uploadNotamButton.addActionListener((ActionEvent e)->{
    //如果(例如getSource()==uploadNotamButton)
    上传notambutton.setText(“备用”);
    progressLabel.setText(“进程已开始,待机…”);
    progressLabel.setVisible(true);
    //创建工人来做背景工作
    SwingWorker worker=新SwingWorker(){
    @凌驾
    受保护的Void doInBackground()引发异常{
    //这一切都是在后台线程中完成的
    uploadNotams();//不要在此方法中进行任何Swing调用
    返回null;
    }
    };
    //当员工完成工作时得到通知,并作出响应
    worker.addPropertyChangeListener(新的PropertyChangeListener(){
    @凌驾
    公共作废属性更改(属性更改事件evt){
    if(evt.getNewValue==SwingWorker.StateValue.DONE){
    上传notambutton.setText(“完成”);
    //下面的代码需要被try/catch块包围
    //您需要处理可能捕获的任何异常
    ((SwingWorker)evt.getSource()).get();
    }
    }
    });
    worker.execute();//运行worker
    });
    
    非常感谢您,它工作得非常好。我希望这些书能像您那样轻松地解释它。
    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
    });