有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带有线程的java DocumentListener。睡觉

我想知道我什么时候在写,什么时候在删除,但是,在0.5秒的延迟后,它会告诉我“你停止了写/删除”,但是,它只显示该消息,并且在半秒的延迟后删除或写入

如何正确使用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);
    }
}

共 (2) 个答案

  1. # 1 楼答案

    同样,使用摆动计时器来完成脏活。您要做的是,无论何时编辑或删除,都可以调用计时器上的“重新启动”来重新设置计时器并启动它。如果计时器正在运行,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();
             }
          });
       }
    }
    

    答案已编辑:无需重新创建计时器对象。只需对其调用restart(),因为如果当前计时器正在运行,它将停止当前计时器

  2. # 2 楼答案

    这个问题相当糟糕,也不是很清楚,所以在问题澄清之前,我无法给出确切的答案

    目前,您似乎正在使用Thread.sleep(500)造成500毫秒的延迟。在大多数程序中,这将起作用

    Thread.sleep(int x)暂停(或冻结,具体取决于您询问的人)当前操作x毫秒(在您的情况下为500毫秒)

    在您正在使用的应用程序中,您正在使用它来挂起文本中的更改。由于它的位置,它当前会冻结整个swing box,并且不会恢复

    如果必须使用Thread.sleep(int x),那么我建议您将正在使用的文本保存为字符串,然后在更新字符串后更新TextChangedFrame。这允许您挂起操作,而不挂起TextChangedFrame

    伪代码:

    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,如his comment中的Hovercraft Full Of Eels所述