简体   繁体   中英

best way to pass GUI references to other classes that edit them

I have a client/server MMORPG I am working on and I want to do things correctly(as impossible as it is). My questions is: What is the best way to pass references to my GUI items(JInternalFrame, JPanels, etc.) to my class that listens to commands/replies from the server. Right now this is what I have going on, which will soon grow quite large.

MyCommandReciever(DataInputStream commandIn, DefaultListModel modelUserList, JInternalFrame skillsFrame, Container skillsPanelHeader, Container skillsPanelContent, JInternalFrame characterFrame){
    this.commandIn = commandIn;
    this.modelUserList = modelUserList;
    this.skillsFrame = skillsFrame;
    this.skillsPanelHeader = skillsPanelHeader;
    this.skillsPanelContent = skillsPanelContent;
    this.characterFrame = characterFrame;
}

I don't want to keep passing more and more JInternalFrames to MyCommandReciever.

Does it make sense to do something like this??

Component[] c = panel.getComponents();
for(int i = 0; i < c.length; i++) {
    System.out.println(c[i].getClass().getSimpleName());
}

Or is there a way that I can create an instance of my Main class(which includes my GUI), from within my main class, and pass that to MyCommandReciever so it has access to everything(maybe like this):

MyCommandReciever(DataInputStream commandIn, DefaultListModel modelUserList, MyClient m){

If this last approach is the way to go(which I'm hoping it isn't, do I need to pass it from the class that creates an instance of it(Character.java creates instance of MyClient.java), to itself(MyClient.java), and then pass it from MyClient.java to MyCommandReciever.java?

Sorry if that last question was too confusing... let me break it down:

Inside Character.java:

if (playSuccess.contains("true")){
    z++; //to turn off the commandIn functionality in Character screen when MyClient is running
    frame.dispose();
    new MyClient(accountName, playWho, commandIn, messageIn, commandOut, messageOut, sM, sC);

Inside MyClient.java:

commandReciever = new MyCommandReciever(commandIn, modelUserList, skillsFrame, skillsPanelHeader, skillsPanelContent, characterFrame);

so in the character.java I would have to create instance of MyClient(and assign to variable) but at the same time pass that assigned variable to MyClient. (now that I'm typing this it doesn't even seem possible).

Please guide me :D Clearly I wrapped my brain on this last idea.

What you could do is use the pattern called "observer" or "event source":

  1. Define an interface between the command receiver and the main class, with methods that the command receiver should call when something interesting happens.
  2. (Obviously the command receiver should hold a refence to an object that implements this interface to be able to send events.)
  3. Implement the interface in the main class--either by the main class itself or by a nested class--and respond to events from the command receiver by updating the interface. Pass the implementation to the command receiver.

This way the command receiver and user interface are completely decoupled, and if at some point you decide to use something other than JInternalFrame for data display you don't have to change code in hundreds of places.

You could also consider using MVC or one of its many siblings..

This is the approach that I decided to go with. Thanks for the other advice however it seemed a bit complex for my needs:

In my main gui class:

commandReciever = new MyCommandReciever(commandIn, this); //passing in instance of my main gui class

In my command receiever class(class that talks to server):

MyClient m; //for access to the GUI pieces

MyCommandReciever(DataInputStream commandIn, MyClient m){
    this.commandIn = commandIn;
    this.m = m;
}

Example of how I edit my main gui class's components from my command receiver class:

m.modelUserList.clear();
for (int i = 0; i < CharactersList.length; i++){
    m.modelUserList.addElement(CharactersList[i]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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