3

I have a Lanterna terminal app.

With threads I would like to fill up a window with different Panels and read key input accordingly.

Using:

thread1 = new ModuleThreads(screen,"Locations","addRightPanel");
thread2 = new ModuleThreads(screen,"Commands","addCenterPanel");
thread1.start();
thread2.start();

The first thread shows in the rightPanel the "Locations" menu. the menu contains: "press a for exit." The thread works. The menu appears, and pressing a exits the program.

Now the second Thread doesn't appear nor listens to the matching key pressed:"press b to exit." Also I used reflection to be able to change menu contents easily.(Its a personal project anyway...:)) The problem is that only the first thread1 is shown in the ui. The reflection just works. On itself thread2 works just fine. But just as a single thread.

public class ModuleThreads extends Thread{

Screen screen;
String myclass,panel;
Class noparams[]={};
Class moduleClass,panelClass;
Class[] paramScreen;
Class[] myPanelClass;
Constructor constructor,moduleConstructor;
Object moduleObject,panelObject;
Method panelGetView,panelMethod,moduleMethod;
Panel mypanel;
private Thread thread1;

public ModuleThreads(Screen screen,String myclass,String panel){

this.screen=screen;
this.myclass=myclass;
this.panel=panel;


//class aanmaken van Screen.class
paramScreen = new Class[1];
paramScreen[0] = Screen.class;
    myPanelClass = new Class[1];
myPanelClass[0] = Panel.class;
thread1 = new Thread(this);
thread1.start();
try{
    moduleClass = Class.forName("app.modules."+this.myclass);
    //package name er voor plakken.
    moduleObject = moduleClass.newInstance();
    moduleMethod = 
    moduleClass.getDeclaredMethod("readInput",paramScreen);
    moduleConstructor = moduleClass.getConstructor();
    panelClass = Class.forName("app.view.MainView");
    constructor = panelClass.getConstructor(Screen.class);
    panelObject= constructor.newInstance(this.screen);
    panelGetView = moduleClass.getDeclaredMethod("getView",noparams);
    panelMethod = 
    panelClass.getDeclaredMethod(this.panel,myPanelClass);


    mypanel =  (Panel) panelGetView.invoke(moduleObject,null);
    panelMethod.invoke(panelObject, mypanel);



    moduleMethod.invoke(moduleObject,this.screen);

}catch(Exception e){
    e.printStackTrace();
}
}
public void start(){

}
@Override
public void run(){

try{


    mypanel =  (Panel) panelGetView.invoke(moduleObject,null);
    panelMethod.invoke(panelObject, mypanel);
    moduleMethod.invoke(moduleObject,this.screen);

}catch(Exception ex){
    ex.printStackTrace();
}
}

}

What am I doing wrong? Why does only thread 1 or thread 2 appear, and not both, with both key listeners?

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
Peter-TI
  • 91
  • 8

2 Answers2

1

1) Why do you override the start() method of Thread like that :

public void start(){    
}

By doing it you prevent the run() method from being invoked. From the javadoc :

void java.lang.Thread.start()

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread

2) You start twice each thread.

thread1 = new ModuleThreads(screen,"Locations","addRightPanel");
thread2 = new ModuleThreads(screen,"Commands","addCenterPanel");
thread1.start();
thread2.start();

and

public ModuleThreads(Screen screen,String myclass,String panel){
...
thread1 = new Thread(this);
thread1.start();
...

You should start once your threads. You could remove the start() call performed in the ModuleThreads constructor as it is more suitable to decide outside the thread when the thread should be started.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • I have applied these changes. I had the code like this before. I end up having the same result. I guess passing the screen are copies of the object and not the same object. So executing these threads makes me have two copies of screen. So I need to have the two threads to modify the same screen object. – Peter-TI Jan 16 '17 at 15:01
0

I think i found a solution:

link in using and modifying same object in different threads

So instead of:

        thread1 = new ModuleThreads(screen,"Locations","addRightPanel");
        thread2 = new ModuleThreads(screen,"Commands","addCenterPanel");
        thread1.start();
        thread2.start();

I would have something like:

        Screen screen =  new TerminalScreen(terminal);

       thread1 = new ModuleThreads() 
        { public void run (){screen.updatePanels("Locations","addRightPanel");
                            screen.readInput();
                           }
        };
        thread2 = new ModuleThreads() 
        { public void run (){screen.updatePanels("Commands","addCenterPanel");
                            screen.readInput();
                           }
        };

    thread1.start();
    thread2.start();

I think this principle would do the trick?

Community
  • 1
  • 1
Peter-TI
  • 91
  • 8