2011-09-16 66 views
10

Tôi có một chức năng thực thi khi một nút được nhấp. Giả sử có một vòng lặp để thêm 1 đến 10 vào một số JList. Tôi thêm dữ liệu đó vào DefaultListModel. Nó hoạt động hoàn hảo và các con số được thêm vào. Sau đó, tôi đã thêm một số Thread.sleep(1000) trong vòng lặp. Nhưng đầu ra là khác nhau. Tôi muốn thêm 1 phần tử mỗi giây. Nhưng bây giờ nó chờ 10secs và thêm tất cả 1 đến 10 với nhau vào cuối 10 giây. Tôi có sai ở đâu không?Thêm các phần tử vào JList trong 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) { 
    } 
} 

Trả lời

4

Bạn nên cập nhật danh sách của mình trong một chuỗi riêng biệt nếu không bạn sẽ kết thúc chặn chuỗi gửi sự kiện.

Hãy thử như sau:

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

Tôi vẫn nghĩ rằng 'model.addElement (i)' phải được đưa vào 'invokeLater', vui lòng cập nhật bài đăng của bạn – mKorbel

+0

@mKorbel thực sự? Tôi đang cập nhật mô hình, điều này sẽ lần lượt kích hoạt một sự kiện cho một trình xử lý gọi là 'repaint' trong danh sách. Tôi tin rằng lệnh gọi 'repaint' này sẽ xếp hàng một yêu cầu cho chuỗi gửi sự kiện để gọi' paint', vì vậy nó sẽ an toàn. – dogbane

+3

đúng là không có cập nhật nào trên EDT, tất cả đều được thực hiện qua Thread.sleep (1000) ;, vì tất cả fireXxxXxx đều nằm ngoài EDT – mKorbel

7

không sử dụng, thực sự không sử dụng Thread.sleep(int) trong EventDispashThread, bởi vì giấc ngủ bị khóa hiện tại Thread và trong trường hợp này EventDispashThread, với sản lượng un-Nguyện vọng với GUI, hơn trong Concurency in Swing,

nếu bạn cần một cái gì đó để dealay, sau đó thêm Items wrappend vào Runneble#Thread, với sản lượng để GUI quấn vào invokeLater, hoặc cách tốt nhất là sử dụng javax.swing.Timer

CHỈNH SỬA 1. ví dụ làm thế nào để programatically chặn EDT với Thread.sleep (int), vì othewise không làm việc với hy vọng sản lượng để GUI (mã là rất loonnnger như tôi muốn để mã)

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. với loại hepl bởi @camickr (giống như 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 3rd.

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(); 
      } 
     } 
    } 
} 

nhưng đối với tất cả các ví dụ có phải EDT tồn tại và với Events trong EventQueue khác đơn giản không làm việc

+0

+2 cho các mẹo tuyệt vời và -1 cho một số lỗi chính tả (chỉ đùa). – asgs

+0

hmmm có Tôi có vấn đề với các ngôn ngữ nói tiếng Anh và Deutch quá :-), – mKorbel

1

Mã này giải thích làm thế nào để chèn giá trị trong Swing JList từ một resultset trong java. Thực hiện thay đổi theo yêu cầu của bạn. Hy vọng điều này sẽ giúp bạn.

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()); 
    } 

Hoặc Chỉ cần đơn giản Mã để Chèn giá trị

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]; } 

});

Hãy nhớ thêm mã này vào sau initComponents() ở đầu trang.

+0

Thay vì 'rs.first();' bạn phải sử dụng 'rs.beforeFirst();'. Nếu không, bạn sẽ bỏ lỡ kỷ lục đầu tiên. –

-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

không, điều đó sai: bạn ** không được ** truy cập các thành phần swing ngoài EDT. Và tại sao bạn về cơ bản sao chép câu trả lời được chấp nhận (mặc dù không chính xác)? tái thiết lập mô hình sau mỗi lần chèn cải thiện chính xác .. không có lỗi cơ bản nào. – kleopatra

Các vấn đề liên quan