views:

45

answers:

1

I want to know what the issue is when I try to close my Java Swing application when I add a listener to the form frameview. Here's how to produce my problem: In Netbeans, create a new Swing application project, then in the main class, create a local method that adds an empty mouse listener to the main window via this.getMainFrame().addMouseListener(new MouseAdapter(){}). Go into the form class, and call that method using .getApplication().createListenerMethod() in the form's constructor, right after InitComponents().

Run the program and you'll see that after closing it, netbean's little progress bar says it's still running :(

I find that if I set the form's default close operation to "dispose", it solves the problem. Why does it do this if I call a method from the form to the main application class to add a listener to itself? The reason why I'm adding it like this is that I want to keep the main application logic in the main file class, I feel uneasy writing code a in form designer parsed class.

+3  A: 

I don't think that the mouse listener has anything to do with what you see, though it's possible that the NB code-generation wizard does some weird stuff in the protected regions.

Swing does not auto-dispose the frames/windows in case you want to reuse them (show/hide multiple times). Usually you want to keep track of closed windows/dispose them from a window listener or in simpler cases, use JFrame.setDefaultCloseOperation(). Most often each reasonably big Swing application has some sort of global state-tracking facility that disposes all windows and shuts down thread pools when the termination condition is met.

You can use NetBeans RCP as well that takes care of many aspects of a GUI application if you are willing to invest the time to learn it (I would not recommend for small apps). Another alternatives for Swing app frameworks are are Jide Software's JDAF (my preferred) and "Better Swing Application Framework" (from kenai.com)

ddimitrov
Yeah my application is quite small, so I'm glad I wouldn't need to make it anymore unnecessarily complex already. The code right after InitComponents seems pretty safe to add a call to the main application, how else are you going to communicate with the private components? Or maybe I'm suppose to keep all my logic in the form?
chaz
I don't know what do you have in InitComponents (haven't used NetBeans in more than 5 years). In general, you try to do most of the short work inside descendents of AbstractAction. Long work is done in SwingWorkers or whatever task execution facilities your framework provides. Both these manipulate the (usually customized) widget model, but DO NOT reference the actual widgets themselves.
ddimitrov
InitComponents is designer generated, in fact it's nicely packed in comment symbols, so you know I'm doing anything there. So adding action listeners like you say is the only time I'm assured safety when referencing widgets. I'm actually setting up all the action listeners I can in the form so they can call action orientated methods in the main class. i.e. "searchCommitted" could be from pressing enter from a text field or clicking a button. And this is pretty much how the problem arose. I actually found out the default value for the default close handler was to "Hide" for the form.
chaz
Accessing widgets is safe any time if you do it from EDT, though I would say that most of the time it is a bad practice. Also, consider using Action classes instead of ActionListeners whenever you can.
ddimitrov