Sorry for not following up earlier.
you pretty much addressed a question i would have asked down the line because you are right the supplied textField and buttons are boring. How do you go about creating your own?
Just draw them as any thing else in your game but don't make them apart of your logic and draw them a-top of everything else, on mouseclicks check if there is a 'component' on that coordinate and dispatch a mouse event to that component. That should make implementing buttons straightforward. as for text fields, have a object in which you track focus, have it contain the object that has focus and what (keyboard)events it's interested in. Append keys to the string resp remove on backspace. All the tedious stuff like validation etc are probably overkill for your game just filter A-Z + -_ or something for names. As for tracking which 'component' should have focus just add additional logic between the 'check-if-theres-a-component-at-that-coordinate' and 'dispatch-event-to-component'
as for my lobby system i have a chat system up and running however now i want each client to be able to see a list of the users connected (and possibly at some point have private chat and challange a specific user to a game). im using arraylist on the server side for all users that are connected but how in the world are you supposed to transfer and entire arraylist to the client and also update it as people come and go?
First you must figure what behaviour you demand from client. Is it really that much of a problem if the user list goes out of sync if so how short should syncing be. Since your using tcp with it's guaranteed delivery as long as your connected, you can also go with sending the chat list on enter and publish modifications(join/leave) to your clients. You can also go hybrid and send modifications and do a complete sync occationally.(Considering your using tcp - going out of sync, given that you can guaranty that publishing is always done, is impossible.)
As for the next step, make sure your familiar with (de)multiplexing - (data and it's context) vs (data + metadata outside of context).(there are perhaps easier explanations of this concept google) Context takes up no space so it's 'free' - how things are put into context is defined by a protocol.
Some examples:
(if ordered:)
Does cas like pie?
yes.
Is Java hard to learn?
no
(from the context you can derive that the answer follows directly after the question. - human protocol - humans aren't physic so it could hardly be any other way)
What where the answers to the teacher's questions?
yes, no
(almost no one is going to answer that way as ppl generally mess up the order - if they remember the questions at all. Also if the questions where asked on different occasions, you might not even be sure you got the same questions)
What where the answers to the teacher's questions?
Java wasn't hard to learn.
Cas likes pie.
As you can probably spot if you can make use of the context you need less text to answer.
An more programming-like example would (I gues) be:
'cas,mark,michael,kev'
vs
'1 cas'
'2 mark'
'3 michael'
'4 kev'
A slightly more complex example:
'100 cas,mark,michael,kev'
'101 cas'
'102 mark'
'103 michael'
'104 kev'
You can derive the same information from both data one just makes use of the context and is smaller. - off-course this only matters if you care about bandwidth esp as constructing information from context might eat away at other resources.
An example would be vectorised graphics, they are smaller but require more processing power to put on the screen.
As you might have picked up from earlier examples transfering a List Strings can be represent a a String itself easily enough. Strings can easily be converted into bytes which can be send. Now you don't have a list of Strings you probably have a list of player objects. Select first what you actually want to share(which data on the server you might keep the ip adress around on the player object - doesn't mean you have to send it to your clients) make up a format convert it to string or directly to bytes.
A pointer here:
class Player {
String name;
...
}
Player one = new Player("Michael");
one.asMessage() -> "Michael"
Player two = new Player("Michael");
one.equals(two) -> false - please note that you did have loss of information here: whilst multiplexing and demultiplexing you lost object identity, you probably don't care about this but in other similar causes you might care.
Simple solution is to define your object identity differently (override equals + hashcode to use name).
Regarding identifying - say you uniquely define players by firstname lastname it's probably not a good idea to repeat that every message as that takes up relatively a lot of space esp if your identifier uses a lot of fields, now dba's figured out long ago that using a unique number is usually more efficient.
A final timbit of information: a integer 1000 takes a lot less bytes as four chars: '1' '0' '0' '0'. - again this might or might not matter also if your lazy you can always just compress your stream characters

though hand tuned 'compression' is probably more efficient.
I would recommend sticking as doing clever things with bytes is probably premature optimalisation.
hope these pointers help, feel free to specify where I messed up -> made it way too obscure.
//edit hmm should probably add a timbit about separators and escape
characters data