JTextArea auto height resize - java

All component widths are same.
I have a JPanel (box layout; PAGE_AXIS).
I have added a Box.filler on it which has following specifications:
Min size(height) -1
Preferred size(height) JPanel height
Maximim size(height) JPanel height
I added JTextArea with border 7 pixels thick (only below).
When I type in text, the JTextArea expands, but not enough, and after a couple of lines the text goes off bounds (you can't see it anymore).
I can determine how many lines of text exist (using FontMetrics), and I can force setSize accordingly, but nothing really changes. Printing out JTextArea.getHeight() does show that the size has changed on my terms, but visually it stays as if it didn't. And I haven't forgot validating and repainting.
How can I force the JTextArea to resize to certain size?

You could alternatively just make the JTextArea wrap words?:
JTextArea.setWrapStyleWord(true);
you could also try setting the amount of rows using setRows(int rows) and then revalidate() and repaint()

You could put the JTextArea into a JScrollPane to keep the additional lines visible without changing the space the JTextArea needs on screen.
See the Oracle Tutorial on how to use Scroll Panes for more information.

Related

The size of a JTextArea

I have a set of JPanel's within a JFrame. One of the panels contains a JTextArea. At the moment I create this like so:
JTextArea = new JTextArea(5, 40);
And this gives me a text area which is 5 rows by (roughly) 40 columns.
Vertically this works as I'd like it to, the area fills the entire height of the parent container - probably because the parent is the only element positioned in that row.
Horizontally the parent width is determined by elements underneath and it is (usually) wider than the JTextArea is. So I end up with a text area with large margins on either side. What is worse, when I resize the frame smaller to the point where the text area is exactly the width of the parent container, it suddenly 'flicks' and changes into a text area that is 1 row high and is then the width of the parent.
Excuse the crude drawing below which hopefully illustrates the issue.
In short: How to I create a JTextArea that always fills the maximum space available to it? (and if possible with a minimum width after which a scrollbar appears if the user sizes the frame even smaller)
In the parent container of the JTextArea (denoted as Panel 1 in your drawing), call the function:
panel1.setLayout(new BorderLayout());
For reference, see this documentation page:
https://docs.oracle.com/javase/7/docs/api/java/awt/BorderLayout.html
As you only have a single child in panel1, the BorderLayout layout manager of panel1 will by default stretch the text area to use all available space in the parent container.
You may want to take away the constructor parameters specifying the size of your TextArea. The BorderLayout should take care of sizes for you :)
You can request that Swing respects a certain minimum size for the text area by calling:
textArea.setMinimumSize(new Dimension(minimum_width, minimum_height));
You have to use layout manager, for start see oficial Oracle docu about layout managers. For your situation, BorderLayout or GridBagLayout should work fine.
Start with:
panel1.setLayout(new BorderLayout());
or
panel1.setLayout(new GridBagLayout());
With GridBagLayout you can more preciselly do layouting (with BorderLayout you have five areas - no more, no less). With GridBagLayout you can do more complicated layouts.

Can't resize JLabels in BoxLayout

I'm trying to set up a few JLabels to use as buttons inside a BoxLayout, stacked on top of each other. The layout is fine, but I'm finding that I can't resize the labels to the dimensions I want. I'm using the following code to size them:
JLabel fileAddBtn = new JLabel("Add File", SwingConstants.CENTER);
fileAddBtn.setBorder(BorderFactory.createLineBorder(Color.black));
fileAddBtn.setMaximumSize(new Dimension(Integer.MAX_VALUE, fileAddBtn.getMinimumSize().height));
and
JLabel fileRemBtn = new JLabel("Remove File", SwingConstants.CENTER);
fileRemBtn.setBorder(BorderFactory.createLineBorder(Color.black));
fileRemBtn.setMaximumSize(new Dimension(Integer.MAX_VALUE, fileRemBtn.getMinimumSize().height));
As of now I have two labels, with one being longer than the other. They are both taking the width of the longer label, which is good, but the labels are hugging the edges of the text right to the nearest pixel. Is there any way to make the labels a little bigger so that there is a bit of a border around the labels? I've tried using setSize() but it doesn't take. I've also added straight values into the above code, but it doesn't change them either. I tried adding an EmptyBorder() around them, which worked for sizing, but it hid my line border which surrounds them. Any thoughts?
Is there any way to make the labels a little bigger so that there is a bit of a border around the labels?
Sure. Add an EmptyBorder.
But since the code is already adding a border to the labels, to retain that line border, make a CompoundBorder consisting of the empty border and the line border, and set the compound border to the label.
See also Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes.)

Get a Fixed sized GridLayout

