2

My Java GUI application needs to quickly show some text to the end-user, so the JOptionPane utility methods seem like a good fit. Moreover, the text must be selectable (for copy-and-paste) and it could be somewhat long (~100 words) so it must fit nicely into the window (no text off screen); ideally it should all be displayed at once so the user can read it without needing to interact, so scrollbars are undesirable.

I thought putting the text into a JTextArea and using that for the message in JOptionPane.showMessageDialog would be easy but it appears to truncate the text!

public static void main(String[] args) {
  JTextArea textArea = new JTextArea();
  textArea.setText(getText()); // A string of ~100 words "Lorem ipsum...\nFin."
  textArea.setColumns(50);
  textArea.setOpaque(false);
  textArea.setEditable(false);
  textArea.setLineWrap(true);
  textArea.setWrapStyleWord(true);
  JOptionPane.showMessageDialog(null, textArea, "Truncated!", JOptionPane.WARNING_MESSAGE);
}

Dialog with truncated text

How can I get the text to fit entirely into the option pane without scrollbars and selectable for copy/paste?

maerics
  • 151,642
  • 46
  • 269
  • 291

4 Answers4

6
import java.awt.*;
import javax.swing.*;

public class TextAreaPreferredHeight2
{
 public static void main(String[] args)
 {
  String text = "one two three four five six seven eight nine ten ";
  JTextArea textArea = new JTextArea(text);
  textArea.setColumns(30);
  textArea.setLineWrap( true );
  textArea.setWrapStyleWord( true );
  textArea.append(text);
  textArea.append(text);
  textArea.append(text);
  textArea.append(text);
  textArea.append(text);
  textArea.setSize(textArea.getPreferredSize().width, 1);
  JOptionPane.showMessageDialog(
   null, textArea, "Not Truncated!", JOptionPane.WARNING_MESSAGE);
 }
}
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Perfect; that's exactly what I need. Out of curiosity, how does the magic number "1" make this work? I had randomly tried other values (-1, 0) but to no effect. – maerics Dec 02 '10 at 06:50
  • 1
    I don't think 1 is a magic number, the key number is the width which causes the wrapping to occur. – camickr Dec 02 '10 at 16:13
  • Ah, ok, now that I think about it I was probably playing with `setPreferredSize` not `setSize`. Thanks! – maerics Dec 02 '10 at 16:15
  • 1
    Yes, you should normally only ever play with the preferred size since the layout manager will use this information. In this case the text area needs to know the actual width of the component so it can do the wrapping of the text, so I guess the preferred size of the component is also based on its actual width so you need to use setSize(). Seems like a bit of a chicken and egg problem. – camickr Dec 02 '10 at 21:22
3

If you need to display a string of an unknown length, you can set number of rows "on the fly":

public static void showMessageDialogFormatted(String msg, String title, int messageType, int columnWidth) {
    JTextArea textArea = new JTextArea(msg);
    textArea.setColumns(columnWidth);
    textArea.setRows(msg.length() / columnWidth + 1);
    textArea.setLineWrap(true);
    textArea.setEditable(false);
    textArea.setWrapStyleWord(true);
    JOptionPane.showMessageDialog(null, textArea, title, messageType);
}
2

You've got the right idea. Just adjust the rows of your textarea.

textArea.setRows(10); // or value that seems acceptable to you...

This seemed to fix the issue for me, using 100 words of lorem ipsum.

Joshua McKinnon
  • 24,489
  • 11
  • 57
  • 63
  • How can I come up with that number (10), short of doing a word/character count and estimating how many lines a given chunk of text will have? Can't the textArea just tell me how many rows it needs? I was really hoping there was an automatic way to do this, rather than hard coding some constant, in case there are some outliers... – maerics Dec 02 '10 at 01:06
  • 1
    I guess you just have to calculate the rows yourself and set it dynamically, e.g. rows = string-length / columns. – William Niu Dec 02 '10 at 01:14
-2

Try this:

JTextArea textArea = new JTextArea();
textArea.setText(getText());
textArea.setSize(limit, Short.MAX_VALUE); // limit = width in pixels, e.g. 500
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
Huey
  • 2,714
  • 6
  • 28
  • 34
  • -1, looks like the answer I gave 1 hour earlier. I don't see a the need for the duplicate posting. – camickr Dec 02 '10 at 05:08