JDK-4101306 : JSplitPane: setDividerLocation() doesn't work when called before validation
Type:Bug
Component:client-libs
Sub-Component:javax.swing
Affected Version:1.1.6,1.2.0
Priority:P3
Status:Closed
Resolution:Fixed
OS:generic,solaris_2.6,windows_nt
CPU:x86
Submitted:1997-12-23
Updated:1999-01-15
Resolved:1999-01-15
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
JSplitPane's setDividerLocation() does not appear to work unless the splitpane is already on screen
Comments
CONVERTED DATA
BugTraq+ Release Management Values
COMMIT TO FIX:
1.2fcs
generic
swing1.1
FIXED IN:
1.2fcs
swing1.1
INTEGRATED IN:
1.2fcs
swing1.1
14-06-2004
EVALUATION
[aim 1/11/98]
It does look on the first call to validate(), the BasicSplitPaneUI
is sizing the children to be their preferredSize, regardless of the
dividerLocation.
ralph.kar@Eng 1998-06-10
Here is a test case that demonstrates the problem:
import com.sun.java.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestApp extends JFrame implements ActionListener
{
JLabel label = new JLabel("Enter divider location [%]:");
JTextField text = new JTextField("20");
JButton preBut = new JButton("set and show");
JButton postBut = new JButton("show and set");
public TestApp() {
super("Testcase (4101306)");
preBut.addActionListener(this);
postBut.addActionListener(this);
this.getContentPane().setLayout(new GridLayout(4, 1));
this.getContentPane().add(label);
this.getContentPane().add(text);
this.getContentPane().add(preBut);
this.getContentPane().add(postBut);
this.addWindowListener(new WindowHandler());
this.setSize(200, 125);
this.setVisible(true);
}
public void actionPerformed(ActionEvent ev) {
double value = Double.valueOf(text.getText()).doubleValue();
if ((value < 0.0) || (value > 100.0)) {
System.err.println("Given value not between " +
"0 and 100");
return;
}
value /= 100.0;
if (ev.getSource() == preBut) {
new PreShownSplitter(value);
}
else if (ev.getSource() == postBut) {
new PostShownSplitter(value);
}
}
static public void main(String args[]) {
new TestApp();
}
}
class PreShownSplitter extends JFrame
{
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
true,
new JPanel(),
new JPanel());
public PreShownSplitter(double location) {
super("Set divider then show");
split.setDividerLocation(location);
this.getContentPane().add(split);
this.addWindowListener(new WindowHandler());
this.setSize(200, 200);
this.setLocation(250, 1);
this.setVisible(true);
}
}
class PostShownSplitter extends JFrame
{
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
true,
new JPanel(),
new JPanel());
public PostShownSplitter(double location) {
super("Show then set divider");
this.getContentPane().add(split);
this.addWindowListener(new WindowHandler());
this.setSize(200, 200);
this.setLocation(1, 200);
this.setVisible(true);
split.setDividerLocation(location);
}
}
class WindowHandler extends WindowAdapter
{
public void windowClosing(WindowEvent ev) {
if (ev.getWindow() instanceof TestApp) {
System.exit(0);
}
else {
ev.getWindow().dispose();
}
}
}
ralph.kar@Eng 1998-07-20
For now I will implement the fast solution (tracking the first occurence of setDividerLocation()).
Later we will probably have to rewrite the layout manager of the JSplitPane completely (will be necessary for some RFEs too). For Swing 1.1 this is too risky.
11-06-2004
SUGGESTED FIX
ralph.kar@Eng 1998-07-20
There are actually 2 solutions to the problem. The first (and cleaner) one requires a major rewrite of the layout manager that the JSplitPane uses. It would involve to use only the divider location in order to layout the componentns in the JSplitPane. Right now all components sizes matter.
The other (quick&dirty ?) solution is to track wether the location of the divider was set before a validation happened. Setting the divider location involves changing the size of the upper/left component. This size then mas to be used when the layout manager lays out the components for the very first time.