This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 192352 - reuse existing JFrame for IDE's main window
Summary: reuse existing JFrame for IDE's main window
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Window System (show other bugs)
Version: 7.0
Hardware: All All
: P2 normal (vote)
Assignee: Stanislav Aubrecht
URL:
Keywords: API_REVIEW_FAST
Depends on:
Blocks:
 
Reported: 2010-11-23 16:50 UTC by Stanislav Aubrecht
Modified: 2012-05-10 09:42 UTC (History)
3 users (show)

See Also:
Issue Type: TASK
Exception Reporter:


Attachments
proposed patch (34.83 KB, patch)
2010-11-23 16:52 UTC, Stanislav Aubrecht
Details | Diff
Test case (6.61 KB, application/x-gzip)
2012-05-09 10:51 UTC, vieiro
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stanislav Aubrecht 2010-11-23 16:50:38 UTC
When window system loads it checks for existing Frames (java.awt.Frame.getFrames()) and if there is a JFrame whose name is "NbMainWindow" then it is reused as the main window. Main menu, toolbars and content pane will be put into this existing JFrame. If there isn't such a JFrame instance then a new empty JFrame is created and used for the main window - the same way as before this change.

see attached diff for more details
Comment 1 Stanislav Aubrecht 2010-11-23 16:52:00 UTC
Created attachment 103253 [details]
proposed patch
Comment 2 Jesse Glick 2010-11-23 17:35:08 UTC
Is there a particular use case?

BTW please avoid making unrelated changes such as adding @Override in an API review patch especially. Do cleanup like this as a separate commit.

Suggest making "NbMainWindow" a public constant in WindowManager. This would serve as a natural point to add Javadoc, @since, etc., and prevent typos. Otherwise you are just declaring an API change in openide.windows without actually changing that module, which is odd.
Comment 3 Jaroslav Tulach 2010-11-24 08:58:35 UTC
It took me a while to scan through the patch to find the "NbMainWindow" contract, but finally I found it.

I agree with Jesse that changing an API of a module while not changing its code is slightly strange, but I don't share Jesse's obsession for public constants. 99.9% of users don't care about this change. It is perfect that the new behavior is available for people who need it, but there does not seem much need to advertise it to everyone by making it a public constant.

If necessary, we can provide default implementation of WindowManager.getMainWindow() method that does the search logic and document it in the method's javadoc.
Comment 4 Stanislav Aubrecht 2010-11-26 07:17:39 UTC
if there are no other comments, i'll update the javadoc and integrate tonight
Comment 5 Stanislav Aubrecht 2010-11-26 21:51:45 UTC
core-main 592df1c28a78
Comment 6 Quality Engineering 2010-11-28 06:15:55 UTC
Integrated into 'main-golden', will be available in build *201011280001* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main/rev/592df1c28a78
User: S. Aubrecht <saubrecht@netbeans.org>
Log: #192352 - reuse existing Frame for NetBeans main window
Comment 7 vieiro 2012-05-09 10:50:42 UTC
This doesn't work on NetBeans 7.1.1 on a Mac OS/X Platform:

Product Version: NetBeans IDE 7.1.1 (Build 201202271535)
Java: 1.6.0_31; Java HotSpot(TM) 64-Bit Server VM 20.6-b01-415
System: Mac OS X version 10.7.3 running on x86_64; MacRoman; es_ES (nb)
User directory: /Users/antonio/.netbeans/7.1
Cache directory: /Users/antonio/.netbeans/7.1/var/cache

I am attaching a simple test case: a NB suite with two modules.

The first module "CustomWindowModule" has an installer that creates a "CustomMainWindow" with name "NbMainWindow". It also logs out currently available Frames. Output is like this:

SEVERE [net.antonioshome.nb.issues.Installer]: Installer 1: restored method
SEVERE [net.antonioshome.nb.issues.Installer]: Installer 1: creating new JFrame 
SEVERE [net.antonioshome.nb.issues.Installer]: Installer 1: new JFrame name: NbMainWindow
SEVERE [net.antonioshome.nb.issues.Installer]: Installer 1: currently available frames:
SEVERE [net.antonioshome.nb.issues.Installer]: Intaller 1: Available frame with name: frame0
SEVERE [net.antonioshome.nb.issues.Installer]: Intaller 1: Available frame with name: frame2
SEVERE [net.antonioshome.nb.issues.Installer]: Intaller 1: Available frame with name: NbMainWindow

It's somewhat surprising that there're already two frames 'frame0' and 'frame2'.

A second module runs an Installer later on, and invokes "invokeWhenUIReady" to verify the class name of the main window. The output is:

SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Installer 2: restored method
[...]
SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Installer 2: UI is ready.
SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Main window is of type: javax.swing.JFrame
SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Currently available frames are:
SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Intaller 2: Available frame with name: frame0
SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Intaller 2: Available frame with name: frame2
SEVERE [net.antonioshome.nb.issues.installer2.Installer]: Intaller 2: Available frame with name: NbMainWindow

Note that although there's a Frame with name 'NbMainWindow' the resulting main window is of type "javax.swing.JFrame", instead of "net.antonioshome.nb.issues.CustomMainWindow".

I'm attaching a test case.


(P.S.: To visualize the "CustomMainWindow" you can run the JUnit tests of the 'CustomWindowModule')
Comment 8 vieiro 2012-05-09 10:51:29 UTC
Created attachment 119193 [details]
Test case

A test case for this issue
Comment 9 vieiro 2012-05-10 09:35:20 UTC
More information: 

the bug happens if the "NetBeans Core UI" module is enabled, but disappears if it's not. I think there's something in there that's triggering the Window System API module and causing it to initialize somehow.
Comment 10 vieiro 2012-05-10 09:41:54 UTC
Yes, it seems that the MenuWarmUpTask is initializing the WindowSystem in a Runnable in META-INF/WarmUp/java.lang.Runnable

http://hg.netbeans.org/main-golden/file/b745a6b9b89d/core.ui/src/org/netbeans/core/ui/warmup/MenuWarmUpTask.java

Quoting (see line 98):

    92     @Override
    93     public void run() {
    94         try {
    95             SwingUtilities.invokeAndWait(new Runnable() {
    96                 @Override
    97                 public void run() {
    98                     Frame main = WindowManager.getDefault().getMainWindow();
    99                     
   100                     assert main != null;
   101                     main.addWindowListener(new NbWindowsAdapter());
   102                     
   103                     if (main instanceof JFrame) {
   104                         comps = ((JFrame) main).getJMenuBar().getComponents();
   105                     }
   106                 }
   107             });
   108         } catch (InterruptedException ex) {
   109             Thread.currentThread().interrupt();
   110             return;
   111         } catch (Exception e) { // bail out!
   112             return;
   113         }

I don't know why this is not invoked "when the UI is ready", maybe running it from a WarmUp task is not very good, as the Window System must be initialized from there.
Comment 11 Stanislav Aubrecht 2012-05-10 09:42:56 UTC
Please open a new issue when reporting bugs.

See #212284