JOptionPane.showMessageDialog усекает сообщение JTextArea

Моему Java-приложению с графическим интерфейсом нужно быстро отображать некоторый текст для конечного пользователя, поэтому служебные методы JOptionPane кажутся подходящими. Кроме того, текст должен быть доступен для выбора (для копирования и вставки) и может быть несколько длинным (~100 слов), поэтому он должен хорошо вписываться в окно (без текста за пределами экрана); в идеале все это должно отображаться сразу, чтобы пользователь мог читать его без необходимости взаимодействовать, поэтому полосы прокрутки нежелательны.

Я думал, что поместить текст в JTextArea и использовать его для сообщения в JOptionPane.showMessageDialog будет легко, но, похоже, текст обрезается!

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);
}

Диалог с усеченным текстом

Как я могу заставить текст полностью вписываться в панель параметров без полос прокрутки и выбирать для копирования/вставки?


person maerics    schedule 01.12.2010    source источник
comment
что, если я хочу получить несколько строк ввода от пользователя?   -  person java_enthu    schedule 14.10.2011
comment
@java_enthu: звучит как другая проблема, вы должны отправить новый вопрос, описывающий, что вы хотите сделать.   -  person maerics    schedule 14.10.2011


Ответы (4)


Если вам нужно отобразить строку неизвестной длины, вы можете задать количество строк «на лету»:

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);
}
person Yuri Joselson    schedule 12.08.2013

У вас есть правильная идея. Просто отрегулируйте строки вашего текстового поля.

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

Это, казалось, решило проблему для меня, используя 100 слов lorem ipsum.

person Joshua McKinnon    schedule 02.12.2010
comment
Как я могу придумать это число (10), не считая подсчета слов/символов и оценки того, сколько строк будет иметь данный фрагмент текста? Разве textArea не может просто сказать мне, сколько строк ему нужно? Я действительно надеялся, что есть автоматический способ сделать это, а не жестко кодировать какую-то константу, на случай, если будут какие-то выбросы... - person maerics; 02.12.2010
comment
Я думаю, вам просто нужно рассчитать строки самостоятельно и установить их динамически, например. строки = длина строки/столбцы. - person William Niu; 02.12.2010

Попробуй это:

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);
person Huey    schedule 02.12.2010
comment
-1, похоже на ответ, который я дал час назад. Не вижу необходимости дублировать сообщения. - person camickr; 02.12.2010

person    schedule
comment
Идеально; это именно то, что мне нужно. Из любопытства, как магическое число 1 заставляет это работать? Я случайно пробовал другие значения (-1, 0), но безрезультатно. - person maerics; 02.12.2010
comment
Я не думаю, что 1 - это магическое число, ключевое число - это ширина, которая вызывает перенос. - person camickr; 02.12.2010
comment
Ах, хорошо, теперь, когда я думаю об этом, я, вероятно, играл с setPreferredSize, а не с setSize. Спасибо! - person maerics; 02.12.2010
comment
Да, обычно вы должны играть только с предпочтительным размером, поскольку менеджер компоновки будет использовать эту информацию. В этом случае текстовая область должна знать фактическую ширину компонента, чтобы она могла выполнять перенос текста, поэтому я предполагаю, что предпочтительный размер компонента также основан на его фактической ширине, поэтому вам нужно использовать setSize(). Похоже на проблему курицы и яйца. - person camickr; 03.12.2010