Java SWT control modified doesn't change - java

I'm making a couple of programs for a chat: a server and the client.
Both of them have a GUI made with SWT. Server always runs great.
In the other side, the GUI of the client doesn't. When I connect to the server, the client ask about the connected clients, and the server answer with X messages, one with each name. I've checked the server really send the names and the client receives them.
But, even when I've received the messages, sometimes the GUI shows them, and other times it doesn't. Even in the same execution, some names can be put into the GUI and others can not.
I think It could be a problem of SWT, especially about the method to modify the GUI.
As You would have supposed, I'm working with threads, even to modify the GUI. Because I want to modify GUI from a thread, I've to use the method "Display.asyncExec", so every time I do a change on GUI I do something like this:
OurDisplay.asyncExec( new Runnable() {
public void run()
{
MyText.append("#The user " + OurName + " has asked us about other clients\n");
}
});
I don't know where can be the problem, because the Server uses the same but It runs fine.
Maybe I would notice, that in the main (both of them, server and client) program I'm using this other code in order to not finish the program execution before I close the window (Shell) i'm working with:
while (!ServerShell.isDisposed())
{
if (!ourDisplay.readAndDispatch())
ourDisplay.sleep();
}
Any idea?
Thanks
- EDIT - Answer to Comment nÂș1 - (I can't answer with a comment, i don't know why)
I didn't. I've tried with "syncExec" method in order to have my thread waiting the modification of the GUI. However this neither does work.
I don't know how to see the Display queue, I'm looking for it. Thanks for the idea.
And I will try to catch the exceptions that the Runnable can be throwing. I will report news.

Make up some try/catch, you will see a typical problem:
trying to update a GUI while it is buisy.
The exception is surpressed until you let it rip.
I assume you've got a Eclipse RCP Application there - right?
The please use the Eclipse Job processing for updating the GUI (UIJob).
That works thousand times better than those asyncExec(Runnable) calls, cause the Eclipse Framework will figure the timing with the GUI updates.
http://www.vogella.com/articles/EclipseJobs/article.html
Lars Vogel has a great Tutorial on the Job processing thingy.

Related

java.awt.Robot.waitForIdle() is unrealiable

We are seeing frequent timing issues in our nightly UI tests. The tests often fail because events performed by the java.awt.Robot have not completed before the test code tries to verifying the results.
We are code like using:
Point p = cb.getLocationOnScreen();
int m = 5;
if (cb.getWidth()<5||cb.getHeight()<5)
m=3;
System.out.println("Click at " + (p.x+m) + "," + (p.y+m));
robot.mouseMove(p.x + m, p.y + m);
robot.mousePress(MouseEvent.BUTTON1_MASK);
robot.mouseRelease(MouseEvent.BUTTON1_MASK);
robot.waitForIdle();
Thread.sleep(100);
// Verify results...
We keep having the bump up the Thread.sleep to ensure things complete on the event thread (things like clicking on a button or typing text) despite the java.awt.Robot.waitForIdle() call.
I found this question (Does java.awt.Robot.waitForIdle() wait for events to be dispatched?) which says to use java.awt.Toolkit.realSync(), but this is not an accessible method and with Java 9 coming, I'd rather not add any unnecessary reflection to our tests.
Are there better solutions? Or do people use realSync() or just increase the wait time until tests pass reliably?
UPDATE
I tried using sun.awt.SunToolkit.realSync(), but it is hanging in some tests and never returning. It looks like the EventThread is painting borders and such.
Looks like my only solution is to bump the sleep time up until the test can actually pass reliably. Yuck.
UPDATE 2
I figured out the first hang I had with realSync(). It was a problem in our code, where some paint code called a get method that called a set method which queued up another paint. Repeat forever.
Fixed our code and realSync() worked for a while, sort of. It still seems to return before it should. No idea why and I have no work around.
Also, I've seen realSync() hang and time out on my Linux box running under Java 1.7, but it works under Java 1.8. Very reliable tool here. /s
So, back the to original question. What is a decent way to tell when UI updates are done?
I came to the conclusion that I did need to use SunToolkit.realSync() and it seems to work correctly for Java 9 as well.
It seems, although I couldn't find any hard evidence, that realSync() waits for all graphics related threads while Robot.waitForIdle() and SwingUntilities.invokeLater() only wait for the Java EventThread to finish it's work.
If someone comes up with a better answer, I'd being will to accept that instead of my answer.

