Как обновить элементы управления Java Jframe из класса без графического интерфейса, используя SwingWorker - PullRequest
0 голосов
/ 12 октября 2018

Я задал этот вопрос, но мне нужно больше деталей.

Как обновить элементы управления Java Jframe из класса no-gui в режиме реального времени

Ответ, предложенный coulndне проверяться, потому что при запуске приложения Windows оно выглядит как размер 0,0, а когда я максимизирую, элементы управления не отображаются.

В любом случае, это моя первоначальная проблема:

То, что я хочу сделать (и ищу, как это сделать), это добавить элементы в мой ListBox из класса без GUI в РЕАЛЬНОМ ВРЕМЕНИ, или, другими словами, «асинхронно», без зависания моего приложения.Это понятно?Я пробовал SwingWorker и темы, но безрезультатно.Все, что я могу сделать, это обновить список после завершения всего процесса (очевидно, с моим приложением, зависшим, потому что мой процесс длинный).

Это моя архитектура:

  • Проект
  • __ Контроллер
  • __ Бизнес
  • __ Util
  • __ View

А вот мой код (пытается воспроизвести предлагаемое решение)

Просмотр (создается с помощью NetBeans)

package view;

import MyController;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;

public class MyView extends javax.swing.JFrame {

    static MyController controller;

    public MyView(DefaultListModel<String> model) {

        initComponents();
        pack();
        setVisible(true);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        btnRun = new javax.swing.JButton();
        jscrlLog = new javax.swing.JScrollPane();
        jlstLog = new javax.swing.JList();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        btnRun.setText("Run");
        btnRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRunActionPerformed(evt);
            }
        });

        jscrlLog.setViewportView(jlstLog);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(159, 159, 159)
                .addComponent(btnRun)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jscrlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btnRun)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jscrlLog, javax.swing.GroupLayout.DEFAULT_SIZE, 242, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void btnRunActionPerformed(java.awt.event.ActionEvent evt) {                                       
        controller.runProcess();
    }                                      

    public void addButtonListener(ActionListener listener) {
        btnRun.addActionListener(listener);
    }

    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MyView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MyView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MyView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MyView.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        //</editor-fold>
        //</editor-fold>
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                controller = new MyController();
            }
        });


    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnRun;
    private javax.swing.JList jlstLog;
    private javax.swing.JScrollPane jscrlLog;
    // End of variables declaration                   
}

Бизнес

package business;

import MyLog;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.SwingWorker;

public class MyBusiness {

    private int counter = 0;
    private DefaultListModel<String> model;
    private MyLog log;

    public MyBusiness(DefaultListModel<String> model) {
        this.model = model;a
    }

    public void runProcess() {
        SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {
            @Override
            protected Void doInBackground() throws Exception {
                for (int i = 0; i < 10; i++) {
                    publish("log message number " + counter++);
                    Thread.sleep(2000);
                }

                return null;
            }

            @Override
            protected void process(List<String> chunks) {
                // this is called on the Swing event thread
                for (String text : chunks) {
                    model.addElement("");
                }
            }
        };
        worker.execute();
    }

}

Журнал (модель)

package util;

import javax.swing.DefaultListModel;

public class MyLog {

    private DefaultListModel<String> model;

    public MyLog() {
        model = new DefaultListModel<String>();
    }

    public DefaultListModel<String> getLog(){
        return model;
    }

}

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Существуют две основные проблемы, препятствующие появлению журналов в JList:

a.Модель никогда не используется.Слишком используйте его, добавьте поле model:

private DefaultListModel<String> model;

public MyView(DefaultListModel<String> model) {
    this.model = model;
    initComponents();
}

и назначьте модель для JList:

//change  jlstLog = new JList<>();  to  
jlstLog = new JList<>(model); 

b.этот метод

public void runProcess() {

    view.addButtonListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            business.runProcess();
        }}
    );
}

никогда не вызывается, поэтому у кнопки нет прослушивателя действий.Полный код с устраненными проблемами можно увидеть здесь .

Некоторые дополнительные комментарии по поводу запросаОригинальный вопрос был ответил .Я считаю, что изменение вопроса после того, как на него был дан ответ, не является хорошей практикой.Это делает ответы на вопрос неактуальными, а вложенная в них работа бесполезна для будущих читателей.Пожалуйста, придерживайтесь политики «один вопрос на пост».Также в комментариях к предыдущему вопросу несколько раз подчеркивалась важность mcve.mcve должен продемонстрировать проблему , а не вашего приложения.

0 голосов
/ 12 октября 2018

при запуске приложения Windows оно выглядит как размер 0,0, а когда я максимизирую, элементы управления не закрашены.

public MyView(DefaultListModel<String> model) {
    setVisible(true);
}

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

Все, что я вижу, это то, что вы делаете рамку видимой,Я не вижу, где вы когда-либо добавляете компоненты в раму.Вот где вы когда-либо вызываете initComponents ()?

Компонент должен быть добавлен в кадр ДО того, как кадр станет видимым.И вам нужно упаковать () кадр, прежде чем он станет видимым.

...