在多个JPanel上运行多个线程并切换它们

时间:2015-02-07 02:43:14

标签: java multithreading swing

我有一个带有多线程的TCP服务器,可以从cli处理它。

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

在JTable内的多个套接字(而不是线程)上处理多个serverthread是一种好方法(甚至可能),我是否能够根据socketactivities向其发送数据以更新各行?我的意思是当每一行代表一个正在运行的serverthread时,用户应该能够点击它,开始一个新的(将被添加到列表中)看到一个字段中的socketstatus(无论是什么),看看有多少客户端是连接的,甚至可以通过该表停止特定的线程?

我的第二个问题是:

当我按照上面描述的方式开始实现它时,当我用另一个接口更新活动JPanel并再​​次切换回来时,jtable和正在运行的线程会发生什么?例如,我有一个接口用于概述所有实例,另一个接口用于单个实例的详细信息。是否所有线程都会被中断,或者之后是否可以与Table通信?或者使用cardLayout更好吗?

当我在cardlayout上更换卡并且在这张卡上运行时(例如,带有运行套接字线程的JTable)它们是否会被中断或停止,或者我是否可以更新JTable中的statusdata?因此套接字应该能够在所有表上写入和更新数据。

现在是我的最后一个问题,感谢阅读这么长时间。在尝试发现上述所有问题的答案时,我尝试了一个简单的JPanel切换框架,每个面板上有一个JTextarea,写入100行,间隔1000ms。然后我想切换面板,看看那个任务是否被中断了。不幸的是,我甚至无法将其付诸实践。

在外部类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();
  }
});

1 个答案:

答案 0 :(得分:2)

首先你需要知道,Swing是一个单线程框架,并不是线程安全的。这意味着所有与UI的更新和交互必须在UI线程(事件调度线程)中进行,请参阅Concurrency in Swing

  

在JTable中的多个套接字(而不是线程)上处理多个serverthread是一种好方法(甚至是可能的),我是否能够根据socketactivities向其发送数据以更新各行?我的意思是当每一行代表一个正在运行的serverthread时,用户应该能够点击它,开始一个新的(将被添加到列表中)看到一个字段中的socketstatus(无论是什么),看看有多少客户端是连接的,甚至可以通过该表停止特定的线程?

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

我不会考虑让每个线程单独向UI发送信息的原因是,这将是一个非常好的方法来压倒EDT并导致它滞后,同时它试图处理大量数据系统可能会创建

  

当我开始按照上面描述的方式实现它时,会发生什么   当我更新活动的JPanel时,jtable和正在运行的线程   用另一个界面再切换回去?例如,我有一个   接口,用于概述所有实例和另一个实例   关于它的单个实例的详细信息。将所有线程中断或   他们可以再次与桌子沟通吗?或者它更好   使用cardLayout?

     

当我在卡片布局上更换卡片时,这张卡片就是这样的   运行(例如,运行socketthreads的JTable)将是   中断或停止或我可以更新JTable中的statusdata   了吗?所以套接字应该能够写入和更新数据   表格全部。

根据我上面给出的描述,您在后台运行的线程基本上什么都不会发生,因为它们与UI断开连接。 &#34;民意调查&#34;线程仍然会运行,并仍然会向表发送更新(我希望通过TableModel),但是,因为它在屏幕上实际上不可见,所以它不会被绘制和& #34;应该&#39; T&#34;对系统的性能产生不利影响。

这提出了一个&#34;州&#34;某种模式。该模型实际上可以用于描述单个线程的状态,然后可以通过&#34;状态&#34;来管理。 manager,它允许您访问此信息(以及实际线程)。轮询线程将从正在运行的线程/套接字获取信息并更新相关的&#34;状态&#34;该线程的模型,这意味着您可以挂起整个UI,并知道在访问它时,它只能在EDT的上下文中修改 - 没有死锁或竞争条件。作为一个想法

  

现在是我的最后一个问题,感谢阅读这么长时间。在尝试时   发现上述所有问题的答案,我试过一个简单的问题   JPanel在每个写入100的Panel上切换带有JTextarea的Frame   在1000毫秒之间休息的线。然后我想切换面板   并查看该任务是否被中断。该死的我是一个菜鸟,我不能   甚至把它带到了工作中。

     

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

那是因为你的代码阻塞了事件调度线程,事件调度线程负责处理事件队列,事件队列也带有重绘事件(除其他外),这意味着,当循环运行时,用户界面无法更新(或与之互动)。

使用SwingWorker可以更好地提供代码。

有关详细信息,请参阅Concurrency in SwingWorker Threads and SwingWorker