-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
1.4.2
-
x86
-
windows_2000
Name: gm110360 Date: 07/14/2003
FULL PRODUCT VERSION :
java version "1.4.1-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-rc-b19)
Java HotSpot(TM) Client VM (build 1.4.1-rc-b19, mixed mode)
On Zaurus:
Insignia Jeode 1.10.2 (Personal Java 1.2)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
ADDITIONAL OPERATING SYSTEMS :
Sharp Zaurus with linux 2.4.6-rmk1-np2-embedix (ROM 2.37)
A DESCRIPTION OF THE PROBLEM :
[1] When a CardLayout is requested to lay out (for instance
with a pack() call), it obtains its preferred size from its
cards and lays out the first visible card.
But it also lays out the invisible cards with an invalid
container with a size of 0x0.
1) This call is not necessary because the preferred size is
already known.
2) Not knowing the display size of the card makes some
layout manager unable to prepare laying out the components.
[2] When an invisible card becomes visible (call to
layout.show("card", this)), the call to lay out its
component is done after the card has been visible.
1) If the layout manager was not able to anticipate the
layout of the component (see [1].2), it has to do it again.
2) This operation is *visible* to the user on slow devices:
you see the components of the card changing position.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the test program
java -cp . TestCardLayout
EXPECTED VERSUS ACTUAL BEHAVIOR :
The test program creates a frame that has a CardLayout with
two cards. It displays the first card for 4s, then the next
card for 4s and exits.
The test program uses instrumented Layout managers and
components to trace how CardLayout behaves.
It shows that when the frame is displayed first, both cards
are requested to layout: the invisible one with an invalid
container size.
Then when the second card becomes visible, it lays out its
components *after* beeing visible.
I expected:
- First, only the visible card is laid out: no need to lay
out the invisible one.
- When the invisible becomes visible, a request to layout
its component is done before being visible.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
C:\Development\Zepo\src>java -cp . TestCardLayout
TestPanel:panel2.setVisible(false)
TestGridLayout.preferredLayoutSize(TestPanel[panel0,0,0,0x0,invalid,layout=TestG
ridLayout])=java.awt.Dimension[width=230,height=46]
TestGridLayout.preferredLayoutSize(TestPanel[panel1,0,0,0x0,invalid,hidden,layou
t=TestGridLayout])=java.awt.Dimension[width=230,height=69]
TestGridLayout.layoutContainer(TestPanel[panel0,4,23,230x69,invalid,layout=TestG
ridLayout])
java.lang.Throwable
at TestGridLayout.layoutContainer(TestCardLayout.java:100)
at java.awt.Container.layout(Container.java:1017)
at java.awt.Container.doLayout(Container.java:1007)
at java.awt.Container.validateTree(Container.java:1089)
at java.awt.Container.validateTree(Container.java:1096)
at java.awt.Container.validate(Container.java:1064)
at java.awt.Window.pack(Window.java:433)
at TestCardLayout.<init>(TestCardLayout.java:39)
at TestCardLayout.main(TestCardLayout.java:51)
TestGridLayout.layoutContainer(TestPanel[panel1,0,0,0x0,invalid,hidden,layout=Te
stGridLayout])
*** ==> The second card is requested to layout without knowing its size!
java.lang.Throwable
at TestGridLayout.layoutContainer(TestCardLayout.java:100)
at java.awt.Container.layout(Container.java:1017)
at java.awt.Container.doLayout(Container.java:1007)
at java.awt.Container.validateTree(Container.java:1089)
at java.awt.Container.validateTree(Container.java:1096)
at java.awt.Container.validate(Container.java:1064)
at java.awt.Window.pack(Window.java:433)
at TestCardLayout.<init>(TestCardLayout.java:39)
at TestCardLayout.main(TestCardLayout.java:51)
Showing next pane
TestPanel:panel1.setVisible(false)
TestPanel:panel2.setVisible(true)
*** ==> Now the second card is visible when the container is requested to
layout again: the user can see the components moving...
TestGridLayout.layoutContainer(TestPanel[panel1,4,23,230x69,invalid,layout=TestG
ridLayout])
java.lang.Throwable
at TestGridLayout.layoutContainer(TestCardLayout.java:100)
at java.awt.Container.layout(Container.java:1017)
at java.awt.Container.doLayout(Container.java:1007)
at java.awt.Container.validateTree(Container.java:1089)
at java.awt.Container.validateTree(Container.java:1096)
at java.awt.Container.validate(Container.java:1064)
at java.awt.CardLayout.show(CardLayout.java:465)
at java.awt.CardLayout.last(CardLayout.java:429)
at TestCardLayout.main(TestCardLayout.java:62)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
/**
* Test how a CardLayout lays out its cards.
*
* @author GenePi
* @created 26 septembre 2002
*/
public class TestCardLayout
extends Frame
{
/**
* Create a frame with a CardLayout containing 2 panes.
*/
TestCardLayout()
{
setLayout(new CardLayout());
Panel panel1 = new TestPanel(new TestGridLayout(0,
2), "panel1");
panel1.add(new Label("panel1.label1"));
panel1.add(new TextField("panel1.field1"));
panel1.add(new Label("panel1.label2"));
panel1.add(new TextField("panel1.field2"));
add(panel1, "panel1");
Panel panel2 = new TestPanel(new TestGridLayout(0,
2), "panel2");
panel2.add(new Label("panel2.label1"));
panel2.add(new TextField("panel2.field1"));
panel2.add(new Label("panel2.label2"));
panel2.add(new TextField("panel2.field2"));
panel2.add(new Label("panel2.label3"));
panel2.add(new TextField("panel2.field3"));
add(panel2, "panel2");
pack();
}
/**
* The main program for the TestCardLayout. Display the frame for 4s
with the
* first pane, then shows the other one for 4s and exits.
*
* @param args The command line arguments
*/
public static void main(final String[] args)
{
TestCardLayout win = new TestCardLayout();
win.show();
try
{
Thread.sleep(4000L);
}
catch (InterruptedException ie)
{
}
System.err.println("\nShowing next pane\n");
CardLayout layout = (CardLayout) win.getLayout();
layout.last(win);
try
{
Thread.sleep(4000L);
}
catch (InterruptedException ie)
{
}
System.exit(0);
}
}
/**
* Instrumented GridLayout class that prints calls to layoutContainer method.
*/
class TestGridLayout
extends GridLayout
{
/**
* Create the layout manager
*
* @param row Number of rows
* @param col Number of columns
*/
TestGridLayout(final int row, final int col)
{
super(row, col);
}
/**
* Print the state of the parent container and the call stack.
*
* @param parent The parent container.
*/
public void layoutContainer(final Container parent)
{
System.err.println("\nTestGridLayout.layoutContainer(" + parent
+ ")");
new Throwable().printStackTrace();
super.layoutContainer(parent);
}
/**
* Print the preferred size of the layout.
*
* @param parent The parent container
*/
public Dimension preferredLayoutSize(final Container parent)
{
System.err.print("\nTestGridLayout.preferredLayoutSize(" +
parent + ")=");
Dimension dim = super.preferredLayoutSize(parent);
System.err.println(dim);
return dim;
}
}
/**
* An instrumented panel to know its visibility state.
*/
class TestPanel
extends Panel
{
// Identifier of the panel
private String _id;
/**
* Create the panel.
*
* @param layout The layout manager
* @param id The identifier of the panel
*/
TestPanel(final LayoutManager layout, final String id)
{
super(layout);
_id = id;
}
/**
* Displays the visibility of the panel.
*
* @param visible The new Visible value
*/
public void setVisible(final boolean visible)
{
System.err.println("\nTestPanel:" + _id + ".setVisible(" +
visible + ")");
super.setVisible(visible);
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Use extended layout managers and override method
layoutContainer to check the size of the parent container.
public void layoutContainer(final Container parent)
{
Dimension dim = parent.getSize();
if (dim.width == 0 && dim.height == 0)
{
return;
}
super.layoutContainer(parent);
}
(Incident Review ID: 165019)
======================================================================
- duplicates
-
JDK-4690266 REGRESSION: Wizard Page does not move to the next page
-
- Resolved
-