Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: useScreenMenuBar+setJMenuBar and windowActivated+getOppositeWindow bugs?



Lieven Dekeyser <email@hidden> wrote:

>I'm trying to pass along a JMenuBar as windows are activated.. This
>way, it would appear as if every window had the same menu bar, without
>the need of creating copies for each window. I know the common way to
>create mac-like menus is just to copy them for each window, but single
>instances are a necessity for our application.

Any time I hear "necessity", I can't help wondering why.  Why is it a
necessity that you share a single instance of JMenuBar across all JFrames?

In Swing, you can replicate JMenuBar and JMenuItems, yet share a single
common model of Actions.  Since Actions have an enabled/disabled state, all
the JMenuItems that refer to the Action will enable or disable based on
that state.  This solves most, though not all, problems associated with
single-menubar implementation.

Considering that Swing and AWT are ill-designed for what you're trying to
do, I suspect it may be simpler to pretend there's only one menubar, rather
than actually coding it that way.  I've definitely had better luck managing
the pretense than the actuality.


>If just do the window.invalidate-repaint-validate routine just as if
>apple.laf.useScreenMenuBar is set to false in the example below, the
>menu bar isn't even shown when manually resizing the windows.
>
>What is it that setSize() does to make this hack work?

Maybe because setSize() sends a property-change, which causes a revalidate().

When you invalidate() a Container, it only invalidates that one component
and its ancestors UP the tree.  It doesn't invalidate any children DOWN the
tree.  Specifically, the JMenuBar, which is a child of the JFrame, is not
invalidated, so does not need relayout, and presumably does not need a
repaint.  Resizing the JFrame causes a property-change, which triggers
revalidate().  See API docs for revalidate().

Or there might be race conditions occurring.  Or something tied to live resize.

Try running your program like this for an interesting variation:
  java -Dapple.laf.useScreenMenuBar=false -cp your.jar SingleMenuBarTest

It certainly has different results than when the property is undefined.

It's hard to say exactly what's going on.  Look at the Java source to find
out for sure.


FWIW, you can't rely on oppositeWindow being the window that's going to
lose ownership of a shared JMenuBar.  Here's a problematic scenario.  Your
app has windows Able and Baker.  Both are visible, and Able is frontmost.
The user clicks on a Finder window, which switches focus away from your
application.  Then the user clicks on Baker.  If you're relying on
oppositeWindow to be Able, you're screwed, because all window-events except
those directly between two Java windows in the same process will have null
for oppositeWindow.

The only reliable indicator of who "owns" a shared JMenuBar is the JMenuBar
itself, which has either null as parent or a non-null Container it was
added to.


And be sure to file real bug-reports:
  <http://developer.apple.com/bugreporter>

Posting to this list is not a bug report.

  -- GG


 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.