简体   繁体   English

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

[英]Running multiple Threads on multiple JPanels and switch them

I have a TCP Server with multithreading and can handle it from the cli. 我有一个带多线程的TCP Server,可以从cli处理它。

Now I want to write a GUI for it so that I can easily start, watch, manage and quit specific instances of that multithreaded server. 现在,我想为其编写一个GUI,以便可以轻松地启动,监视,管理和退出该多线程服务器的特定实例。 First I thought on JTable and thats also my first question: 首先,我想到了JTable,这也是我的第一个问题:

Is it a good way (or even possible) to handle multiple serverthreads on multiple sockets (not threads) inside a JTable and am I be able to send data to it to update individual rows depending on socketactivities? 在JTable内处理多个套接字(而不是线程)上的多个服务器线程是否是一种好方法(甚至可能),并且我能够根据套接字活动向其发送数据以更新单个行吗? I mean when every row stands for a running serverthread, the user should be able to click on it, start a new one (that will be added to the list) see the socketstatus (whatever that will be) in a field, see how many clients are connected and even be able to stop a specific thread throu that table? 我的意思是,当每一行代表一个正在运行的服务器线程时,用户应该能够单击它,启动一个新的服务器线程(将添加到列表中),在字段中查看socketstatus(无论如何),查看有多少客户端已连接,甚至可以通过该表停止特定线程?

My second question is: 我的第二个问题是:

When I start implementing it the way I described above, what happens to the jtable and the running threads when I update the active JPanel with another interface and switch back again? 当我以上述方式开始实现它时,用另一个接口更新活动的JPanel并再​​次切换回去时,jtable和正在运行的线程会怎样? For example, I have one interface for an overview about all instances and another one for details on a single instance of it. 例如,我有一个界面可概述所有实例,而另一个界面可提供有关单个实例的详细信息。 Will all threads be interrupted or can they communicate to the Table after that again? 是所有线程都会中断还是在此之后又可以与表通信? Or is it better to use a cardLayout? 还是使用cardLayout更好?

When I change the card on a cardlayout and on this card is something running (for ex. A JTable with running socketthreads) will they be interrupted or stopped or can i update statusdata in the JTable anymore? 当我在cardlayout上更换卡时,该卡上正在运行某些东西(例如,具有运行套接字线程的JTable),它们会被中断或停止,还是可以再更新JTable中的statusdata? So the sockets should be able to write and update data to the table over all. 因此,套接字应该能够全部向表写入和更新数据。

And now my last question, thanks for reading so long. 现在是我的最后一个问题,感谢您阅读了这么长时间。 while trying to discover answers for all of my questions above, I tried a simple JPanel switching Frame with a JTextarea on each Panel that writes 100 lines with a 1000ms break between. 在尝试找到上述所有问题的答案时,我尝试了一个简单的JPanel切换框架,每个面板上都有一个JTextarea,可写入100行,且间隔为1000ms。 Then I wanted to switch the panels and see if that task was interrupted. 然后,我想切换面板,看看该任务是否被中断。 Unfortunately, I can't even bring this to work. 不幸的是,我什至无法解决这个问题。

In an external class MyPanel I am initiating a JPanel with individual configuration and add it to the main frame. 在外部类MyPanel中,我将启动具有单独配置的JPanel并将其添加到主框架。

The for loop is just for testing: 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();

  }

}