Is the jtextarea.settext() method buffered?

i'm not a java developer, but i need to write a small applet to upload file via ftp
(actually, i'm a web developer). Everything works fine, except for the way that feedback messages are displayed. Let me explain with an example:
if i wrote sometingh like that, inside a method (controlled by a click event)
//....
myJpanel.setText("Connecting to remote server");
//actually, it's surrounded by try-catch statement
myFtpObject.connect(); //this is taken from a third part package
myJpanel.setText("Connected")
When I try to run this code the connection is set (after that connection I upload files with no problem), but inside the Jpanel myJpanel I immeditaly read "connected" (altought it takes several seconds to connect) and I never see the "Connecting to remote server" string.
It sounds to me like the Jpanel setText method is buffered in some way.
How can I display messages in real time?
(I've tried to do System.out.println for testing and it worked great!)
Thanks
if i wrote sometingh like that inside a method (controlled by a click event)
Code executed in an event listener executes on the EDT. The problem is that the long running task is blocking the Swing EDT. So the GUI never gets a chance to repaint itself.
Read the section from the Swing tutorial on Concurrency for more information and for a solution. The basic solution is to create a separate thread for the long running task.
This is also why System.out.println(..) works, because it executes on a different Thread.

IO thread alert GUI thread if error occures

I have a client/server question that i am trying to figure out the best solution for.
If a client ever gets disconnected from the server, for any reason, i would like a way for the input output thread to alert the gui thread that something went wrong, and thus have the gui thread print an error and gracefully handle it (probably drop back out to the login gui). After the initial gui thread is created, the client could change to any number of guis, depending on what he is doing, so I am thinking i need a way to dynamically see what gui is currently being run.
The way that i was thinking of doing this so far:
1) Create an object that creates and shows every gui. So instead of calling invokeLater...SomeGui.CreateAndShoGui()... we would have this object be responsible for doing that, ie GuiObject.showSomeGui();
2) Have each gui implement an interface, which will insure there is a method that, when called, will gracefully shutdown this gui when we have lost connection to the server.
3) Have a thread that monitors the IO thread and the gui object. If something goes wrong on the IO thread, the IO thread will close down and notify the monitoring thread that we have lost connection the server. The monitoring thread could then alert any open guis (from the gui object) that we have lost connection and that it needs to shut down.
I have just started thinking about this, and so far this is the best solution i have come up with. Does this seem like a reasonable solution that wont add too much complexity to the code? Or can anyone recommend a solution that would be simpler for people reading the code to understand?
Thanks
EDIT:
The other option i am toying with is having an object on the IO thread, that also gets passed to each new gui as it is opened. This object will give the currently opened guis reference back to the io thread, so that the io thread can alert it if something goes wrong. I am leaning against this solution though, because it seems like it would be easier to read if you had one object that was dedicated to get this working (like the above solution), instead of passing some obscure object to each gui.
Let me just go through each of your ideas:
1) Bad idea - you are tying your whole application together through a single object. This makes maintainability difficult and is the antithesis of modularity.
2) This is the way to go IMHO. Since it seems that each gui has unique logic in a failure scenario then it stands to reason that the object that best understands what to do would be the gui object itself.
Another version of this idea would be to create an adapter for each gui to put this failure logic into. The advantage would be you have one less dependency between your application framework and your gui. The disadvantage is that this is an extra layer of complexity. If your gui is already pretty coupled to your application then I would choose the interface method. If you want to reuse your guis in another application then the adapter way could help facilitate that.
3) This complements #2 nicely. So let me get this straight - you would have 3 threads: the IO thread, the monitor thread, and the UI thread. I don't know if you need the monitor thread. From what you were saying the IO thread would be able to detect a connection problem by itself (probably because some form of IOException was caught). When a connection problem is discovered the IO thread is not busy since it is just going to shut itself down soon so it might as well just have the responsibility of notifying the guis that there was a problem. The guis should have their interface method called on the UI thread anyways so the IO thread is just calling a bunch of invokeLater() calls (or asyncExec() calls for SWT) and then the IO thread can just shut itself down.
4) (Your Edit) You are basically describing the Visitor pattern. I do not think this is a good solution because the call is from the IO thread to the gui and not the other way around. I am not sure how passing a visitor object around will help in this case.
One final thought. If you make your interface generic (not gui specific) then you can apply this pattern to other resources. For instance you may want to flush your user credentials when you lose connection (since you talked about going to the login screen again). That isn't really gui logic and should not be done from a gui class.
Edit: I would use an event model. Let's say you create a interface like this:
public interface ConnectionFailureListener {
void handleConnectionFailure(); // Add an event object if you need it
}
You could then have registration methods in some object (maybe the Runnable for the IO thread or somewhere else that is convenient for you). These methods would be pretty standard:
public void addConnectionFailureListener(ConnectionFailureListener l) {}
public void removeConnectionFailureListener(ConnectionFailureListener l) {}
When you show a gui on the screen you would add it to your registration object and when you close the gui you would remove it from the registration object. You can add other types of objects as needed - for example when you log in you can add a listener for your credential system and remove it again when log out is processed.
This way when you have a failure condition you simply loop through the currently registered listeners and the listener does its thing.

