-
Bug
-
Resolution: Not an Issue
-
P3
-
None
-
1.4.1, 1.4.1_02, 1.4.2
-
x86
-
windows_2000, windows_xp
Name: jk109818 Date: 04/23/2003
FULL PRODUCT VERSION :
1.4.1_02-b06
FULL OS VERSION :
Windows XP Home 2002
A DESCRIPTION OF THE PROBLEM :
A dialog that uses SpringLayout works fine in jre 140_01 but does not work in jre 141_02. It includes a table and textarea that do not display at all, even when the dialog is resized. I have included the source code below.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
source is attached below, includes main() to open dialog
EXPECTED VERSUS ACTUAL BEHAVIOR :
dialog should work as it does in 140_01
dialog no longer works
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.table.AbstractTableModel;
/**
* This class demonstrates a bug in SpringLayout.
* This dialog works ok with jre 140_01 but not
* jre 141_02.
*/
public class SpringDialog extends JDialog implements ActionListener {
class ParamTableModel extends AbstractTableModel {
//the opening table has 6 rows which allows
//table space to be allocated to fit that many
String[][] data = { { "", "" }, {
"", "" }, {
"", "" }, {
"", "" }, {
"", "" }, {
"", "" }
};
public int getColumnCount() {
return 2;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
if (col == 0)
return "Name";
return "Value";
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public boolean isCellEditable(int row, int col) {
return col == 1;
}
public void updateParameterData() {
/*Vector list = model.parameterList();
String[][] newData = new String[list.size()][2];
String[] listParam;
String[] modelParam;
for (int i = 0; i < list.size(); i++) {
listParam = (String[]) list.elementAt(i);
modelParam = new String[2];
modelParam[0] = listParam[0];
modelParam[1] = listParam[1];
newData[i] = modelParam;
}
data = newData;
fireTableDataChanged();*/
}
public void setValueAt(Object value, int row, int col) {
/*String name = (String) getValueAt(row, 0);
String confirmedValue =
model.confirmParamValue(name, (String) value);
if (confirmedValue == null)
return;
data[row][col] = confirmedValue;
fireTableCellUpdated(row, col);*/
}
}
/**
* Create and open a new dialog.
*/
public static void main(String[] args) {
SpringDialog dialog = new SpringDialog(new JFrame());
dialog.show();
}
private ParamTableModel dataModel;
private JTable table;
/**
* Create a modal dialog for component.
*/
public SpringDialog(JFrame frame) throws HeadlessException {
super(frame, "Spring Test Dialog", true);
layoutDialog();
}
public void actionPerformed(ActionEvent e) {
if ("exit".equals(e.getActionCommand())) {
System.exit(0);
return;
}
}
/**
* Layout the dialog controls.
*/
protected void layoutDialog() {
getContentPane().setLayout(new BorderLayout());
int numPairs = 3;
Component[] leftComp = new Component[numPairs];
Component[] rightComp = new Component[numPairs];
JButton button1 = new JButton("Button1");
button1.setActionCommand("button1");
JButton button2 = new JButton("Button2");
button2.setActionCommand("button2");
leftComp[0] = button1;
leftComp[1] = button2;
leftComp[2] = new JLabel("Table:");
JLabel stylesheetLabel = new JLabel("label1");
rightComp[0] = stylesheetLabel;
JLabel resultLabel = new JLabel("label2");
rightComp[1] = resultLabel;
rightComp[2] = new JLabel("");
JPanel labelPanel = createLabelPanel(leftComp, rightComp, 5, 5, 5, 5);
getContentPane().add(labelPanel, BorderLayout.NORTH);
dataModel = new ParamTableModel();
table = new JTable(dataModel);
table.getTableHeader().setReorderingAllowed(false);
JScrollPane scrollpane = new JScrollPane(table);
scrollpane.setBorder(BorderFactory.createEtchedBorder());
//set pref. size so that centerPanel will allocate
//correct size to the log panel
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setColumnSelectionAllowed(false);
table.setRowSelectionAllowed(false);
JTextArea textArea = new JTextArea();
textArea.setBorder(BorderFactory.createEtchedBorder());
JPanel centerPanel = createCenterPanel(scrollpane, textArea, 5, 5);
getContentPane().add(centerPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JButton closeButton = new JButton("Exit");
closeButton.setActionCommand("exit");
closeButton.addActionListener(this);
buttonPanel.add(closeButton);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
pack();
setSize(500, 400);
setLocationRelativeTo(this.getOwner());
//send this now to clear (or show) parameters
//after table sizing and layout
dataModel.updateParameterData();
}
private JPanel createCenterPanel(
Component top,
Component bottom,
int xPad,
int yPad) {
SpringLayout layout = new SpringLayout();
JPanel parent = new JPanel(layout);
parent.add(top);
parent.add(bottom);
Spring xPadSpring = Spring.constant(xPad);
Spring yPadSpring = Spring.constant(yPad);
Spring xPadSpring2 = Spring.sum(xPadSpring, xPadSpring);
Spring yPadSpring2 = Spring.sum(yPadSpring, yPadSpring);
SpringLayout.Constraints consTop = layout.getConstraints(top);
SpringLayout.Constraints consBottom = layout.getConstraints(bottom);
SpringLayout.Constraints consParent = layout.getConstraints(parent);
consTop.setX(xPadSpring);
consTop.setWidth(
Spring.sum(consParent.getWidth(), Spring.minus(xPadSpring2)));
consTop.setY(yPadSpring);
consTop.setHeight(Spring.constant(top.getPreferredSize().height));
consBottom.setX(xPadSpring);
consBottom.setWidth(consTop.getWidth());
consBottom.setY(Spring.sum(consTop.getY(), consTop.getHeight()));
consBottom.setHeight(
Spring.sum(
consParent.getHeight(),
Spring.minus(consBottom.getY())));
return parent;
}
/**
* Creates a panel that uses a SpringLayout to present
* pairs of components. For example:
* <pre>
* LLLL RRR
* LL RRR
* L RRR
* LLLLL RRR
* </pre>
* where the max of the widths of the L (left) components
* dictates the x location of the R (right) components.
* The width of the Rs is locked to that of the container
* so that all extra space is given to them.
*
* Copied from SpringLayout demo in the java 1.4 tutorial.
* Some minor changes were made and are noted below.
*/
private JPanel createLabelPanel(
Component[] leftComponents,
Component[] rightComponents,
int initialX,
int initialY,
int xPad,
int yPad) {
SpringLayout layout = new SpringLayout();
int numRows = Math.max(leftComponents.length, rightComponents.length);
// The constant springs we'll use to enforce spacing.
Spring xSpring = Spring.constant(initialX);
Spring ySpring = Spring.constant(initialY);
Spring xPadSpring = Spring.constant(xPad);
Spring yPadSpring = Spring.constant(yPad);
Spring negXPadSpring = Spring.constant(-xPad);
// Create the container and add the components to it.
JPanel parent = new JPanel(layout);
for (int i = 0; i < numRows; i++) {
parent.add(leftComponents[i]);
parent.add(rightComponents[i]);
}
// maxEastSpring will contain the highest min/pref/max values
// for the right edges of the components in the first column
// (i.e. the largest X coordinate in a first-column component).
// We use layout.getConstraint instead of layout.getConstraints
// (layout.getConstraints(comp).getConstraint("East"))
// because we need a proxy -- not the current Spring.
// Otherwise, it won't take the revised X position into account
// for the initial layout.
Spring maxEastSpringLeft =
layout.getConstraint("East", leftComponents[0]);
for (int row = 1; row < numRows; row++) {
maxEastSpringLeft =
Spring.max(
maxEastSpringLeft,
layout.getConstraint("East", leftComponents[row]));
}
// Lay out each pair. The left column's x is constrained based on
// the passed x location. The y for each component in the left column
// is the max of the previous pair's height. In the right column, x is
// constrained by the max width of the left column (maxEastSpringLeft),
// y is constrained as in the left column, and the width is
// constrained to be the x location minus the width of the
// parent container. This last constraint makes the right column fill
// all extra horizontal space.
SpringLayout.Constraints lastConsL = null;
SpringLayout.Constraints lastConsR = null;
Spring parentWidth = layout.getConstraint("East", parent);
Spring rWidth = null;
Spring maxHeightSpring = null;
Spring rX = Spring.sum(maxEastSpringLeft, xPadSpring);
//right col location
Spring negRX = Spring.minus(rX); //negative of rX
for (int row = 0; row < numRows; row++) {
SpringLayout.Constraints consL =
layout.getConstraints(leftComponents[row]);
SpringLayout.Constraints consR =
layout.getConstraints(rightComponents[row]);
consL.setX(xSpring);
consR.setX(rX);
//modified to equalize height so labels will
//center vertically next to buttons
consR.setHeight(consL.getHeight());
rWidth = consR.getWidth();
//get the spring that tracks this
//component's min/pref/max width after
//setting the X spring but before
//setting the width spring (to avoid
//a circularity); we really only
//need to do this once for the
//textfield case, since they have the
//same size info
//XXX To account for other cases,
//XXX we should probably take the max
//XXX of the widths.
//This is used to set the container's
//width after this loop.
consR.setWidth(
Spring.sum(Spring.sum(parentWidth, negRX), negXPadSpring));
if (row == 0) {
consL.setY(ySpring);
consR.setY(ySpring);
maxHeightSpring =
Spring.sum(
ySpring,
Spring.max(consL.getHeight(), consR.getHeight()));
} else { // row > 0
Spring y =
Spring.sum(
Spring.max(
lastConsL.getConstraint("South"),
lastConsR.getConstraint("South")),
yPadSpring);
consL.setY(y);
consR.setY(y);
maxHeightSpring =
Spring.sum(
yPadSpring,
Spring.sum(
maxHeightSpring,
Spring.max(consL.getHeight(), consR.getHeight())));
}
lastConsL = consL;
lastConsR = consR;
} // end of for loop
// Wire up the east/south of the container so that the its preferred
// size is valid. The east spring is the distance to the right
// column (rX) + the right component's width (rWidth) + the final
// padding (xPadSpring).
// The south side is maxHeightSpring + the final padding (yPadSpring).
SpringLayout.Constraints consParent = layout.getConstraints(parent);
//modified to not use rWidth - let parent fill space
//consParent.setConstraint(
// "East",
// Spring.sum(rX, Spring.sum(rWidth, xPadSpring)));
//modified to not use yPadSpring at bottom
//consParent.setConstraint(
// "South",
// Spring.sum(maxHeightSpring, yPadSpring));
consParent.setConstraint("South", maxHeightSpring);
return parent;
}
}
---------- END SOURCE ----------
Release Regression From : 1.4.0_01
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 183178)
======================================================================