But I think, that is completely wrong because I call it before revalidate and repaint :( And inside the mainframe I want to initiating it that way: 但是我认为,这是完全错误的,因为我在重新验证和重新绘制之前调用它:(在大型机内部,我想以这种方式启动它:

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

First thing you need to know, Swing is a single threaded framework and is NOT thread safe. 您需要了解的第一件事,Swing是一个单线程框架,并且不是线程安全的。 This means that all updates and interactions with the UI MUST be made from within the UI thread (the Event Dispatching Thread), see Concurrency in Swing 这意味着所有与UI的更新和交互都必须在UI线程(事件调度线程)内进行,请参见Swing中的并发

is it a good way (or even possible) to handle multiple serverthreads on multiple sockets (not threads) inside a JTable and am i be able to send data to it to update individual rows depending on socketactivities? 在JTable中处理多个套接字(而非线程)上的多个服务器线程是否是一种好方法(甚至可能),并且我能够根据套接字活动向其发送数据以更新单个行吗? i mean when every row stands for a running serverthread, the user should be able to click on it, start a new one (that will be added to the list) see the socketstatus (whatever that will be) in a field, see how many clients are connected and even be able to stop a specific thread throu that table? 我的意思是,每行代表一个正在运行的服务器线程时,用户应该可以单击它,开始一个新的(将被添加到列表中),在字段中查看socketstatus(无论将是什么),查看有多少客户端已连接,甚至可以通过该表停止特定线程?

Honestly, I don't think it matters, the problem you have is getting information from your threads/sockets to your UI. 老实说,我认为这并不重要,您遇到的问题是从线程/套接字向UI获取信息。 What I would consider doing is having a Thread whose sole purpose is to poll all the other threads/sockets for information and then synchronise that information with the UI, making sure not to break the single thread rules of Swing in the process. 我要考虑做的是拥有一个Thread其唯一目的是轮询所有其他线程/套接字以获取信息,然后将该信息与UI同步,以确保在该过程中不违反Swing的单线程规则。 A SwingWorker might be a good choice here, depending on your design. 根据您的设计,在这里SwingWorker可能是一个不错的选择。

The reason I would not consider having each thread sending information to the UI individually is that this would be a really good way to overwhelm the EDT and cause it to lag, while it tried to process the copious amount of data that your system might create 我不考虑让每个线程分别向UI发送信息的原因是,这将是淹没EDT并导致其滞后的一种很好的方法,而它试图处理系统可能创建的大量数据

when i start implementing it the way i described above, what happens to the jtable and the running threads when i update the active JPanel with another interface and switch back again? 当我以上述方式开始实现它时,当我使用另一个接口更新活动的JPanel并再​​次切换回时,jtable和正在运行的线程会怎样? for example i have one interface for an overview about all instances and another one for details on a single instance of it. 例如,我有一个界面可提供所有实例的概述,而另一个界面可提供有关单个实例的详细信息。 will all threads be interrupted or can they communicate to the Table after that again? 所有线程都将被中断,还是可以在此之后再次与表通信? or is it better to use a cardLayout? 还是使用cardLayout更好?

when i change the card on a cardlayout and on this card is something running (for ex. a JTable with running socketthreads) will they be interrupted or stopped or can i update statusdata in the JTable anymore? 当我在cardlayout上更换卡时,在该卡上正在运行的东西(例如,具有运行套接字线程的JTable)会被中断或停止,还是可以再更新JTable中的statusdata? so the sockets should be able to write and update data to the table over all. 因此套接字应该能够将数据全部写入和更新到表中。

Based on the description I gave above, essentially nothing will happen to the threads you have running in the background, because they are disconnected from the UI. 根据我上面的描述,在后台运行的线程基本上不会发生任何事情,因为它们已与UI断开连接。 The "polling" thread will still be running and will still send updates to the table (I hope via the TableModel ), but, because it's not actually visible on the screen, it won't be painted and "should't" adversely effect the performance of the system. “轮询”线程将仍在运行,并且仍将向表发送更新(我希望通过TableModel ),但是,由于它实际上在屏幕上不可见,因此不会被绘制,并且“不应”产生不利影响系统的性能。

This brings up the idea of a "state" model of some kind. 这提出了某种“状态”模型的思想。 This model could actually be used to describe the state of an individual thread, this could then be managed by a "state" manager, which gives you access to this information (as well as the actual thread). 该模型实际上可以用于描述单个线程的状态,然后可以由“状态”管理器进行管理,该管理器使您可以访问此信息(以及实际线程)。 The polling thread would take information from the running thread/socket and update the associated "state" model for that thread, this means you can hang your entire UI of this and know that while you are accessing it, it's only ever been modified from within the context of the EDT - no dead locking or race conditions. 轮询线程将从正在运行的线程/套接字获取信息并更新该线程的关联“状态”模型,这意味着您可以挂起它的整个UI,并且知道在访问它时,只能从内部对其进行修改EDT的上下文-没有死锁或竞争条件。 As an idea 作为一个想法

And now my last question, thanks for reading so long. 现在是我的最后一个问题,感谢您阅读了这么长时间。 while trying to discover answers for all of my questions above, i tried a simple JPanel switching Frame with a JTextarea on each Panel that writes 100 lines with a 1000ms break between. 在尝试发现上述所有问题的答案时,我尝试了一个简单的JPanel切换框架,每个面板上都有一个JTextarea,可写入100行,且间隔为1000ms。 then i wanted to switch the panels and see if that task was interrupted. 然后我想切换面板,看看该任务是否被中断。 damn i'm such a noob, i cant even bring this to work. 该死的我真是个菜鸟,我什至不能带这个去上班。

In an external class MyPanel i am initiating a JPanel with individual configuration and add it to the main frame. 在外部类MyPanel中,我将启动具有单独配置的JPanel并将其添加到主框架。

That's because your code is blocking the Event Dispatching Thread, which is responsible for processing the Event Queue, which is also carries the repaint events (amongst other things), this means, that while the loop is running, the UI can't be updated (or interacted with). 这是因为您的代码阻塞了事件处理线程,该线程负责处理事件队列,该事件队列还携带重绘事件(除其他事项外),这意味着,在循环运行时,无法更新UI (或与之互动)。

The code would be better served with a SwingWorker . 使用SwingWorker可以更好地提供代码。

See Concurrency in Swing and Worker Threads and SwingWorker for more details 有关更多详细信息,请参见SwingWorker线程中的 并发 和SwingWorker

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM