I have a question about execution of program. In C++ for example, the program is being executed line by line until it reaches the end (return 0; or just reaches the end of the scope of the main function). In a program with a text interface if I want to repeat the program until a user for instance hits the [Esc] key I put it in the loop that is being executed until that specific one situation occurs. Same happens in a GUI program (precisely: WinAPI), program is looping through the event loop until for example user hits 'X' and then the program is reaching the end of the main function, so the execution of the program stops. So far so good.
What is surprising me and is keeping me up at night is the fact that when I create a JFrame object, initialize it and make it happen just to show it, when the program execution reaches the end of the scope of the main function, the window still exists. I've also checked it in a debugger that it's not showing a line that is actually being executed. It clearly states that the thread execution has been finished. I am sure that the execution is not being frozen so something has to be happening under the hood, cause I still can resize, close the window and so on. So here's my question: where is actually the execution of a program 'moving to' when a window in Java is being displayed?
Same thing is happening in VBA. I've created a main function in a module, then in that one module i've forced one non-modal form to show and once the execution of the function has finished, the window did not disappear, but the variables declared in the function did, so the access to them vanished as well.
In both examples in C/C++ those situations would mean, that program was finished, but there's that window visible, so the application actually didn't stop, right?
Related
I have a global variable
static int debugNumber;
and a breakpoint with a condition
debugNumber > 1
with Suspend thread, Conditional and Suspend when 'true' checked. Currently, if I pause the execution of the program and hover over the declaration the value displayed is 2. Still, this breakpoint doesn't break.
As far as I can see on Google and here at SE debugNumber > 1 should be fine. What am I doing wrong?
Just so we're clear: That line means: If code execution gets to this line (the line with the breakpoint), then do what breakpoints usually do: Freeze the thread (or if you've configured things to be that way, and pause all other threads, which is not the default). However, a conditional breakpoint means: Before breaking as usual, check the condition. If the condition is false, then don't do anything.
A conditional breakpoint is going to break as often, or less often, than a normal breakpoint, never more often.
It sounds like what you want is to 'breakpoint' every line in the codebase that sets the debugNumber variable, if the value it is being set to is 2 or higher. If that's what you want, make a 'watch' on debugNumber and configure the watch to break execution.
If that's not what you wanted, then, well, you made no mistakes in what you describes, so then it's one of a billion things that could be wrong:
The line with your breakpoint was never hit.
The debugNumber was 1 or less when it hit your breakpoint.
You used 'run' to start your application and not 'debug' (there's pretty much no reason to ever 'run' anything, always pick 'debug')
The global 'disable all breakpoints' toggle within eclipse has been toggled off. It's (unless you changed things) on the toolbar: a larger 'breakpoint dot' (blueish circle) with a big slash through it. It's a toggle button. Is it pressed in?
Eclipse debugger has desynced. It will throw you a dialog if this happens, but one of the options in this dialog is 'ignore now and in the future' (It's a more succint text than that, but that's the gist of it). If you ever pressed that, it can desync. The debug view will tell you. This can happen if you change compiled code as eclipse runs, or change signatures in your source files and save the source file in the middle of a run.
Many many more things
I am making a javafx application that simulates a robot vacuum.
I want it to be automated so it would vacuum the environment by itself.
I need to insert a delay so a human can see the steps the vacuum is taking as it traverses the environment.
So far all the delay methods I have tested crash my program if they are inside a while loop.
If I put it outside the while and just click a button for the next step, everything works fine.
It also works fine if I set the delay to really short time, like 1 ms.
Any ideas of why this is happening?
Any application that executes a set of instructions for a while (is busy) and cannot respond to user input or system events is "seen" by Windows as "not responding" and when you try to interact with a "not responding" program, Windows will tell you it crashed.
The problem, you see, is that you try to delay interface updates with a while loop, and that makes your program execute something for a while and while is busy executing your loop it cannot respond to system or user events.
If you want to make delayed updates, use multithreading. Your while loop is blocking the main thread which is also responsible for rendering and taking any input, so you cannot block this thread. Create another thread and share state (eg. use observer pattern). And then you can execute TimeUnit's sleep() in this helper thread and it won't make your app "crash".
EDIT: I had originally believed this problem to have been caused by the ifPresentOrElse statement, however I now understand this is not the case and the infinite while loop is to blame for this behavior, and have renamed the question (see comments and chosen answer).
There is an existing question here that shares a similar behavior with this question, however I believe that the solutions are different enough for this not to be considered a duplicate.
Original Question:
Suppose I have a JavaFX application whose start method (in the Application thread) contains the following code:
while(true) {
new TextInputDialog().showAndWait()
.ifPresentOrElse(System.out::println,
Platform::exit);
}
The behavior of this should be that, if the OK button of the TextInputDialog is pressed (making a result present), the text entered within the dialog should be printed. If the CANCEL button is pressed, the Platform::exit statement will be called and the JavaFX application will exit.
The former case works as expected, however the latter doesn't. If the CANCEL button is pressed, the application stays alive and the dialog is opened again as if the OK button had been pressed, however no text is printed, which means that the Platform::exit statement must have been reached instead of the System.out::println statement. In an attempt to debug this issue, I adjusted the original code to the following:
while(true) {
new TextInputDialog().showAndWait()
.ifPresentOrElse(System.out::println,
() -> System.out.println("The latter statement has been reached"));
}
When running this code and pressing the CANCEL button, "The latter statement has been reached" is printed to the screen, proving that the Platform::exit was being reached in the original code, but was not closing the application as expected.
Interestingly enough, if I edit the original code once more to the following:
while(true) {
new TextInputDialog().showAndWait()
.ifPresentOrElse(System.out::println,
() -> System.exit(0));
}
...the program exits as expected.
I have never encountered a behavior like this before, and I am truly at a loss as to what is going on. Any insight would be greatly appreciated.
Read the documentation of Platform.exit():
Causes the JavaFX application to terminate. If this method is called after the Application start method is called, then the JavaFX launcher will call the Application stop method and terminate the JavaFX application thread. The launcher thread will then shutdown. If there are no other non-daemon threads that are running, the Java VM will exit. If this method is called from the Preloader or the Application init method, then the Application stop method may not be called.
This method may be called from any thread.
As can be seen, calling the method will not kill threads, so the thread running your while(true) loop will continue to run, and will prevent the program from ending.
You need to change the code so the while loop ends too, e.g. something like this:
AtomicBoolean keepRunning = new AtomicBoolean(true);
while (keepRunning.get()) {
new TextInputDialog().showAndWait()
.ifPresentOrElse(System.out::println,
() -> keepRunning.set(false));
}
Platform.exit();
I am making a programme in Java for a school project. It has the form of an interactive multiple-choice test.
I wanted it to perform it in a way that an action button creates an event in which (the order of the code is the same as listed):
1) Randomly chooses an Object that consist of several Strings from a prepared List and prints it on adequate text fields in GUI
2) Using a proper method there is a delay created that holds further code down below for 1 minute. In this time the user should be able to check proper Checkboxes so the GUI must stay active.
3)When this minute ends the checked places are read and further processed.
The thing is that I am unable to create step number 2) which is the delaying of the code below. I have tried function sleep() but when I do it with sleep() the whole GUI freezes and the user is unable to do anything on it. I have read that function swing timer would be appropriate but I dont know how to do it. I have seen examples but in them the timer along with functions that were executed after some time were written in the class ActionListener instead of the action button. I am using Netbeans 8.1
Sorry for my bad explanation of the problem, I am a total beginner in java programming and really count on your help :)
Cheers!
Your problem comes from how you structured your code. You wrote everything into a single method.
Split this up into two methods. One to set up the UI state (everything before "HERE I NEED TO DELAY..."). The second method takes everything below.
Then, at the end of the first method, create a non-repeating Timer for one Minute, add an ActionListener that just calls your second method. Then start the timer. When the timer has run its course, it will call your second method through the action listener.
I'm working on a multithreaded program in Java that uses a shared array to pass data between threads. It's being developed in Netbeans 6.7.1.
One of the threads only seems to work when a breakpoint is placed in it, it doesnt matter where it is.
Running in debug mode with no breakpoints acts the same as running in release - the expected output never arrives.
I can't tell where the problem occurs, as the moment a breakpoint is added and I press continue, it works as expected.
How can I narrow down where/why this problem occurs?
Example code:
result = utils.isBufferFull(AudioDuplex.voiceArray);
if(result == true) {
System.out.println("Taking copy");
voiceArray = AudioDuplex.voiceArray;//.clone();
utils.clearBuffer(AudioDuplex.voiceArray);
}
If a breakpoint is placed on line 2, it is never hit.
A breakpoint on line 3 will be hit, and the expected output will arrive.
It's impossible to tell exactly what's wrong without a lengthier code sample, but in my experience, this kind of behavior is typical of unrecognized producer-consumer problems (see http://en.wikipedia.org/wiki/Producer-consumer_problem).
Basically, what's probably happening is that your producer thread does not have the data available when the consumer thread is requesting it. The basic solution is to keep a semaphore (there is a Sempahore class in java afaik). The producer would post when it has the data, the consumer would wait until the producer posts.
What you're seeing with the break point is you stopping the consumer thread for a long enough period that the producer can offer something. When you don't break, the consumer runs normally, and exits before the producer has anything.
Write the values of the involved variables to a log file, the console or add them to an array and print them as soon as you get the error.
Your problem is probably a runtime issue (a second thread updates an involved variable). Since breakpoints only stop the active thread, the second thread gets its work done so the code works.