2

I'm aware of this thread showing a way to do but it leads to strange behaviors in my case and i'm wondering if there is no simpler way to do it.

I need to know the size my JTextArea will have after setting the text. Here is how i do at the moment:

tarea.getLineCount() * tarea.getRowHeight();

It works unless there is no line wrapping. I'd like to do the same calculation with line wrapping. Is there any to know when a line wrapping happen? This way i would only need to increment the current line count by one.

EDIT:

Here is (maybe) a solution i found. It's almost copy paste of this by @camickr.

int rowStartOffset = textComponent.viewToModel(new Point(0, 0));
int endOffset = textComponent.viewToModel(new Point(0, textComponent.getHeight()));

int count = 0; //used to store the line count
while (rowStartOffset < endOffset) {
    try {
        rowStartOffset = Utilities.getRowEnd(textComponent, rowStartOffset) + 1;
    } catch (BadLocationException ex) {
        break;
    }
    count++;
}

I made few tests with/without line wrapping enabled and it seemed to work.

Community
  • 1
  • 1
nathan
  • 1,111
  • 3
  • 18
  • 33
  • If it is not for edit, use a multi-line `JLabel`. – Andrew Thompson Oct 11 '12 at 10:43
  • someone will crucify you for that :-) – mKorbel Oct 11 '12 at 10:56
  • @mKorbel how seriously? what i did wrong? But thanks, i will consider using multiline jlabel. – nathan Oct 11 '12 at 10:58
  • uuuups (my bad) this was addresed to @Andrew Thompson, but maybe he has important reason for his advice, :-) will ask for additional details, reason(s) :-), then this thread could be very nice with funny comments, aaach – mKorbel Oct 11 '12 at 11:01
  • 1
    and until this moment you can to read and try [Text Component Line Number](http://tips4java.wordpress.com/2009/05/23/text-component-line-number/) by @camickr – mKorbel Oct 11 '12 at 11:03
  • @mKorbel great! i think i might be able to extract the interesting part in my case out of this. Will edit the question if i run in further troubles :-) – nathan Oct 11 '12 at 11:53
  • OK. Edited the question with potential solution. – nathan Oct 11 '12 at 12:13
  • 1
    @mKorbel It really depends on what the OP is trying to achieve. If they do not clarify things like whether or not the area is for edit, I am just making guesses. – Andrew Thompson Oct 11 '12 at 12:46

1 Answers1

0

It seems to me that so long as you haven't done called setPreferredSize on the Text Area, the getPreferredSize method should give you exactly what you're looking for without the hassle...

This is the reason why you shouldn't call setPreferredSize to do layout stuff. Preferred size is supposed to be calculated by the component (when text is set for example).

Let me know if I'm missing the point ;)

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class CalculateTextAreaSize extends Box{

    public CalculateTextAreaSize(){
        super(BoxLayout.Y_AXIS);

        final JTextArea text = new JTextArea("I've\nGot\nA\nLovely\nBunch\nof\nCoconuts!\n");

        JScrollPane pane = new JScrollPane(text);

        add(pane);

        JButton button = new JButton("Set Text!");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                text.insert("Longish string - how long will it be?", text.getDocument().getLength());
                //The size it will be once everything is figured out
                System.out.println(text.getPreferredSize());
                //The size it is now because no rendering has been done
                System.out.println(text.getSize());
            }
        });
        add(button);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new CalculateTextAreaSize());
        frame.validate();
        frame.pack();
        frame.setVisible(true);
    }

}
Nick Rippe
  • 6,465
  • 14
  • 30