2013-05-02 140 views
2

我在Swing上看過很多內容,但是我遇到了一個死路,我知道你可以幫助我。 我讀過很多像Updating an JList這樣的問題,但我仍然無能爲力。 我的問題與提到我提到的問題的人相同。我正在製作一臺服務器,用戶將訪問它。 這是我的課程。動態更新Jlist

服務器

private string name; 
private string dateOfAccess; 

@Override 
public String toString() { 
    // TODO Auto-generated method stub 
    return nombreAmigo; 
} 

主要

private DefaultListModel listModel = new DefaultListModel(); 
private JList list=new JList(listModel); 

和我ClientHandler的

public static List<Conexion> clientes=new ArrayList<Conexion>(); 

所以,我要被灌從不同的線程clientes名單,因爲他們連接到我的服務器,我需要在我的Jlist中顯示它們。有關如何更新它的任何建議?我真的被困在這裏 謝謝!

+0

首先,閱讀[併發中的Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – MadProgrammer 2013-05-02 01:43:07

+0

我知道在Swing中使用線程,但這是一個初步版本,沒有正確使用線程。我知道這不是建議,但我需要表明它的工作原理,然後我會解決問題 – 2013-05-02 01:49:11

+0

所以,你需要什麼?事件模型? 'DefaultListModel#addElement'? – MadProgrammer 2013-05-02 01:55:30

回答

5

就我個人而言,我會有某種「客戶經理」負責將所有客戶端整合到一個集中的存儲庫中。這將是你的服務器中的一個單例。可以隨時查詢當前活動用戶列表(和其他管理功能),但應該只有一個活動用戶。

經理然後將通知事件發送給感興趣方(使用觀察模式)。

其中一個派對就是你的用戶界面。當「連接」或「斷開」事件引發的,你需要確保這是同步回事件分派線程之前你嘗試更新列表模式,例如...

​​

;實際實施將回落到什麼是你想要達到你想達到的方式,但是這是基本的概念...

更新了概念性的一例

這是一個基本的,概念性,例如。通過模擬(例如)連接的按鈕引發事件。然後,該事件被髮送到列表中,通過偵聽器接口,其中,所述模型被更新

enter image description here

事件從一些其他源產生並在它們出現時經典觀察者模式

的UI被更新時,
import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.text.DateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.swing.DefaultListModel; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import org.w3c.dom.ls.LSInput; 

public class UpdateListOnEvent { 

    public static void main(String[] args) { 
     new UpdateListOnEvent(); 
    } 

    public UpdateListOnEvent() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class ConnectionEvent { 

     private Date date; 

     public ConnectionEvent(Date date) { 
      this.date = date; 
     } 

     public Date getDate() { 
      return date; 
     } 

    } 

    public interface ConnectionListener { 
     public void connectionEstablished(ConnectionEvent evt); 
    } 

    public class TestPane extends JPanel implements ConnectionListener { 

     private JList list; 
     private DefaultListModel<String> model; 

     public TestPane() { 
      setLayout(new BorderLayout()); 
      model = new DefaultListModel<>(); 
      list = new JList(model); 
      add(new JScrollPane(list)); 
      EventPane eventPane = new EventPane(); 
      eventPane.addConnectionListener(this); 
      add(eventPane, BorderLayout.SOUTH); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.dispose(); 
     } 

     @Override 
     public void connectionEstablished(ConnectionEvent evt) { 
      model.addElement(DateFormat.getDateTimeInstance().format(evt.getDate())); 
     } 
    } 

    public class EventPane extends JPanel { 

     private List<ConnectionListener> listeners; 
     private JButton update; 

     public EventPane() { 
      listeners = new ArrayList<>(5); 
      setLayout(new GridBagLayout()); 
      update = new JButton("Update"); 
      update.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
//     connectionEstablished(new Date()); 
        fireConnectionEstablished(new Date()); 
       } 
      }); 
      add(update); 
     } 

     public void addConnectionListener(ConnectionListener listener) { 
      listeners.add(listener); 
     } 

     public void removeConnectionListener(ConnectionListener listener) { 
      listeners.remove(listener); 
     } 

     protected ConnectionListener[] getConnectionListeners() { 
      return listeners.toArray(new ConnectionListener[listeners.size()]); 
     } 

     protected void fireConnectionEstablished(Date date) { 
      ConnectionListener[] listeners = getConnectionListeners(); 
      if (listeners != null && listeners.length > 0) { 
       ConnectionEvent evt = new ConnectionEvent(date); 
       for (ConnectionListener listener : listeners) { 
        listener.connectionEstablished(evt); 
       } 
      } 
     } 

    } 
} 
+0

完美!感謝這個概念性的例子,現在我很清楚。 – 2013-05-02 02:25:51

+0

DefaultListModel不是通用的,你不能這樣做'DefaultListModel ' – 2014-03-12 13:19:05

+0

@BjornTipling啊,是的,它是['DefaultListModel'](http://docs.oracle.com/javase/7/docs/api/javax/擺動/ DefaultListModel.html)。來自JavaDocs *「Class DefaultListModel 」* - Java 7引入了這個。 – MadProgrammer 2014-03-12 22:39:33