2011-09-16 15 views
10

Ho una funzione che viene eseguita quando si fa clic su un pulsante. Supponiamo che ci sia un ciclo per aggiungere da 1 a 10 a JList. Aggiungo i dati a DefaultListModel. Funziona perfettamente e i numeri vengono aggiunti. Quindi ho aggiunto uno Thread.sleep(1000) all'interno del ciclo. Ma l'output è diverso. Volevo aggiungere 1 elemento al secondo. Ma ora aspetta 10 secondi e aggiunge tutti i numeri da 1 a 10 insieme alla fine del 10 ° secondo. Mi sbaglio da qualche parte?Aggiunta di elementi a JList in Swing Java

List processList = listNumbers.getSelectedValuesList(); 
DefaultListModel resultList = new DefaultListModel(); 
listResult.setModel(resultList); 

for (int i = 0; i < processList.size(); i++) { 
    resultList.addElement(String.valueOf(i)); 
    try { 
     Thread.sleep(1000); 
    } 
    catch (InterruptedException ex) { 
    } 
} 

risposta

4

Si dovrebbe aggiornare l'elenco in un thread separato altrimenti si finisce per bloccare il thread evento spedizione.

Provare quanto segue:

final DefaultListModel model = new DefaultListModel(); 
final JList list = new JList(model); 

//another thread to update the model 
final Thread updater = new Thread() { 
    /* (non-Javadoc) 
    * @see java.lang.Thread#run() 
    */ 
    @Override 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      model.addElement(i); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       throw new RuntimeException(e); 
      } 
     } 
    } 
}; 
updater.start(); 
+1

Continuo a pensare che 'model.addElement (i)' deve essere avvolto in 'invokeLater', si prega di aggiornare il tuo post – mKorbel

+0

@mKorbel davvero? Sto aggiornando il modello, che a sua volta genererà un evento a un gestore che chiamerà 'repaint' sulla lista. Credo che questa chiamata di 'repaint' accoderà una richiesta per il thread di invio degli eventi per chiamare' paint', quindi dovrebbe essere sicuro. – dogbane

+3

true è che non ci sono aggiornamenti su EDT, tutti sono passati oltre Thread.sleep (1000) ;, poiché tutti i fireXxxXxx sono fuori EDT – mKorbel

7

non utilizzare, in realtà non utilizzare Thread.sleep(int) durante EventDispashThread, perché il sonno bloccato corrente Thread e in questo caso EventDispashThread, con uscita non-expection alla GUI, più in Concurency in Swing,

se si ha bisogno di qualcosa di dealay, poi aggiungere elementi wrappend in Runneble#Thread, con uscita per la GUI avvolta in invokeLater, o il modo migliore è usare javax.swing.Timer

MODIFICA 1a. ad esempio come bloccare programatically EDT con Thread.sleep (int), perché othewise non si lavora con aspettandosi di uscita per l'interfaccia grafica (codice è molto loonnnger come voglio il codice)

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

public class ShakingButtonDemo implements Runnable { 

    private JButton button; 
    private JRadioButton radioWholeButton; 
    private JRadioButton radioTextOnly; 

    public static void main(String[] args) throws Exception { 
     SwingUtilities.invokeLater(new ShakingButtonDemo()); 
    } 

    @Override 
    public void run() { 
     radioWholeButton = new JRadioButton("The whole button"); 
     radioTextOnly = new JRadioButton("Button text only"); 
     radioWholeButton.setSelected(true); 
     ButtonGroup bg = new ButtonGroup(); 
     bg.add(radioWholeButton); 
     bg.add(radioTextOnly); 
     button = new JButton(" Shake with this Button "); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       shakeButton(radioWholeButton.isSelected()); 
      } 
     }); 
     JPanel p1 = new JPanel(); 
     p1.setBorder(BorderFactory.createTitledBorder("Shake Options")); 
     p1.setLayout(new GridLayout(0, 1)); 
     p1.add(radioWholeButton); 
     p1.add(radioTextOnly); 
     JPanel p2 = new JPanel(); 
     p2.setLayout(new GridLayout(0, 1)); 
     p2.add(button); 
     JFrame frame = new JFrame(); 
     frame.setTitle("Shaking Button Demo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(p1, BorderLayout.NORTH); 
     frame.add(p2, BorderLayout.SOUTH); 
     frame.setSize(240, 160); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    private void shakeButton(final boolean shakeWholeButton) { 
     final Point point = button.getLocation(); 
     final Insets margin = button.getMargin(); 
     final int delay = 75; 
     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       for (int i = 0; i < 30; i++) { 
        try { 
         if (shakeWholeButton) { 
          moveButton(new Point(point.x + 5, point.y)); 
          Thread.sleep(delay); 
          moveButton(point); 
          Thread.sleep(delay); 
          moveButton(new Point(point.x - 5, point.y)); 
          Thread.sleep(delay); 
          moveButton(point); 
          Thread.sleep(delay); 
         } else {// text only 
          setButtonMargin(new Insets(margin.top, margin.left + 3, margin.bottom, margin.right - 2)); 
          Thread.sleep(delay); 
          setButtonMargin(margin); 
          Thread.sleep(delay); 
          setButtonMargin(new Insets(margin.top, margin.left - 2, margin.bottom, margin.right + 3)); 
          Thread.sleep(delay); 
          setButtonMargin(margin); 
          Thread.sleep(delay); 
         } 
        } catch (InterruptedException ex) { 
         ex.printStackTrace(); 
        } 
       } 
      } 
     }; 
     Thread t = new Thread(r); 
     t.start(); 
    } 

    private void moveButton(final Point p) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       button.setLocation(p); 
      } 
     }); 
    } 

    private void setButtonMargin(final Insets margin) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       button.setMargin(margin); 
      } 
     }); 
    } 
} 

