Как увидеть связь между двумя работающими с прогрессом

У меня 2 класса.java

Главный:

public class Controller extends javax.swing.JFrame
{   
    public static void updateProgressBar(int i) {
        jProgressBar1.setValue(i);
        jProgressBar1.repaint();
    }

    public static void main(String args[]) {

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Controller app = new Controller();
                app.setVisible(true);
                app.setResizable(false);
            }
        });
    }

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        ChildModel model = new ChildModel();
        Thread t1 = new Thread(model);
        t1.start();
    }

    private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder
}

Мой ChildModel (ChildModel.java) вычисляет некоторый код (который занимает около 10-20 секунд), и я хочу показать прогресс в классе отца (Controller.java).

Вот моя ChildModel:

public class ChildModel implements Runnable
{
    public ChildModel(){ /* Something */ }

    public void complexMath()
    {
        //Lots of logic here
        Controller.updateProgression(purcent);
    }

    @Override
    public void run() {
        complexMath();
    }
}

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

2 ответа

Решение

jProgressBar1 переменная является переменной экземпляра, поэтому вы не можете получить к ней доступ из статического метода. И метод не должен быть статическим: вы хотите обновить прогресс в контроллере, а не во всех экземплярах контроллера.

Передайте ссылку на контроллер в ChildModel и используйте эту ссылку из ChildModel для обновления индикатора выполнения. Также помните, что все взаимодействия Swing должны выполняться в EDT, а не в фоновом потоке. ТАК код должен выглядеть так:

public class Controller extends javax.swing.JFrame
{   
    public void updateProgressBar(int i) {
        jProgressBar1.setValue(i);
        // no need for repaint. The progress bar knows it must be repainted 
        // when its value changes
    }

    public static void main(String args[]) {

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Controller app = new Controller();
                app.setVisible(true);
                app.setResizable(false);
            }
        });
    }

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        ChildModel model = new ChildModel(this);
        Thread t1 = new Thread(model);
        t1.start();
    }

    private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder
}

public class ChildModel implements Runnable
{

    private Controller controller;

    public ChildModel(Controller controller){
        this.controller = controller;
    }

    public void complexMath()
    {
        //Lots of logic here
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                controller.updateProgression(percent);
            }
        });
    }

    @Override
    public void run() {
        complexMath();
    }
}

У Swing есть свои собственные механизмы параллелизма для обновления компонентов. Здесь вы можете использовать Swing Timer и обновить JProgressBar, Вместо того, чтобы иметь ChildModel воплощать в жизнь RunnableВы могли бы использовать Timer в качестве переменной члена класса и передать в вашем экземпляре jProgressBar1, позволяя вам позвонить setValue когда требуется.

Другие вопросы по тегам