miglayout row format: JScrollPane containing a 1-line JTextArea
I w开发者_如何学Goant to display a one-line text label that has a horizontal scrollbar if necessary. (No vertical scrollbar since I know it's one line.)
I am implementing via a JScrollPane containing a JTextArea.
For layout manager, I am using MigLayout and can't seem to figure out what to use for the row format specification. If I just use []
then it works fine for no horizontal scrollbar, but when the scrollbar appears, it looks bad since the scrollbar takes up all the space.
What I would like to do is either:
- show the JScrollPane with a constant height that looks good when the scrollbar is present, and has extra space when the scrollbar is absent
- show the JScrollPane with variable height so that the height of the pane is the 1 line of text when the scrollbar is absent, or an additional space to accomodate the scrollbar when it's present
- show the JScrollPane in a way that only takes 1 row of text (e.g. the scrollbar is changed so that it eats up some of the horizontal space to the right of the text in question)
Any suggestions?
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
精彩评论