EDIT 2 °. con kind hepl di @camickr (somigliante a similair)

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

public class ShakeComponents1 { 

    private JFrame frame = new JFrame(); 
    private final String items[] = {"One", "Two", "Three"}; 
    private Timer timer; 
    private JPanel panel = new JPanel(); 
    private JPanel buttonPanel = new JPanel(); 
    private JButton button = new JButton(" Exit "); 
    private boolean repeats = true; 
    private boolean runs = false; 
    private Color clr[] = {Color.red, Color.blue, Color.magenta}; 
    private Insets initMargin; 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ShakeComponents1().makeUI(); 
      } 
     }); 
    } 

    public void makeUI() { 
     buttonPanel = new JPanel(); 
     buttonPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     buttonPanel.setLayout(new BorderLayout()); 
     button.setPreferredSize(new Dimension(100, 45)); 
     button.setForeground(Color.darkGray); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent event) { 
       Runnable doRun = new Runnable() { 

        @Override 
        public void run() { 
         System.exit(0); 
        } 
       }; 
       SwingUtilities.invokeLater(doRun); 
      } 
     }); 
     button.addMouseListener(new java.awt.event.MouseListener() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
      } 

      @Override 
      public void mousePressed(MouseEvent e) { 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
       if (runs) { 
        SwingUtilities.invokeLater(new Runnable() { 

         @Override 
         public void run() { 
          runs = false; 
          timer.stop(); 
          changePnlBorder(new EmptyBorder(5, 5, 5, 5)); 
          changeBtnForegroung(Color.darkGray); 
         } 
        }); 
       } 
      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
       if (!runs) { 
        timer.start(); 
        runs = true; 
       } 
      } 
     }); 
     buttonPanel.add(button); 
     final Insets margin = button.getMargin(); 
     panel.add(buttonPanel); 
     for (int i = 0; i < 2; i++) { 
      JComboBox combo = new JComboBox(items); 
      combo.setMinimumSize(new Dimension(50, 25)); 
      combo.setMaximumSize(new Dimension(150, 25)); 
      combo.setPreferredSize(new Dimension(100, 25)); 
      combo.addActionListener(new ShakeAction()); 
      panel.add(combo); 
     } 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(panel); 
     frame.pack(); 
     frame.setLocation(50, 50); 
     frame.setVisible(true); 
     timer = new Timer(500, new ShakeAction()); 
     timer.setRepeats(repeats); 
     initMargin = button.getMargin(); 
    } 

    private class ShakeAction extends AbstractAction { 

     private static final long serialVersionUID = 1L; 
     private int noColor = 0; 
     private Border border; 
     private int count = 0; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      timer.start(); 
      if (count > 5) { 
       new Thread(new Runnable() { 

        @Override 
        public void run() { 
         try { 
          Thread.sleep(750); 
          changeBtnForegroung(Color.darkGray); 
          Thread.sleep(750); 
          count = 0; 
          Thread.sleep(750); 
         } catch (Exception e) { 
          System.out.println(e); 
         } 
        } 
       }).start(); 
      } else { 
       new Thread(new Runnable() { 

        @Override 
        public void run() { 
         try { 
          runs = true; 
          if (noColor < 2) { 
           noColor++; 
           changeBtnForegroung(clr[noColor]); 
          } else { 
           noColor = 0; 
           changeBtnForegroung(clr[noColor]); 
          } 
          changeBtnMargin(new Insets(initMargin.top, initMargin.left + 10, initMargin.bottom, initMargin.right - 10)); 
          border = new EmptyBorder(0, 5, 10, 5); 
          changePnlBorder(border); 
          Thread.sleep(100); 
          changeBtnMargin(new Insets(initMargin.top, initMargin.left - 10, initMargin.bottom, initMargin.right + 10)); 
          border = new EmptyBorder(0, 0, 10, 10); 
          changePnlBorder(border); 
          Thread.sleep(100); 
          changeBtnMargin(new Insets(initMargin.top, initMargin.left + 10, initMargin.bottom, initMargin.right - 10)); 
          border = new EmptyBorder(5, 10, 5, 0); 
          changePnlBorder(border); 
          Thread.sleep(100); 
          changeBtnMargin(new Insets(initMargin.top, initMargin.left - 10, initMargin.bottom, initMargin.right + 10)); 
          border = new EmptyBorder(10, 10, 0, 0); 
          changePnlBorder(border); 
          Thread.sleep(100); 
          changeBtnMargin(new Insets(initMargin.top, initMargin.left, initMargin.bottom, initMargin.right)); 
          border = new EmptyBorder(5, 5, 5, 5); 
          changePnlBorder(border); 
          Thread.sleep(100); 
          count++; 
         } catch (Exception e) { 
          System.out.println(e); 
         } 
        } 
       }).start(); 
      } 
     } 
    } 

    private void changePnlBorder(final Border b) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       buttonPanel.setBorder(b); 
       buttonPanel.revalidate(); 
       buttonPanel.repaint(); 
      } 
     }); 
    } 

    private void changeBtnForegroung(final Color c) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       button.setForeground(c); 
      } 
     }); 
    } 

    private void changeBtnMargin(final Insets margin) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       button.setMargin(margin); 
      } 
     }); 
    } 
} 

