This post originated from an RSS feed registered with Java Buzz
by Danno Ferrin.
Original Post: Flattening the JSplitPane Divider
Feed Title: And They Shall Know Me By My Speling Errors
Feed URL: http://shemnon.com/speling/archives/cat_GUI.rdf
Feed Description: Danno Ferrin's Many Reasons he was a Comp Sci Major and not an English Major
You can do just about anything with Swing... Iff you know the magic internal classes to monkey with.
Todays example has to do with the JSplitPane. For a GUI I am working on I needed to allow a list box on the left to be resized by the user while keeping some content on the right, but it can't be to obtrusive or distracting. This is obviously what the JSplitPane was meant to solve, except for the part where the implementation always paints the whole freaking thing! What I want is what is on the bottom and what I get by default is on the top.
So how do I fix this? I need to override the UI painters. Usually this isn't for the faint of heart, but in this case it is for the faint of heart! You see the basic plaf split panel divider painter only paints the associated border for the split pane divider, and maybe the expand buttons.
So all we need to insure is (a) we use some variant of the BasicSplitPaneDivider and (b) that it doesn't get any border set to it. I'll wave my hand over some access issues and complaints about global defaults, and show you what finally worked...
jSplitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
};
}
});
jSplitPane.setBorder(null);
The how without the why is that I create my own UI for the BasicSplitPane that uses a custom BasicSplitPaneDivider that is oblivious to any border set on it.
Here the complete demo that spits up the frames I took the screen shots from.
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
public class FlatSplitPaneDivider {
public static void flattenSplitPane(JSplitPane jSplitPane) {
jSplitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
};
}
});
jSplitPane.setBorder(null);
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(200, 200);
JPanel p = new JPanel();
p.setLayout(new GridLayout(0, 1));
f.getContentPane().add(p);
JSplitPane sp = new JSplitPane();
sp.setLeftComponent(new JLabel("This is the Top Left Label"));
sp.setRightComponent(new JLabel("This is the Top Right Label"));
sp.setDividerLocation(100);
p.add(sp);
sp = new JSplitPane();
sp.setLeftComponent(new JLabel("This is the Bottom Left Label"));
sp.setRightComponent(new JLabel("This is the Bottom Right Label"));
sp.setDividerLocation(100);
flattenSplitPane(sp);
p.add(sp);
f.setVisible(true);;
}
}