Domanda

Stavo cercando di aggiornare il contenuto di una JLIST quando è stato premuto un pulsante. Quindi, ho cancellato il modello dell'elenco, quindi ho cancellato l'elenco e quindi ho proceduto ad aggiungere nuovi valori all'elenco. Ecco il codice strippato:

testlist.java

public class testList extends javax.swing.JFrame {

    private Thread t;
    public DefaultListModel model;
    public boolean first = true;

    public testList() {
        model = new DefaultListModel();
        initComponents();
        this.centre(this);
    }

    public static void centre(javax.swing.JFrame f) {
        Dimension us = f.getSize(), them = Toolkit.getDefaultToolkit().getScreenSize();
        int newX = (them.width - us.width) / 2;
        int newY = (them.height - us.height) / 2;
        f.setLocation(newX, newY);
    }

    class updateList implements Runnable {

        public void run() {
            tmp.getTheList();
            model.clear();
            ouputList.removeAll();

            for (int i = 0; i < tmp.returnList.size(); i++) {
                model.addElement(tmp.returnList.get(i));

            }
            if (first) {
                chList.setModel(model);
            }

        }
    }

    private void initComponents() {
    // generated by NetBeans 6.9
    }

    private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
        t = new Thread(new updateList(), "List Updater");
        t.start();
    }

    public static void main(String args[]) {

        tmp = new aC();

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new chapList().setVisible(true);
            }
        });
    }

    static aC tmp;

    private javax.swing.JButton button;
    public static javax.swing.JList outputList;
    private javax.swing.JScrollPane jScrollPane1;
}

ac.java

public class aC extends testList {

    ArrayList returnList = new ArrayList();

    void getTheList() {
        returnList.clear();
        generateList();
    }

    void generateList() {
    // populate returnList with random values of random size using returnlist.add()
    }
}

Il problema che sto affrontando è che quando l'elenco creato per la prima volta, aggiorna la JLIST. Quando il pulsante viene premuto di nuovo, la JLIST viene aggiornata solo a volte. E per ulteriori pressioni del pulsante non viene visualizzato nulla nella JLIST.

Qualcuno potrebbe aiutarmi a capire cosa sta causando questo problema? Grazie.

È stato utile?

Soluzione

Il tuo problema principale è probabilmente correlato all'aggiornamento della GUI di swing da un thread che non è il AWT-EDT.

Potresti voler leggere e/o cercare di usare Sweworker (spedito con Java 6 e anche Disponibile per il download per l'uso con le versioni precedenti di Java.)

In alternativa, dai un'occhiata a questo approccio:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class BackgroundWorkerFrame extends javax.swing.JFrame {
    public BackgroundWorkerFrame() {
        initComponents();
        jList.setModel(new DefaultListModel());
    }

    private void jButtonGoActionPerformed(ActionEvent evt) {                                          
        Thread t = new Thread(new WorkerRunnable());
        t.start();
    }                                         

    public class WorkerRunnable implements Runnable {
        public void run() {
            System.out.println("Working hard...");
            sleep(1000);
            ArrayList<Integer> list = new ArrayList();
            for (int i = 0; i < 5; i++) {
                list.add((int) (Math.random() * 100));
            }
            System.out.println("Updating GUI...");
            SwingUtilities.invokeLater(new UpdateRunnable(list));
        }
    }

    public class UpdateRunnable implements Runnable {
        private final ArrayList<Integer> list;
        private UpdateRunnable(ArrayList<Integer> list) {
            this.list = list;
        }
        public void run() {
            DefaultListModel model = (DefaultListModel) jList.getModel();
            model.clear();
            for (Integer i : list) {
                model.addElement(i);
            }
        }
    }

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

        jButtonGo = new JButton();
        jScrollPane = new JScrollPane();
        jList = new JList();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        jButtonGo.setText("Go");
        jButtonGo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                jButtonGoActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonGo, BorderLayout.PAGE_START);

        jScrollPane.setViewportView(jList);

        getContentPane().add(jScrollPane, BorderLayout.CENTER);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-309)/2, (screenSize.height-338)/2, 309, 338);
    }// </editor-fold>

    public static void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BackgroundWorkerFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    JButton jButtonGo;
    JList jList;
    JScrollPane jScrollPane;
    // End of variables declaration
}

Altri suggerimenti

Una cosa che stai facendo è creare un nuovo thread e quindi apportare modifiche al tuo componente GUI al di fuori di EventDispatchThread. Questa non è generalmente una grande idea. Prova a correre il updateList() In posizione, che sarà sull'EDT, poiché gli eventi del pulsante vengono gestiti in quel thread.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top