-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0
-
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
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
- relates to
-
JDK-6423050 javax/swing/JToolBar/4529206/bug4529206.java test fails on winxp,cinnabar and RHAS3 platforms.
- Closed
-
JDK-8081469 Test java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java fails in OEL 7 only
- Closed