JScrollPanes, JTextAreas, and maximum sizes
-
18-06-2021 - |
Question
Context: In a flashcard application, I have a view for a CardData
(a data structure representing one side of a flashcard). It has, in its most basic form, a String text
. The view (known as CardDataView
) consists of the text
in an uneditable JTextArea
inside a JScrollPane
.
At one point, I need to line up (vertically) a bunch of these CardDataView
s, so I put them in a vertical Box
.
Here's the problem: when I expand the window from it's "preferred" size (as determined by pack
) and then size it back down, the JScrollPane adds a horizontal scroll bar and allows me to scroll horizontally in the text field. Essentially, it's sizing up the text area when it shouldn't be.
Here's my code (stripped down and simplified):
public class DebugTest {
public static void main(String[] args) {
CardDataView cdv = new CardDataView(new CardData(
"Lorem ipsum dolor sit amet filler filler filler"));
JFrame frame = new JFrame();
frame.add(new JScrollPane(cdv), BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class CardData {
private String text; // text on the card
/*
* NOTE: This class has been simplified for SSCCE purposes. It's not really
* just a String field in production; rather, it has an image and other
* properties.
*/
public CardData(String text) {
super();
this.text = text;
}
public String getText() {
return text;
}
}
class CardDataView extends Box {
private JTextArea txtrText; // the text area for the text
/*
* NOTE: As with CardData, this class has been simplified. It's not just a
* JTextArea; it's also an ImageView (custom class; works fine), among other
* things.
*/
public CardDataView(CardData data) {
super(BoxLayout.Y_AXIS);
txtrText = new JTextArea();
txtrText.setLineWrap(true);
txtrText.setRows(3);
txtrText.setEditable(false);
txtrText.setWrapStyleWord(true);
final JScrollPane scrollPane = new JScrollPane(txtrText);
add(scrollPane);
txtrText.setText(data.getText());
}
}
Now, something that really confuses me (unless I'm going about it wrong) is that if I essentially inline the data and view classes, by just creating a text area with text and a scroll pane (even with setting the same number of rows, same wrap settings, etc.), it behaves as expected. What could be happening?
Concerns:
- All imports are in order.
- If you're wondering why CardLayoutView
is a Box
: in production, it has more than just a text box. The same error happens when it's a JPanel
and I setLayout
instead of super
.
- The same glitch happens if I don't use the CardData
class at all (and set the text area's text manually).
Any ideas?
Solution
Putting my comment to answer :
Use GridBagLayout
with GridBagConstraints.VERTICAL/NONE
as the gridBagLayoutObject.fill
value, instead of BoxLayout
. Since when adding components to the CENTER
of the JFrame
, BorderLayout
never respects the preferredSize()
for the CENTER
component. Hence try to add your stuff to a JPanel
and then put this JPanel
at the CENTER
of the JFrame
.