JFrame:语句之间的睡眠

时间:2015-02-16 16:46:58

标签: java multithreading swing sleep thread-sleep

我对编程世界还很陌生,并且最近注意到,每当我告诉程序在代码之间闲置一段时间时,它会在开始时休眠然后去通过剩下的代码。

我尝试了thread.sleep()或计时器等多种方式,但我从来没有得到我想要的东西。

以下是一个例子:

public void Console(){

        Console.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        Console.setSize(500, 500);
        Console.setLocationRelativeTo(null);
        Console.setResizable(false);
        Console.setVisible(true);
        Console.setTitle("Console");

        JPanel contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

        Console.setContentPane(contentPane);
        contentPane.setLayout(null);
        contentPane.setBackground(new Color(47, 79, 79));

        cinput.setBounds(10, 442, 353, 20);
        contentPane.add(cinput);

        cinput.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                in();

                cinput.requestFocus();

            }
        });

        cinput.setColumns(10);
        cinput.requestFocus();

        JButton Enter = new JButton("Enter");
        Enter.setBounds(373, 439, 111, 23);
        contentPane.add(Enter);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 10, 474, 421);
        contentPane.add(scrollPane);

        cmd.setEditable(false);
        cmd.setFont(new Font("Courier New", Font.PLAIN, 18));
        cmd.setForeground(Color.GREEN);
        cmd.setText("CONSOLE\n");
        cmd.setBackground(Color.BLACK);
        cmd.setLineWrap(true);
        cmd.setWrapStyleWord(true);


        scrollPane.setViewportView(cmd);

        Enter.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {

            in();

            cinput.requestFocus();
            }
        });

    }

    private void addText(JTextArea textArea, String text) {

        String input = textArea.getText();
        String output = input + text;

        textArea.setText(output);
    }

    private void in()
    {
        String input = cinput.getText();
        cinput.setText("");

        String text;

        text = input;

        addText(cmd, "> " + text + "\n");

        if(text.equals("start"))
        {
            addText(cmd, "1");

            // SLEEP HERE

            Thread.sleep(1000); 

           // -------------------

            addText(cmd, "2");


        }
        else if(text.equals("exit"))
        {   
            Console.dispose();
        }
    }

看起来应该是这样的:

enter image description here

在这个非常基本的“控制台”中,每当我在文本框中输入'start'并按Enter键时,我希望首先出现数字'1',然后在1000毫秒之后出现数字'2',它不会出现'吨!

有没有办法告诉程序在语句之间休眠而不是总是在函数的beginnig中休眠?

提前致谢

3 个答案:

答案 0 :(得分:4)

虽然从技术上讲上面的答案都是正确的,但问题是

  1. 您必须在Swing Event Dispatch Thread上完成所有Swing工作。
  2. 你真的,真的,不想睡觉主要的Swing Event Dispatch Thread!
  3. 你要做的是创建一个包装javax.swing.Timer(而不是java.util.timer)的帮助器类,它允许你在经过一定的毫秒数后在事件线程上轻松运行代码

    public abstract class LazyAction implements Runnable { 
    
        public LazyAction(int millis) {
            Timer t = new Timer(millis, new ActionListener() {
    
                            @Override
                            public void actionPerformed(ActionEvent e) {
                             try{
                                LazyAction.this.run();
                             catch(Exception e){
                                //Your error handling code
                             }
                            }
    
                        });
                        t.setRepeats(false);
                        t.start();
           }}
    

    现在,要使用此代码,您可以通过以下方式调用它:

      addText(cmd, "1");
      new LazyAction(300){
    
            @Override
            public void run() {
               addText(cmd, "2");
            }
      }
    

    (注意如果您使用的是Java 8,则可以使用Lambdas,在这种情况下,LazyAction将采用Runnable而不是实现Runnable ......)

答案 1 :(得分:1)

看起来你正试图让主Thread睡觉,这不是最好的主意。运行你自己的Thread并让它进入睡眠状态。

试试这个:

System.out.println(1);
SwingUtilities.invokeLater(() -> {
    new Timer(1000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(2);
        }
    }).start();
});

您也可以在不Thread.sleep()的情况下执行此操作:

long tick = 1000;
long startTime = System.currentTimeMillis();

while (true) {
    long now = System.currentTimeMillis();
    while (now - startTime > tick) {
        System.out.println("Seconds from start time: " + (int) (tick / 1000));
        tick += 1000;
    }
}

如果它适合您,只需根据您的需要调整上述示例(它还会考虑可能的延迟,因此秒数仍然是正确的。)

答案 2 :(得分:0)

在添加第一行文本之前放入一个sleep语句:

Thread.sleep(1000);
addText(cmd, "1");

 // SLEEP HERE

Thread.sleep(1000); 

// -------------------

addText(cmd, "2");