JavaFX Threading issue - GUI freezing while method call ran

I hoped someone might be able to help as I'm a little stumped. I have a javafx class which runs a user interface, which includes a button to read some text out loud. When you press it, it invokes a Java object which uses the FreeTTS java speech synth to read out loud a String, which all works fine.
The problem is, when the speech is being read out, the program stops completely until its completed. I'm not an expert on threaded applications, but I understand that usually if I extend the Thread class, and provided my implementation of the speech synth code inside an overridden run method, when I call start on the class it "should" create a new Thread, and run this code there, allowing the main thread which has the JavaFX GUI on to continue as normal.
Any idea why this isn't the case? Thanks a lot in advance!
Ack - I've solved it! I called the start() method of the class rather than run() and its sorted. Seems so obviously when looking now!

Calling function when program exits in java

I would like to save the programs settings every time the user exits the program. So I need a way to call a function when the user quits the program. How do I do that?
I am using Java 1.5.
You can add a shutdown hook to your application by doing the following:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
// what you want to do
}
}));
This is basically equivalent to having a try {} finally {} block around your entire program, and basically encompasses what's in the finally block.
Please note the caveats though!
Adding a shutdown hook addShutdownHook(java.lang.Thread) is probably what you look for. There are problems with that approach, though:
you will lose the changes if the program aborts in an uncontrolled way (i.e. if it is killed)
you will lose the changes if there are errors (permission denied, disk full, network errors)
So it might be better to save settings immediately (possibly in an extra thread, to avoid waiting times).
Are you creating a stand alone GUI app (i.e. Swing)?
If so, you should consider how you are providing options to your users how to exit the application.
Namely, if there is going to be a File menu, I would expect that there will be an "Exit" menu item.
Also, if the user closes the last window in the app, I would also expect it to exit the application.
In both cases, it should call code that handles saving the user's preferences.
Using Runtime.getRuntime().addShutdownHook() is certainly a way to do this - but if you are writing Swing applications, I strongly recommend that you take a look at JSR 296 (Swing Application Framework)
Here's a good article on the basics: http://java.sun.com/developer/technicalArticles/javase/swingappfr/.
The JSR reference implementation provides the kind of features that you are looking for at a higher level of abstraction than adding shutdown hooks.
Here is the reference implementation: https://appframework.dev.java.net/

Categories