I have a panel layout issue that I can't seem to solve. I have the following code:
public class Test extends ApplicationFrame {
public Test(String title) {
super(title);
JPanel jpanel = new JPanel();
jpanel.setPreferredSize(new Dimension(100 * 2, 300));
jpanel.setBackground(new Color(0xFF0000));
JScrollPane scrollPane = new JScrollPane(jpanel);
scrollPane.setBackground(new Color(0xFF0000));
scrollPane.getViewport().setPreferredSize(new Dimension(100 * 2, 300));
this.add(scrollPane, BorderLayout.WEST);
this.setPreferredSize(new Dimension(500, 500));
}
public static void main(String args[]) {
Test test = new Test("Layout Test");
test.pack();
RefineryUtilities.centerFrameOnScreen(test);
test.setVisible(true);
}
}
to create the following layout:
When I drag the right hand side of the window and move it over into the red JPanel
and JScrollPane
, I'd like the horizontal scroll bars to appear on the JScrollPane
. But currently the window just shrinks without showing the horizontal scroll bar. Is this possible?
I'd like to keep the BorderLayout.WEST
since my use case for this is to keep a JFreeChart from stretching when I don't have a big enough chart to fill the entire window.
There are many reasons not to use setPreferredSize()
, but the critical one here is that the desired result depends on the preferred size of the enclosed components. In particular,
ChartPanel
has the default FlowLayout
specified by JPanel
, but the chart ignores this and adjusts to fill the space available; you can override getPreferredSize()
to choose any desired initial geometry.
The scroll bars of a JScrollPane
only appear when the size of the viewport is smaller than the size of the content. BorderLayout.WEST
and BorderLayout.EAST
don't change, so the scroll bars never appear.
Invoking pack()
"causes this Window
to be sized to fit the preferred size and layouts of its subcomponents." In the example below, the frame's size is artificially reduced after pack()
in order to cause the scroll bars to appear. GridLayout
causes the two panels to be equal is size. Resize the frame to see the effect.
Addendum: If you want a ChartPanel
to have a fixed size, add it to a JPanel
; the default FlowLayout
uses the preferred size.
public class ChartPanelTest {
private static final int N = 64;
private static final int SIZE = 400;
private static final Random random = new Random();
private static XYDataset createDataset() {
final TimeSeries series = new TimeSeries("Random Data");
Day current = new Day();
for (int i = 0; i < N; i++) {
series.add(current, random.nextGaussian());
current = (Day) current.next();
}
return new TimeSeriesCollection(series);
}
private static JFreeChart createChart(final XYDataset dataset) {
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Test", "Day", "Value", dataset, false, false, false);
return chart;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setLayout(new GridLayout(1, 0));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFreeChart chart = createChart(createDataset());
f.add(new JScrollPane(new JPanel() {
{
setBackground(Color.red);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
}));
f.add(new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
});
f.pack();
f.setSize(2 * (SIZE - N), SIZE - N);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With