I need to make a fixed sized for a GridLayout with 100 buttons located in the center portion of a BorderLayout. On the east portion of the border layout is another Gridlayout that keeps shrinking the center component whenever the text is longer then the size of the current JTextAreas located in the east. The JFrame is not resizable also.
Is there a way to get a fixed size for the center component while allowing the JTextArea to still expand?
"I need to make a fixed sized for a GridLayout with 100 buttons located in the center portion of a BorderLayout".
Sorry, but that's not going to work. BorderLayout doesn't work like that. You can nest JPanel containers with different Layout managers to get your desired effect.
"Gridlayout that keeps shrinking the center component whenever the text is longer then the size of the current JTextAreas located in the east."
You should wrap your text area in a JScrollPane, and setLineWrap(true) and setWrapStyleWord(true) on you text area. The last two will set it, so that the line typed wraps when it is reaching the right edge of the text area. Also If you are setting the size to the text area, don't. Instead, use the following constructor to set its size
JTextArea jta = new JTextArea(20, 50); <--- rows, and character columns
jta.setLineWrap(true);
jta.setWrapStyleWord(true);
JScrollPane scroll = new JScrollPane(jta);
container.add(scroll); <--- make sure you don add jta anywhere else
Without more context to your querstion, these are really the only valid suggestions I can make.

Java's FlowLayout does not resize correctly

I created a JFrame initialized with a BorderLayout and a JScrollPane as its CENTER element.
The scroll pane is set with VERTICAL_SCROLLBAR_ALWAYS and HORIZONTAL_SCROLLBAR_NEVER policies. The intent of my frame is to have a controlled width, while the height should grow/shrink as data is added/removed.
Inside my scroll pane, I added a simple JPanel (lets call it the content panel) which is initialized with a FlowLayout (and LEADING policy).
In order to test this, I simply populate my content panel with 20 JLabel("Item " + n) components where n is the loop counter.
I would expect to see my labels shown on a single row if the frame is large enough and the labels wrap to other lines when I shrink the width. But instead, there is only a single line displayed with no wrapping... ever.
Does anyone know why the flow layout does not wrap when a scroll pane is involved?
If I remove the scroll pane all together and put the content panel directly in the frame, the desired wrapping effect occurs, but if the frame height is shrunk smaller than the content panel height it just disappears.
The idea is that I want my labels to be wrapped when necessary but also always be visible if it means having to scroll up/down.
Any suggestions on how to fix this?
Thanks.
Wrap Layout gives an explanation and a solution.
If you work with the designer, you have to set the prefferedSize property to null (delete what is set) then set the preferred size by clicking the triple dots [...] button next to the prefferedsize property name and put your preferred value.
I encountered the same problem and it works for me.

How to set jTextArea to have height that matches the size of a text it contains (to avoid scrollbars)

This problem looks trivial, but I can't find the solution.
When I create a form it contains a JTextArea. I want to put large constant text in it. If the text is say 1000 lines long, I want my JTextArea to be 1000 lines high (to be large enough to display the entire text without scrollbars). JTextArea is inside a panel which can have scrollbar so it is not a problem when it gets too large (there are two JTextArea in that panel.. something like in a diff tool). Does anybody knows how can I achieve this? Thanks.
The BorderLayout will handle the scrollbar out of the box if you simply put your JTextAreain a JScrollPane before you add it to your JPanel. FlowLayout, on the other hand, does not. It will not display the scroll bar unless, as #Xorty intimates, you call setPreferedSize() on your JScrollPane and give it the dimension that you would like.
You can also use something like this (limited width, height depending on text, useful when showing info messages):
public JTextArea createTextAreaFitToText(String message, Dimension minimalSize){
JTextArea aMessagePanel = new JTextArea();
aMessagePanel.setText(message);
/*for modelToView to work, the text area has to be sized. It doesn't matter if it's visible or not.*/
aMessagePanel.setPreferredSize(minimalSize);
aMessagePanel.setSize(minimalSize);
Rectangle r = aMessagePanel.modelToView(aMessagePanel.getDocument().getLength());
Dimension d = new Dimension(minimalSize.width, r.y + r.height);
aMessagePanel.setPreferredSize(d);
return aMessagePanel;
}
To increase or decrease the height of JTextArea. When a text is entered, call for getPreferredSize() of JTextArea- it'll give you the size needed to display the whole text.
After that use setPrefferedSize() of JScrollPane to set the size of JTextArea
Well, first of all : it's JTextArea not jTextArea.
Now - put JTextArea into JScrollPane. When a text is entered, call for getPreferedSize() of JScrollPane - it'll give you precise size needed to display whole text. Also, I never use other LayoutManager than 'Free Design' from NetBeans Swing builder - so I am not sure how other LayoutManagers will behave there.

Categories

Resources