2

Я хочу знать, когда я пишу, и когда я удаляю, но после задержки на 0,5 секунды он скажет мне: «Вы перестали писать/удалять» Однако это только показывает это сообщение, и оно удалите или напишите после половины второй задержки.DocumentListener with Thread.sleep

Как правильно использовать Thread.sleep(500);?

Мой текущий исходный код:

import java.awt.BorderLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTextField; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 


public class TextChangedFrame extends JFrame { 

    JTextField textField = new JTextField("Put your text here"); 
    JLabel label = new JLabel("You have written: "); 

    public TextChangedFrame() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(300, 100); 
     setLayout(new BorderLayout()); 
     getContentPane().add(textField, BorderLayout.CENTER); 
     getContentPane().add(label, BorderLayout.SOUTH); 
     textField.getDocument().addDocumentListener(new DocumentListener() { 

      public void insertUpdate(DocumentEvent e) { 
       label.setText("I'm writting: " + textField.getText()); 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException ex) { 

       } 
       label.setText("I stopped writing"); 
      } 

      public void removeUpdate(DocumentEvent e) { 
       label.setText("I'm deleting"); 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException ex) { 

       } 
       label.setText("I stopped deleting"); 
      } 

      public void changedUpdate(DocumentEvent e) { 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     TextChangedFrame frame = new TextChangedFrame(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

Никогда не называйте 'Thread.sleep (...)' в потоке отправки событий Swing, EDT. Когда-либо. Если вы не хотите, чтобы все приложение спало. –

+0

Ow, так как я могу это сделать? – DavidM

+0

Я не уверен, что вы просите. Я отредактировал, чтобы попытаться уточнить, но это очень помогло бы, если бы вы могли отредактировать свой вопрос для деталей. В настоящее время кажется, что вы спрашиваете, что делает 'thread.sleep (int x)', что приостанавливает любые операции, которые текущий поток выполняет для 'x' миллисекунд (Thread.sleep (1000) = 1 секунда). – Azulflame

ответ

2

Опять же, использовать Swing-таймер, чтобы сделать грязную работу. То, что вы делаете, - это когда вы редактируете или удаляете, вызывают повторный запуск таймера, чтобы повторно установить таймер и запустить его. Метод restart() остановит таймер, если он запущен.

 public void insertUpdate(DocumentEvent e) { 
     label.setText(EDITING); 
     writeDeleteTimer.restart(); 
    } 

Например:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.*; 

import javax.swing.*; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

@SuppressWarnings("serial") 
public class TextChangedFrame extends JPanel { 

    public static final String STOPPED_EDITING = "No Longer Editing or Deleting"; 
    private static final String EDITING = "Editing"; 
    private static final String DELETING = "Deleting"; 
    private static final int TIMER_DELAY = 500; 
    private static final int PREF_W = 400; 
    private static final int PREF_H = 100; 
    private JTextField textField = new JTextField("Put your text here"); 
    private JLabel label = new JLabel("You have written: "); 
    private ActionListener timerListener = new TimerListener(); 
    private Timer writeDeleteTimer = new Timer(TIMER_DELAY, timerListener); 

    public TextChangedFrame() { 
     setLayout(new BorderLayout()); 
     add(textField, BorderLayout.CENTER); 
     add(label, BorderLayout.SOUTH); 
     textField.getDocument().addDocumentListener(new DocumentListener() { 

     public void insertUpdate(DocumentEvent e) { 
      label.setText(EDITING); 
      writeDeleteTimer.restart(); 
     } 

     public void removeUpdate(DocumentEvent e) { 
      label.setText(DELETING); 
      writeDeleteTimer.restart(); 
     } 

     public void changedUpdate(DocumentEvent e) { 
     } 
     }); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class TimerListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent evt) { 
     label.setText(STOPPED_EDITING); 
     Timer timer = (Timer) evt.getSource(); 
     timer.stop(); 
     } 
    } 

    private static void createAndShowGui() { 
     TextChangedFrame mainPanel = new TextChangedFrame(); 

     JFrame frame = new JFrame("TextChangedFrame"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

Ответ отредактирован: нет необходимости воссоздать объект Timer. Просто назовите restart() на нем, так как он остановит текущий таймер, если он запущен.

+0

Спасибо! Это то, что я искал! Он работает правильно! :) – DavidM

+0

@David: см. Редактирование и упрощение кода. Не нужно постоянно воссоздавать таймер. Просто назовите 'restart()' на нем. –

2

Этот вопрос довольно беден, и не очень понятно, поэтому я не могу дать точный ответ, пока этот вопрос не будет прояснилось.

Похоже, что вы используете Thread.sleep(500), чтобы вызвать задержку на 500 миллисекунд. В большинстве программ это будет работать.

Thread.sleep(int x) приостанавливает (или замораживает, в зависимости от того, кого вы запрашиваете) текущая операция для x миллисекунд (в вашем случае 500 миллисекунд).

В приложении, которое вы используете, вы используете его для приостановки изменения текста. Из-за его местоположения он в настоящее время замерзает всю коробку поворота, и она не восстанавливается.

Если вы хотите использовать Thread.sleep(int x), то я рекомендую вам сохранить текст, который вы используете в качестве строки, а затем обновите TextChangedFrame после обновления строки. Это позволяет приостановить операции, не приостанавливая TextChangedFrame.

PsuedoCode:

String oldString = "old string"; 
String newString = "new string"; 

// setup your dialog/popup here, with oldString 

Thread.sleep(500); 

// modify the dialog/popup here, changing oldString to newString 

и что следует избегать каких-либо проблем с замерзанием. (что я думаю, с вопросом и комментариями, ваша проблема).

Лучшим решением было бы использовать Swing Timers, как было упомянуто Hovercraft Full Of Eels в his comment

+0

Я попробую 'Swing таймеры'! Спасибо – DavidM