Расширяемая JTextArea

Часть приложения, которое я создаю, требует, чтобы я отображал переменное количество текста в каком-то нередактируемом компоненте. В настоящее время это реализовано в JTextArea, но JTextArea имеет только функцию setRows() для установки размера компонента по вертикали.

Мне нужен компонент, который будет расширяться до необходимого размера. Это не представляет проблемы, так как панель, в которую встроена эта штука, прокручивается. Не обязательно, чтобы все они появлялись в какое-то конкретное время, но они должны быть видны. (И мне не нужны полосы прокрутки внутри полос прокрутки, которые я считаю мерзостью.

Какой компонент Swing лучше всего соответствует этим требованиям?

(Примечание: я спрашиваю об этом здесь только потому, что весь #$%^&* сайт документации Oracle Java, включая все демонстрации и учебные пособия по Swing, похоже, сейчас недоступен).


person Steve Cohen    schedule 23.03.2012    source источник


Ответы (2)


Мне удалось создать рабочий прототип для решения проблем с динамическим изменением размера в исходной проблеме. По мере добавления текста размер текстовой области изменяется, чтобы стать достаточно большим, чтобы вместить текст. Очевидно, используйте setEditable(false), чтобы остановить редактирование текста. Надеюсь, это даст вам некоторые идеи.

  • установить текст
  • измените количество столбцов на приблизительное значение - здесь я использовал квадратный корень из общего количества символов * произвольный коэффициент.
  • не текстовая область имеет разумную ширину, но нам все равно нужно исправить высоту.
  • установите предпочтительный размер на низкое значение - это приведет к пересчету
  • установите предпочтительную высоту на минимальную высоту - она ​​рассчитывается из минимальной ограничивающей рамки содержимого.

Код

JFrame frame = new JFrame();
GroupLayout gLayout = new GroupLayout(frame.getContentPane());
frame.getContentPane().setLayout(gLayout);

final JTextArea area = new JTextArea();
area.setEditable(false);
area.setLineWrap(true);
area.setWrapStyleWord(true);

JButton button = new JButton("Add more");
button.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        area.setText(area.getText()
                + "apple banana carrot dingo eagle fox gibbon ");

        // set approx number of cols
        int chars = area.getText().length();
        int cols = (int) Math.round(Math.sqrt(chars) * 1.3);
        area.setColumns(cols);

        // force recalculation
        area.setPreferredSize(new Dimension(25, 25));

        // downsize
        area.setPreferredSize(new Dimension(
                area.getPreferredSize().width,
                area.getMinimumSize().height));

    }
});

ParallelGroup hGroup = gLayout
        .createParallelGroup()
        .addComponent(button)
        .addComponent(area, GroupLayout.PREFERRED_SIZE,
                GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE);
gLayout.setHorizontalGroup(hGroup);

SequentialGroup vGroup = gLayout
        .createSequentialGroup()
        .addComponent(button)
        .addComponent(area, GroupLayout.PREFERRED_SIZE,
                GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE);
gLayout.setVerticalGroup(vGroup);

frame.setSize(600, 500);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

frame.invalidate();
frame.validate();
frame.setVisible(true);
person Adam    schedule 23.03.2012

Эмм... В случае, если вы не хотите вводить текст, вам не нужен JTextArea... Просто для отображения текста вы можете просто использовать JLabel; JLabel поддерживает текстовый формат html, поэтому вы можете легко использовать его следующим образом.

...

JPanel aPanel=new JLanel(new FlowLayout());
JLabel aLabel=new JLabel();
aPanel.add(aLabel);


void showFormattedText(String html)
{
 aLabel.setText(html);
}

...

Как вы уже догадались, форматированный текст может быть примерно таким

<html>
Put some text<br>
...<br>

</html>

Я надеюсь, что вы получили концепцию

...

мини-парсер — не тестировался

  String getFormattedText(String text)
{
  char commonBR='\n';
  String htmlBR="<br>";
  char check;
  String result="";

  for(int i=0; i<text.length(); i++)
  {
      check=text.charAt(i);
      if(check==commonBR)

    {

    result+=htmlBR;
    continue;
    }

    result+=check;

     }

     return result;

    }

...

void test
{
       String text="Hello world \n Hello World once again \n ...and again ";

       System.out.println(this.getFormattedText(text));
}

... это не окончательное решение, а базовая концепция. Я надеюсь, что это было полезно

Удачи

person user592704    schedule 23.03.2012
comment
Спасибо. Я унаследовал этот код, и именно его они использовали. Однако я согласен с вами, что JTextArea не нужен, так как нет редактирования. Просто я вас понимаю, поскольку это html, если я не добавлю теги ‹br›, будет ли JLabel достаточно умным, чтобы разбивать строки самостоятельно и добавлять строки по мере необходимости (как html-страница)? Текст, который я показываю, представляет собой просто случайную строку символов, которые были введены где-то еще. И будет ли он достаточно умен, чтобы разбить границы слов? Если так, то это как раз то, что мне нужно. - person Steve Cohen; 24.03.2012
comment
Put some text<br> Используйте стили, а не разрывы строк. Таким образом, текст может переноситься на следующую строку по мере необходимости без каких-либо осложнений. См. пример. - person Andrew Thompson; 24.03.2012
comment
@SteveCohen Нет, содержимое HTML не будет переноситься автоматически. Посмотрите мой пример с использованием CSS, чтобы исправить это. - person Andrew Thompson; 24.03.2012
comment
если это веб-приложение, для него полезно передавать данные в формате html; Хотя вы говорили, что мне нужен компонент, который будет расширяться до необходимого размера. Таким образом, максимальный размер должен быть пределом длины строки содержимого, верно? Как будто вы собираетесь показать сообщение в том виде, в котором оно было написано раньше, со всем его форматированием? Итак, вам нужно уловить все ранее введенное форматирование... Конечно, вы можете сделать свой текст зависимым от ширины JLabel (добавьте для него CSS), но если вы хотите, чтобы JLabel зависел от длины текстовых строк, вместо этого вы можете создать что-то вроде мини-парсера для ваше приложение... - person user592704; 24.03.2012
comment
... например, вы можете поймать каждый символ \n и заменить его на ‹br›. Это очень простой код; Я только начинаю его основу... смотрите мой ответ, отредактированный - person user592704; 24.03.2012