2013-05-02 137 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