Java — Как быстро остановить мерцание текста при использовании setText ()

#java #swing

#java #swing

Вопрос:

Итак, у меня возникли некоторые проблемы при попытке создать эффект телетайпа для моей программы swing. По сути, я хочу обновлять JFrame с шагом 40 мс новой буквой, «печатая» сообщение пользователю. Однако он сильно мерцает, когда я пытаюсь это сделать. Метод приведен ниже:

 public static void animateTeletype(String input, JTextArea displayArea) 
       throws InterruptedException {
    displayArea.setText("");
    String s = "";
    for(int i = 0; i<input.length(); i  ) {
        s  = input.substring(i, i 1);
        displayArea.setText(textToDisplay);
        Thread.sleep(40);
        displayArea.update(displayArea.getGraphics());
    }
}
  

Я полагаю, проблема связана с слишком быстрым обновлением текста, и ему приходится обновлять больше, чем он может обработать. Я не уверен, как бы я справился с этой проблемой, поскольку уменьшение времени тактирования приведет к слишком медленной прокрутке текста. Приветствуются любые советы!

** Я решил проблему. Это мой новый код:

 static Timer timer = null;
public static void animateTeletype(final String input, final JTextArea displayArea) throws InterruptedException
    {
        final String[] s = new String[1];
        s[0] = " ";
        final int[] i = new int[1];
        i[0] = 0;
        displayArea.setText("");    
        timer = new Timer(30, new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                s[0] = input.substring(i[0], i[0] 1);
                i[0]  ;
                displayArea.append(s[0]);
                if(displayArea.getText().equals(input))
                    timer.stop();
            }
        });
        timer.start();
    }
  

Комментарии:

1. Я надеюсь, вы не используете этот код в своем EDT .

Ответ №1:

 displayArea.update(displayArea.getGraphics());
  

Не используйте метод update(). Для этого никогда не бывает причин. Избавьтесь от этого утверждения.

Компоненты Swing автоматически перерисуют себя.

 displayArea.setText(textToDisplay);
  

Не используйте set setText(…) для добавления нового текста.

Вместо этого вы должны использовать:

 displayArea.append( "some more text" );
  

Не используйте Thread.sleep(40) для анимации. Если вам нужна анимация, используйте Swing Timer для планирования анимации.

Я предлагаю вам ознакомиться с другим разделом руководства по основам Swing. Может быть, что-то вроде How to Use Text Fields .

Комментарии:

1. Когда я не включаю строку обновления, компонент, похоже, не обновляется до завершения выполнения инструкции for. Он немного подождет, а затем отобразится вся строка.

2. @ThomasRichmond, расскажите нам, каким было ваше решение, оно будет полезно другим.

3. the component doesn't seem to update until the for statement completes. — это из-за Thread.sleep(). Я рассказал вам о правильном решении. 1) избавьтесь от Thread.sleep(), 2) избавьтесь от метода update (…). 3. Используйте таймер Swing.

4. Я избавился от Thread.sleep(). Вместо этого я использовал таймер, но, похоже, он по-прежнему не прокручивает текст.

5. @ThomasRichmond, текст должен прокручиваться автоматически. Для получения дополнительной информации см. раздел Прокрутка текстовой области . Если вам нужна дополнительная помощь, задайте новый вопрос с надлежащим SSCCE , который демонстрирует проблему.