I have a JFrame (EC_GUI.main) and then I create several JDialogs to which I add a JPanel, passing the JFrame as owner.
I am now in the process of detecting if any of these JDialogs are opened through the jFrame.getOwnedWindows(), since I can't get them through one of this
EC_GUI.main.getComponentCount() 1
javax.swing.JRootPane[,0,0,755x1005,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=]
EC_GUI.main.getRootPane().getComponentCount() 2
javax.swing.JPanel[null.glassPane,0,0,755x1005,hidden,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
javax.swing.JLayeredPane[null.layeredPane,0,0,755x1005,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true]
EC_GUI.main.getContentPane().getComponentCount() 1
ec.gui.dialogs.template.EC_BorderPanel[,0,0,755x1005,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.border.EmptyBorder#44e6097c,flags=9,maximumSize=,minimumSize=,preferredSize=]
But I do get them if I query the ownedWindows
EC_GUI.main.getOwnedWindows().length 1
ec.gui.dialogs.visivilityfield.EC_VrPresetDialog$1[dialog0,385,254,502x511,invalid,hidden,layout=java.awt.BorderLayout,MODELESS,title=Virtual Reality Presets,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,502x511,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
I noticed that even if I call jDialog.dispose() I still have a reference so if I open and close, let's say 3 times, one of my JDialogs, I get
EC_GUI.main.getOwnedWindows().length 3
ec.gui.dialogs.visivilityfield.EC_VrPresetDialog$1[dialog1,385,254,502x511,invalid,hidden,layout=java.awt.BorderLayout,MODELESS,title=Virtual Reality Presets,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,502x511,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
ec.gui.dialogs.visivilityfield.EC_VrPresetDialog$1[dialog2,385,254,502x511,invalid,hidden,layout=java.awt.BorderLayout,MODELESS,title=Virtual Reality Presets,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,502x511,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
ec.gui.dialogs.visivilityfield.EC_VrPresetDialog$1[dialog3,385,254,502x511,invalid,hidden,layout=java.awt.BorderLayout,MODELESS,title=Virtual Reality Presets,defaultCloseOperation=DO_NOTHING_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,0,502x511,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
Is this normal?
You read through the JavaDocs you will not that, when configured correctly, dispose will release the native resources that the window is using, this does not "dispose" of the object, you can re-show the window by calling setVisible.
You could check the isDisplayable (which will let you know if the window still has a reference to it's native peer) or the more reliable isVisible option...
If the dialog has no other strong references, it will, eventually be garbage collected.
Related
I have a page with multiple applets (yes, it's old). One of these applets overrides the stop method, as follows:
#Override public void stop() {
System.out.println("Stop called!");
}
But, when I do this, nothing is displayed in the console (yes, the java console) when I switch tabs, or do anything else that should call stop(). The same problem is happening with overriding destroy(). However, the start() and init() functions work as expected.
My applets are extending another class, which in turn extends JApplet. I did this to give all of my applets access to specific functions (defined in this in-between class). These applets also create other threads for repetitive tasks, but I don't think that should affect the life cycle methods. I'm not sure where to look at this point, is it possible that the focus functions or something else like that is preventing the lifecycle methods from executing, or does having multiple applets on one page cause problems with these methods? Thanks beforehand.
EDIT: I have posted a SSCCE on my server to show this behaviour Click here to run and Here to dowload sources, it's a simple applet that starts a thread, which calls a method in the parent applet that opens a JDialog. You'll notice that you can close the browser tab while the dialog is open (as long as there are other tabs open) and neither the stop or destroy print statements will occur in IE10. On top of that, the JVM keeps running, and the Java console does not close. However, if you acknowledge the pop-up before closing the browser window, everything functions as expected.
So, the question then, is if someone closes the browser window while a popup is open, how do I kill the extra thread, and the pop-up itself?
The JDialog mentioned is created using JOptionPane. Quoting from the javadoc
All dialogs are modal
Modal dialogs effectively block the applet preventing the stop and destroymethods in the applet from being called. You could simply make the dialog non-modal
popup.setModal(false);
After downloading and expanding the Zip, and turning the 2 sources into an SSCCE (an SSCCE is one source file by definition), I noted the same behavior in IE9.
It seems to me this is yet another example of a browser/JVM interaction bug. In FF the user is unable to close the page or change tabs when the dialog is open. That leads to a behavior that is as we'd expect, since the dialog must be closed prior to the applet tab being closed (or tab change or the browser being closed).
In IE9 (and 10, according to your report), the page can be accessed despite the visibility of the dialog, leading to all the problems.
Unfortunately the only work-around I could think of, didn't (work). Sometimes the necessary event can be detected by a ComponentListener, but in this case, it does not fire on closing the tab or changing tab.
So, I suggest you search the bug database for anything similar. If you find nothing, raise a new report and see what Oracle has to say on the matter. If it is a bug and they think it is the fault of IE, they can take it up with MS.
I switch tabs, or do anything else that should call stop(). The same
problem is happening with overriding destroy(). However, the start()
and init() functions work as expected.
Life Cycle of an Applet Doc page says:
When the user leaves the page, for example, to go to another page, the browser stops and destroys the applet. The state of the applet is not preserved. When the user returns to the page, the browser intializes and starts a new instance of the applet.
So yes I am having the correct result when i try to change the page on which applet is running, the stop() and destroy() method gets called and stopping and destroying gets printed. If by switching the tab you are meaning selecting one tab among the opened tabs, this is not to cause stop() and destroy() get called. However if you run JApplet directly from an applet viewer using Netbeans/Eclipes you will see that window state change(e.g., iconified, normalized) will cause stop() get called. destroy() will be called if you close the JApplet viewer.
You'll notice that you can close the browser tab while the dialog is open (as long as there are other tabs open) and neither the stop or destroy print statements will occur in IE10.
well i have tested with IE9 as i don't have IE10 now, i noticed in IE9 unlike in Firefox that the JDialouge lets switching tab among the opened tabs but it let neither the browser nor the page containing the applet get closed until acknowledging it. So it has something to do with IE10. you can try to use javascript to call an applet function to force it to be exited on window close event. I am not sure about this though as i mentioned, i don't have IE10.
On top of that, the JVM keeps running, and the Java console does not close. However, if you acknowledge the pop-up before closing the browser window, everything functions as expected.
I am a little bit confused here. Actually both Firefox and in IE9, i have experienced that after closing the page containing JApplet, jp2launcher.exe takes at most 2 mins time to exit itself and java.exe. In the mean time if you reopen the page containing the applet, it will start instantly without asking for any permission as it would ask first time when it got loaded.
This question already has answers here:
Deleting an object in java?
(7 answers)
Closed 9 years ago.
I have an object called CounterGUI. It creates a GUI. I create it in another class, say MyProgram.
Once MyProgram creates a CounterGUI object, how do I delete the object? Say if I do this:
CounterGUI first = new CounterGUI(); //displays the GUI
first = null;
I thought setting the object to null would delete everything (including the GUI), but it doesn't. How do I completely delete it?
I don't see how this is a duplicate question, the previous answers were to set it to null or a new object, but that doesn't work here.
Assuming that CounterGUI is a java.awt.Window, then:
The way to make the window disappear is to call setVisible(false).
The way to disconnect it entirely from the native windowing is to call dispose().
Once the Window has been disposed, making it unreachable (e.g. by assigning null to all of your variables that reference it) will make it eligible for garbage collection.
Simply assigning null while the Window is visible will have no effect. The a visible Window object is connected to various things that prevent it from being garbage collected.
Java uses automatic garbage collection. When you set an object to null and it is the last reference remaining, the JVM will reclaim the memory used.
In your case, however, it may be that a thread is created (with GUIs this is often the case) and a reference to the current object is given to it. In this case, setting the reference to null has no effect as something else still has access to the object.
In order to properly close your GUI, you have to invoke a close method. For a JFrame, you can try this:
myGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
which will close the application when the user clicks the close button. If you want to control closing by the program, then you can try:
private void closeItDown() {
WindowEvent event = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
}
...and calling this method. You don't have to set anything to null, the JVM will garbage collect for you at this point, maybe. Not guaranteed, but possibly at this point, perhaps later, or now... or whenever :)
Deleting an object by setting its reference to null make it eligible for garbage collection and JVM will take care of removal of all those object. If you wants to force the garbage collector to run you can issue System.gc() or Runtime.gc () but it is still not a guarantee that it will be collected back to JVM. You can find further information on how garbage collector works here
If you wants to remove your GUI window you can use dispose() method.
you want to make disappear GUI then dispose()
you dont have to worry about this , Garbage collector will automatically take it out of memory or
you can invoke it yourself
System.gc()
but it is bad practice as well as not guaranteed that it will surely being collected.
I started writing a small program to learn a bit more about java and try to design my layouts by hand without always using NetBeans.
Thing is, when I run my project and close it, it won't stop running in NetBeans, so everytime I re-run it creates another run. By searching and looking at another GUI I had created using NetBeans I thought adding the
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
would do the trick, but I guess I am wrong.
Can someone please explain me what I should do?
Here is a SSCCE of my programa: http://pastebin.com/QhKpwdDw
Thank you very much in advance!
You might want to take a look at this question: How to close a Java Swing application from the code, as it deals with closing the application in general and also how to ensure it completely terminated.
But to answer your question quickly, there are a couple of options.
Option 1
Since you are extending JFrame in your class, you can just use EXIT_ON_CLOSE to quit.
setDefaultCloseOperation(EXIT_ON_CLOSE);
NOTE: EXIT_ON_CLOSE exits all JFrames in your application, not just the one it is applied to.
Option 2
This is most likely not the answer you want, but DISPOSE_ON_CLOSE will close only the JFrame you are applying it to.
If you have multiple JFrames open, or if you have any other Threads, they will keep running and the program will not end. But if you only have one Thread and one JFrame, this will close the application.
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
My Preference
I would go with Option 1, disagreeing with everyone else. It is directly tied to JFrame and not dependent on WindowConstants, which makes things cleaner and more reliable. But more importantly, it closes all of the windows, not just the one that you apply it to.
Even though it looks like you only have one window, you may have other internal Threads elsewhere in your program that NetBeans is throwing in there.
To be sure everything closes, you want to use EXIT_ON_CLOSE.
Extra Information
For a discussion on how DISPOSE_ON_CLOSE and EXIT_ON_CLOSE differ: http://www.coderanch.com/t/340183/GUI/java/DISPOSE-CLOSE-vs-EXIT-CLOSE
Documentation on JFrame's EXIT_ON_CLOSE: http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/JFrame.html#EXIT_ON_CLOSE
Documentation on DISPOSE_ON_CLOSE and other WindowConstants: http://docs.oracle.com/javase/1.5.0/docs/api/javax/swing/WindowConstants.html#DISPOSE_ON_CLOSE
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/WindowConstants.html#DISPOSE_ON_CLOSE
DISPOSE_ON_CLOSE
public static final int DISPOSE_ON_CLOSE
The dispose-window default window close operation.
Note: When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate. See AWT Threading Issues for more information.
See Also:
Window.dispose(), JInternalFrame.dispose(), Constant Field Values
Try this...
Place it inside the constructor of your JFrame or the class which extends JFrame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
As you can see here (setDefaultCloseOperation doc) you can use DISPOSE_ON_CLOSE if you want to trigger a window listener (for example to close a database connection).
In such a case it make sense to choose DISPOSE_ON_CLOSE instead of EXIT_ON_CLOSE.
PS : Don't forget although to add a System.exit(0) at the end of the window listener code, so that the application exits.
Situation: a main form calls a modal jDialog with textboxes in which parameters are filled in by the user to create or modify an instance of a certain class, call it ClassA.
When the dialog needs to modify an existing instance, it is passed in the constructor as a parameter. Otherwise the jDialog will create a new instance of ClassA.
Problem: the mainform needs to access that new instance, and I think it is unclean code to pass the entire main form as a parameter, and let the dialog push the new instance into it by a method call, because that way a perfectly re-usable stand-alone dialog becomes only usable with one single main form that needs a certain classname and method to receive the new instance.
It is much more logical to make the main form get the new instance from the jdialog after the OK button is clicked, by calling a getClassAInstance() method (which could be called also when an existing instance was being modified). The method is called after the "setVisible(true)" method on a new instance of the jdialog in question. The dialog appears, the thread of the main form will sleep until the dialog is closed (because it is modal). The OK button calls the dispose() method of the jDialog, then the very next statement is the getClassAInstance() call on the jDialog by the mainform.
Here's the same thing in code..
ClassAInstanceMakerDialog imd = new ClassAInstanceMakerDialog(this, true);
imd.setVisible(true);
//imd.dispose(); after OK button click
System.out.println(imd.getClassAInstance()); //return a new ClassA instance
//output: whatever ClassA.toString() should return, works fine
Question: I've tried it and it seems to work perfectly fine. But, is it a good code? Is there any danger of the getClassAInstance() method returning "null", because the garbage collector collected the ClassA instance after the jDialog was disposed and before the main form could complete the call?
Please excuse me if I didn't make myself clear, I'm not a native English speaker. If you would rather see some code, let me know...
I think it's perfectly legal to access the member variable of your dialog instance that holds the ClassA instance, the dialog instance will not be garbage collected until it goes out of scope, not just because you called dispose on it.
I'd give slight preference to a solution where you define an event handler interface with a signature of
someThingHappened(ClassA toThisObject), make your mainform or anything that might be interested that ClassA thing implement that interface make it possible to add listeners to the dialog before making it visible.
That way, you would loosen the coupling between the dialog and the main form a little.
I don't think that dispose() sets the JDialog up for garbage collection, but instead just releases resources. The dialog is still re-usable as per the Window API (since JDialog inherits this method from Window):
Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.
The Window and its subcomponents can be made displayable again by rebuilding the native resources with a subsequent call to pack or show. The states of the recreated Window and its subcomponents will be identical to the states of these objects at the point where the Window was disposed (not accounting for additional modifications between those actions).
Note: When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate. See AWT Threading Issues for more information.
As long as there are valid reachable references to the JDialog object still present, it will not be garbage collected. I think that the cost of disposing the dialog is that your code will need to spend a (very) little bit of time to re-create the resources.
It is perfectly reasonable and appropriate to have an IDisposable include properties or methods which may be used after Dispose is called to return information about things which happened before Dispose was called. Rather than blindly enforcing a rule that any and all methods of a disposed object should throw an ObjectDisposedException, one should instead consider which methods and properties do or do not make sense on disposed objects. Attempting to access a disposed object should throw ObjectDisposedException in preference to re-acquiring released resources or letting escape some other exception which occurs as a consequence of the disposal. If the method or property access can succeed without any of the released resources, it should often be allowed to do so.
I have written a nifty thing in Java with a GUI that includes a JDialog that starts out rather small and then uses pack() to accommodate things the progam later puts in it. All of this is going on before the JDialog renders.
Then, to my surprise, about 80% of the time, when I run it, the window fails to resize. It seems to be entirely random, as it's theoretically doing exactly the same thing every time. Why on Earth would it do something different with the same code on the same machine five seconds later?
This problem, by the way, popped up when I enabled the native Windows look-and-feel for this GUI.
In my experience, when the GUI does random funny stuff like this, it might be a symptom of not doing all your GUI calls on the Event Dispatch Thread.
Make sure all your GUI calls from non-GUI threads are wrapped in SwingUtilities.invokeLater or invokeAndWait.
A quick google search turned up what seems to be a nifty way to check that your application conforms to the EDT-rules: http://thejavacodemonkey.blogspot.com/2007/08/using-aspectj-to-detect-violations-of.html