BrainWorx
BrainWorx

Reputation: 103

Running multiple Threads on multiple JPanels and switch them

I have a TCP Server with multithreading and can handle it from the 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. First I thought on JTable and thats also my first question:

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? 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?

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? 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?

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? 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. 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.

The for loop is just for testing:

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

Upvotes: 1

Views: 654

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347244

First thing you need to know, Swing is a single threaded framework and is NOT thread safe. 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

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? 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?

Honestly, I don't think it matters, the problem you have is getting information from your threads/sockets to your 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. A SwingWorker might be a good choice here, depending on your design.

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

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? 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?

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? 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. 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.

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. 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. 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.

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).

The code would be better served with a SwingWorker.

See Concurrency in Swing and Worker Threads and SwingWorker for more details

Upvotes: 2

Related Questions