Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4529206

JToolBar - setFloating does not work correctly

XMLWordPrintable

    • b14
    • generic
    • generic

      Name: jl125535 Date: 11/19/2001


      java version "1.4.0-beta3"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
      Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

      The BasicToolBarUI.setFloating() method does not work correctly.
      This is related to two other reports, 133469 & 135579.


      Problem 1
      ---------

      (This problem is related to the second half of Bug 4246771.)

      Under normal circumstances when the user drags a toolbar to make it float
      everything works fine, but when setFloating() is called to make the toolbar
      float it will be created as a new window that can go behind it's parent window
      and appears in the task list.

      The reason for this is that the floating window is only created after the
      toolbar has been removed from it's parent. This means that there is no way to
      associate the two windows.

      Note that this problem will not happen if the toolbar has previously been
      dragged as the floating window will already have been created correctly.

      The fix for this (as detailed in 133469) is to move this:

      if (floatingToolBar == null)
      floatingToolBar = createFloatingWindow(toolBar);

      above this:

      if (dockingSource == null)
      {
      dockingSource = toolBar.getParent();
      dockingSource.remove(toolBar);
      }


      in the code for setFloating.


      This will solve that problem and toolbars are created correctly.


      Problem 2
      ---------

      When you call setFloating the toolbar becomes visible even if the parent window
      is not visible.

      For example, if you make a toolbar float while your application is loading and
      you have the splash screen displayed, it will be shown as soon as you make it
      float, regardless of the fact that the parent window is invisible. This looks
      really bad.

        To solve this problem the following changes could be made:

      1) add a public setShowWithParent() method to java.awt.Window to set the value
      of the private showWithParent variable. (This is detailed in 135579)

      2) Modify the setFloating method to check if the parent window is visible, if
      not then do not show the window. Instead call setShowWithParent so that when
      the parent window is made visible the toolbar appears floating.


      Solution
      --------

      The following shows the changes required to setFloating to resolve both issues:


      public void setFloating(boolean b, Point p) {
      if (toolBar.isFloatable() == true) {
      if (dragWindow != null)
      dragWindow.setVisible(false);
      this.floating = b;
      if (b == true)
      {

      ///////////////////////////////////////////////////////
      // New lines to ensure toolbar is only shown if parent window is visible
      boolean visible = true;
      Window ancestor = SwingUtilities.getWindowAncestor(toolBar);
      if (ancestor != null)
      visible = SwingUtilities.getWindowAncestor
      (toolBar).isVisible();
      ///////////////////////////////////////////////////////

      ///////////////////////////////////////////////////////
      // Moved from below to fix bug that toolbar goes behind
      if (floatingToolBar == null)
      floatingToolBar = createFloatingWindow(toolBar);
      // End change
      ///////////////////////////////////////////////////////

      if (dockingSource == null)
      {
      dockingSource = toolBar.getParent();
      dockingSource.remove(toolBar);
      }
      Point l = new Point();
      toolBar.getLocation(l);
      constraintBeforeFloating = calculateConstraint(dockingSource,
      l);
      if ( propertyListener != null )
      UIManager.addPropertyChangeListener(
      propertyListener );
      if (floatingToolBar == null)
      floatingToolBar = createFloatingWindow(toolBar);
      floatingToolBar.getContentPane().add
      (toolBar,BorderLayout.CENTER);
      setOrientation( JToolBar.HORIZONTAL );
      if (floatingToolBar instanceof Window) ((Window)
      floatingToolBar).pack();
      if (floatingToolBar instanceof Window) ((Window)
      floatingToolBar).setLocation(floatingX, floatingY);

      ///////////////////////////////////////////////////////
      // Was
      // if (floatingToolBar instanceof Window) ((Window)
      floatingToolBar).show();
      //
      // Now
      if (floatingToolBar instanceof Window)
      {
      if (visible)
      ((Window)floatingToolBar).show();
      else
      ((Window)floatingToolBar).setShowWithParent
      (true);
      }
      // End change
      ///////////////////////////////////////////////////////

      } else {

      ///////////////////////////////////////////////////////
      // This is now moved above
      // if (floatingToolBar == null)
      // floatingToolBar = createFloatingWindow(toolBar);
      ///////////////////////////////////////////////////////

      if (floatingToolBar instanceof Window) ((Window)
      floatingToolBar).setVisible(false);
      floatingToolBar.getContentPane().remove(toolBar);
      String constraint = getDockingConstraint(dockingSource,
      p);
      int orientation = mapConstraintToOrientation(constraint);
      setOrientation(orientation);
      if (dockingSource== null)
      dockingSource = toolBar.getParent();
      if ( propertyListener != null )
      UIManager.removePropertyChangeListener(
      propertyListener );
      dockingSource.add(constraint, toolBar);
      }
      dockingSource.invalidate();
      Container dockingSourceParent = dockingSource.getParent();
      if (dockingSourceParent != null)
      dockingSourceParent.validate();
      dockingSource.repaint();
      }
      }


      --------------------------------------------------------------------------------
      ----

      Demonstration
      -------------

      This is a sample application to show both problems.
      This simulates an application starting up.

      If you run this, you will see that the toolbar appears floating 3 seconds
      before the parent window appears.
      Also, when the window does appear, it moves in front of the toolbar.

      The correct behaviour would be that both appear together after 3 seconds and
      the toolbar is always in front of the parent window.


      import javax.swing.*;
      import javax.swing.event.*;
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.plaf.basic.*;

      public class Test extends JFrame
      {
          JToolBar jToolBar1 = new JToolBar();
          JButton jButton1 = new JButton("Float");

          public Test()
          {
              try
              {
                  enableEvents(AWTEvent.WINDOW_EVENT_MASK);
                  JPanel jPanFrame = (JPanel) this.getContentPane();
                  jPanFrame.setLayout(new BorderLayout());
                  this.setSize(new Dimension(200, 100));
                  this.setLocation(125, 75);
                  this.setTitle("Test Floating Toolbar");
                  jPanFrame.add(jToolBar1, BorderLayout.NORTH);
                  jToolBar1.add(jButton1, null);
                  jButton1.addActionListener(new ActionListener()
                                          
          {public void actionPerformed(ActionEvent e)
                                              
                      {buttonPressed(e);}});

                  // Now, as part of the initial loading the toolbar is set to float
                  makeToolbarFloat();

                  // Carry on processing
                  Thread.sleep(3000);

                  // Now ready to go.
                  setVisible(true);
              }
              catch (Throwable t) {}
          }

          private void makeToolbarFloat()
          {
              BasicToolBarUI ui = (BasicToolBarUI) jToolBar1.getUI();
              if (!ui.isFloating())
              {
                  ui.setFloatingLocation(100, 100);
                  ui.setFloating(true, jToolBar1.getLocation());
              }
          }

          private void buttonPressed(ActionEvent e)
          {
              makeToolbarFloat();
          }

          protected void processWindowEvent(WindowEvent e)
          {
              super.processWindowEvent(e);
              if (e.getID() == WindowEvent.WINDOW_CLOSING)
                  System.exit(0);
          }

          public static void main(String[] args)
          {
              new Test();
          }
      }

      (Review ID: 135586)
      ======================================================================
      ###@###.### 10/11/04 13:39 GMT

            kereminsunw Konstantin Eremin (Inactive)
            jleesunw Jon Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: