Interesting problem (and me not overly enthused with looking into jpa as I should )
Basically, it's not much a layout could do on its own: the pref size of the scrollPane differs depending on the visibility of the horizontal scrollBar. It's up to client code to dynamically tell the manager what to do with the to-be covered area, IMO. Below is a code-snippet to play with.
- it uses an invisible dummy component with the fixed size of the maybe visible horizontal scrollbar (yeah, gals, I know, that fixed size should be adjusted dynamically to any height changing properties of the scrollPane's horizontal scrollbar :-)
- it installs a componentListener on the scrollPane's horizontal scrollBar, adjusts the dummy's hidemode on visibility changes and revalidates the containing panel.
Works fine for Win/Nimbus, there's a glitch in Metal, though (and maybe other LAFs) which needs a magic number adjust of the diff to keep the layout steady
JTextArea area = new JTextArea("starting ", 1, 10);
JScrollPane areaScrollPane = new JScrollPane(area);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
areaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
Dimension dim = areaScrollPane.getPreferredSize();
areaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// get the height diff with/out horizontal scrollbar
int diff = dim.height - areaScrollPane.getPreferredSize().height;
areaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
LC lc = new LC().wrapAfter(2).debug(500);
final MigLayout layout = new MigLayout(lc);
final JPanel panel = new JPanel(layout);
panel.add(new JLabel("OneLineRow"));
panel.add(areaScrollPane);
// create and add an invisible filler
// note: metal needs magic adjust, dont know why
// diff -= 3;
final JComponent dummy = (JComponent) Box.createVerticalStrut(diff);
dummy.setVisible(false);
final String dummyConstraint = "span, hidemode ";
panel.add(dummy, dummyConstraint + "0");
// component listener which adjusts hidemode of filler on
// scrollpane's horizontal scrollbar showing/hiding
ComponentAdapter adapter = new ComponentAdapter() {
/**
* @inherited <p>
*/
@Override
public void componentShown(ComponentEvent e) {
layout.setComponentConstraints(dummy, dummyConstraint + "2");
panel.revalidate();
}
/**
* @inherited <p>
*/
@Override
public void componentHidden(ComponentEvent e) {
layout.setComponentConstraints(dummy, dummyConstraint + "0");
panel.revalidate();
}
};
areaScrollPane.getHorizontalScrollBar().addComponentListener(adapter);
panel.add(new JScrollPane(new JTable(20, 5)), "span");
showInFrame(panel, "one line textArea");
Feedback highly welcome, maybe there is a less artificial approach that I overlooked