EDIT terzo.

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

public class DelayedComboBoxTest extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JCheckBox chkA = new JCheckBox("A"); 
    private JCheckBox chkB = new JCheckBox("B"); 
    private JCheckBox chkC = new JCheckBox("C"); 
    private JComboBox cboItems = new JComboBox(); 

    public DelayedComboBoxTest() { 
     super("Delayed ComboBox Test"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     JPanel p = new JPanel(); 
     p.add(chkA); 
     p.add(chkB); 
     p.add(chkC); 
     p.add(cboItems); 
     Container c = getContentPane(); 
     c.setLayout(new BorderLayout()); 
     c.add(p); 
     pack(); 
     cboItems.addPopupMenuListener(new MyPopupMenuListener()); 
    } 

    private void rebuildList() { 
     setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 
     Vector<String> items = new Vector<String>(); 
     if (chkA.isSelected()) { 
      items.add("A"); 
     } 
     if (chkB.isSelected()) { 
      items.add("B"); 
     } 
     if (chkC.isSelected()) { 
      items.add("C"); 
     } 
     cboItems.setModel(new DefaultComboBoxModel(items)); 
     try { 
      new Thread().sleep(2500); // simulate a long transaction 
     } catch (InterruptedException ex) { 
     } 
     setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 
    } 

    public static void main(String[] args) { 
     JFrame f = new DelayedComboBoxTest(); 
     f.setVisible(true); 
    } 

    private class MyPopupMenuListener implements PopupMenuListener { 

     @Override 
     public void popupMenuCanceled(PopupMenuEvent e) { 
     } 

     @Override 
     public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 
     } 

     @Override 
     public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 
      int items = cboItems.getItemCount(); 
      rebuildList(); 

      if (items != cboItems.getItemCount()) { 
       cboItems.hidePopup(); 
       cboItems.showPopup(); 
      } 
     } 
    } 
} 

ma per tutti gli esempi ci deve EDT esistere e con Events nel EventQueue altrimenti semplice compie le opere

+0

+2 per i grandi consigli e -1 per alcuni errori di battitura (sto scherzando). – asgs

+0

hmmm sì, ho problemi con le lingue parlate anche in inglese e Deutch :-), – mKorbel

1

Questo codice spiega come inserire i valori in Swing JList da un gruppo di risultati in Java non. Apporta le modifiche secondo le tue esigenze. spero che questo ti possa aiutare.

try 
    { 
     CreateConnection(); 
     st=con.prepareStatement(QueryString); 
     rs=st.executeQuery(); 
     int i = 0; 
     rs.last(); 
     final String[] strings = new String[rs.getRow()]; 
     rs.first(); 
     strings[i]="Send to All";i++; 
     while (rs.next()) { 
      strings[i] = rs.getString(1); i++; 
     } 
     ToBeFilled.setModel(new javax.swing.AbstractListModel() { 

     public int getSize() { return strings.length; } 
     public Object getElementAt(int i) { return strings[i]; } 
     }); 
     con.close(); 
    } 
    catch(Exception ex) 
    {  
     JOptionPane.showMessageDialog(null, ex.toString()); 
    } 

o solo semplice codice per inserire i valori

jList1.setModel(new javax.swing.AbstractListModel() { 
String[] strings = { "Send to All", "ABC", "DEF" }; 
public int getSize() { return strings.length; } 
public Object getElementAt(int i) { return strings[i]; } 

});

Ricordarsi di aggiungere questo codice dopo initComponents() nella parte superiore della pagina.

+0

Invece di 'rs.first();' devi usare 'rs.beforeFirst();'. Altrimenti perderai il primo record. –

-1
final DefaultListModel model = new DefaultListModel(); 


    final Thread updater = new Thread() { 

     @Override 
     public void run() { 
      for (int i = 0; i < 10; i++) { 
       model.addElement(i); 
       listData.setModel(model); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        throw new RuntimeException(e); 
       } 
      } 
     } 
    }; 
    updater.start(); 
+0

no, è sbagliato: tu ** non devi ** accedere ai componenti swing dall'EDT. E perché stai sostanzialmente copiando la risposta accettata (anche se errata)? ri-impostare il modello dopo ogni inserto migliora esattamente .. nulla dell'errore di base. – kleopatra