2015-02-07 107 views
1

我有一个带有多线程的TCP服务器,可以通过cli来处理它。在多个JPanel上运行多个线程并切换它们

现在我想为它编写一个GUI,以便我可以轻松启动,观察,管理和退出该多线程服务器的特定实例。首先我想到了JTable,那也是我的第一个问题:

在JTable中处理多个套接字(而不是线程)上的多个serverthread是否是一种好的方法(或者甚至可能),并且我能够向它发送数据根据套接字活动更新单独的行?我的意思是当每一行代表一个正在运行的serverthread时,用户应该能够点击它,启动一个新的(将被添加到列表中)查看字段中的socketstatus(不管那将是),看看有多少客户是连接在一起的,甚至可以通过桌子阻止特定的线程?

我的第二个问题是:

当我开始实现它,我上面描述的方式,会发生什么情况的JTable,当我更新与另一个接口活跃JPanel并再​​次切换回正在运行的线程?例如,我有一个接口用于概述所有实例,另一个接口用于获取单个实例的详细信息。所有的线程会被中断吗?或者他们可以再次与桌面通信吗?还是使用cardLayout更好?

当我更换cardlayout上的卡时,此卡上正在运行的某个东西(例如带有运行套接字线的JTable)是否会被中断或停止,或者我能否更新JTable中的statusdata?所以套接字应该能够写入和更新数据到表中。

现在我最后一个问题,感谢阅读这么久。在试图找出上述所有问题的答案时,我尝试了一个简单的JPanel切换帧,每个面板上都有一个JTextarea,它可以写入100行,间隔1000毫秒。然后,我想切换面板,看看这个任务是否中断。不幸的是,我甚至无法把这个工作。

在一个外部类MyPanel中,我使用单独的配置启动一个JPanel并将它添加到主框架中。

for循环是只是为了测试:

class MyPanel extends JPanel { 

public static JTextArea tArea; 

    public MyPanel(String config) { 

    JButton testButton = new JButton(config); 
    add(testButton); 

    tArea = new JTextArea();  
    JScrollPane scroll = new JScrollPane(tArea); 
    add(scroll, BorderLayout.CENTER); 

    for (int i = 0 ; i < 50 ; i ++) { 
     tArea.append("test \n") ; 
     try { Thread.sleep(2000); } catch(InterruptedException ie) {} 
    } 

    setVisible(true); 
    revalidate(); 
    repaint(); 

    } 

} 

但我认为,这是完全错误的,因为我把它叫做之前重新验证并重新绘制:(与主机内我要发起这样的说法:

JMenuItem menuItem = new JMenuItem("Test"); 
menuItem.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent event) { 
    MyPanel dynamicPanel = new MyPanel("Test"); 
    contentContainer.removeAll(); 
    contentContainer.add(dynamicPanel); 
    contentContainer.revalidate(); 
    contentContainer.repaint(); 
    } 
}); 
+0

你需要知道的第一件事,Swing是一个单线程的框架,不是线程安全的,请参阅Concurrency in SwingWorker Threads and SwingWorker。这意味着所有与UI的更新和交互都必须在UI线程(Event Dispatching Thread)内完成,请参见[Swing中的并发](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/ ) – MadProgrammer 2015-02-07 03:33:14

回答

2

你需要知道的第一件事,Swing是一个单线程框架,并且不是线程安全的,这意味着所有的UI更新和交互必须来自UI线程(Event Dispatching Thread)见Concurrency in Swing

它是一个很好的方式(或者甚至可能)处理JTable中多个套接字(而不是线程)上的多个serverthreads,并且我能够根据套接字活动向它发送更新单个行的数据?我的意思是当每一行代表一个正在运行的serverthread时,用户应该能够点击它,启动一个新的(将被添加到列表中)查看字段中的socketstatus(无论是什么),看看有多少客户是连接在一起的,甚至可以通过桌子阻止特定的线程?

老实说,我不认为这很重要,你有问题是从你的线程/套接字获取信息到你的用户界面。我会考虑做一个Thread,它的唯一目的是轮询所有其他线程/套接字以获取信息,然后将该信息与UI同步,确保不会在此过程中破坏Swing的单线程规则。根据您的设计,A SwingWorker可能是一个不错的选择。

我不会考虑让每个线程单独向用户界面发送信息的原因是,这将是压倒美国东部时间并导致它滞后的一个非常好的方法,同时它试图处理大量的数据当我开始实现它,我上面描述的方式,会发生什么 到JTable,当我与另一个接口更新活动的JPanel 并再次切换回正在运行的线程系统可能会造成

?例如,我有一个 接口用于概述所有实例,另一个用于其单个实例上的另一个 详细信息。将所有线程中断或 他们可以再次沟通到表后?或者是更好地 使用cardLayout?

当我在cardlayout这张牌上更改该卡是什么 运行(当然,一个JTable与运行socketthreads)才具 中断或停止,或者我可以在JTable 更新statusdata了吗?所以套接字应该能够将数据写入并更新至全部的表。

基于上面给出的描述,基本上没有任何事情会发生在你在后台运行的线程中,因为它们与UI断开了连接。 “轮询”线程仍然在运行,并且仍然会向桌面发送更新(我希望通过TableModel),但是,因为它实际上并不在屏幕上可见,所以它不会被绘制,并且“不应该”产生不利影响系统的性能。

这提出了某种“状态”模型的概念。这个模型实际上可以用来描述单个线程的状态,然后这个模型可以由一个“状态”管理器来管理,它可以让你访问这些信息(以及实际的线程)。轮询线程会从正在运行的线程/套接字获取信息并更新该线程的关联“状态”模型,这意味着您可以挂起整个UI并知道在访问它时,它只能从内部修改EDT的背景 - 没有死锁或竞赛状况。作为一个想法

现在我最后一个问题,感谢阅读这么久。在尝试 发现上述所有问题的答案时,我尝试了一个简单的 JPanel切换帧,每个面板上有一个JTextarea,写入100 行之间有1000ms的中断。然后我想切换面板 并查看该任务是否中断。该死的我是这样的noob,我不能 甚至把这个工作。

在外部类MyPanel中,我正在启动一个带有个人 配置的JPanel,并将其添加到主框架中。

那是因为你的代码是阻断事件指派线程,它负责处理事件队列,它也承载了重绘事件(除其他事项外),这意味着,当循环运行时,用户界面无法更新(或与之交互)。

该代码最好用SwingWorker

更多细节

+0

谢谢你,我现在读了大约2小时,但我不知道如何处理它在我的情况。有没有一个正在运行的代码,你可以告诉我或者是那么多的代码?无论如何,由于你的悠久而详细的解释。 – BrainWorx 2015-02-07 05:50:39

+0

它不是100%相同,但是像[this](http://stackoverflow.com/questions/13753562/adding-progress-bar-to-each-table-cell-for-file-progress-java/13755155 #13755155)它有许多'Thread'正在运行,它更新了表。 – MadProgrammer 2015-02-07 05:52:33