views:

681

answers:

2

Hello!

Background information:

I am implementing a visual diagram editor, which consists of

  • different complex elements (re-sizable, with title bar, sub-elements) and
  • different simple elements (not re-sizable, no title bar, no sub-elements).

All elements are draggable.

I am using JInternalFrame (for complex elements) along with JPanel (for simple elements) to represent elements of a schematic diagram. There is a container (either a JDesktopPane or a JLayeredPane), which contain all these elements.

I have several problems with this concept:

Case 1 - The container is a JDesktopPane:

  • JInternalFrames are always above other elements.
  • Clicking other elements don't "deactivate" previously active JInternalFrame

Case 2 - The container is a JLayeredPane:

  • After clicking some elements inside a JInternalFrame, it stays "activated" forever.

Case 3 - JInternalFrame used for everything, but without decoration for simple elements:

  • My custom border (which is needed when I manually remove JInternalFrame's title bar) is every time replaced by current LAF border, after activating/deactivating the JInternalFrame.

I don't get the whole concepts behind activating JInternalFrames anyway. If I could make a JInternalFrame not activable at all, I could choose Case 2 any would be happy.

Please advice me, what would be an simple and straightforward solution to given problems.

NOTE: Selection of components and activation of JInternalFrame seem to be different things.

A: 

I might misunderstand your problem. Have you tried to look at the setSelected() method of JIF? It seems there are support for method override and vetoable activation events.

Edit: Maybe we have some terminological misunderstanding as the javadoc states:

/**
 * Selects or deselects the internal frame
 * if it's showing.
 * A <code>JInternalFrame</code> normally draws its title bar
 * differently if it is
 * the selected frame, which indicates to the user that this
 * internal frame has the focus.
 * When this method changes the state of the internal frame
 * from deselected to selected, it fires an
 * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
 * If the change is from selected to deselected,
 * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
 * is fired.
 *
 * @param selected  a boolean, where <code>true</code> means this internal frame
 *                  should become selected (currently active)
 *                  and <code>false</code> means it should become deselected
 * @exception PropertyVetoException when the attempt to set the
 *            property is vetoed by the <code>JInternalFrame</code>
 *
 * @see #isShowing
 * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
 * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
 *
 * @beaninfo
 *     constrained: true
 *           bound: true
 *     description: Indicates whether this internal frame is currently
 *                  the active frame.
 */

Edit 2: Now I re-read your 2nd case. I would say each JIF has its own separated focus/selection environment. You could create a method which traverses all your JIFs and deselects anything in it unless its the component you wanted to be selected.

kd304
Yes, but it doesn't help. Selection doesn't have to do with JInternalFrame's activation.
ivan_ivanovich_ivanoff
You see, even in the Javadoc it is confusing. They talk about selecting, but the property is named "activated". Note: there is also a property "selected" (which does not apply to my problem). Hmmm, I'm confused...
ivan_ivanovich_ivanoff
I don't get it. Now I've added InternalFrameListener and FocusListener to all JIFs, but non of these listeners receive any events!
ivan_ivanovich_ivanoff
Beats me. Try out some breakpoints and watch.
kd304
InternalFrameListener works now, my mistake. But I think I'll make the whole thing somehow different. But thank you anyway!
ivan_ivanovich_ivanoff
A: 

give this a try when you initialize your JInternalFrame=

 new JInternalFrame(<your args>) {
          protected void fireInternalFrameEvent(int id){  
               if (id != InternalFrameEvent.INTERNAL_FRAME_ACTIVATED) {
                   super.fireInternalFrameEvent(id);
               }
          }
 };

note that looking at the code in JInternalFrame.setSelected(boolean), setSelected and 'actvation' are tied together in process, in that setSelected fires not only property changes for Selection, but also calls fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED) as well.

akf