JFrame:在语句之间休眠

Posted

技术标签:

【中文标题】JFrame:在语句之间休眠【英文标题】:JFrame: Sleep between statements 【发布时间】:2015-04-17 06:03:39 【问题描述】:

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

我尝试了各种方法,例如 thread.sleep() 或 Timers,但我从来没有得到我想要的。

这是一个例子:

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 键时,我希望首先出现数字“1”,然后在 1000 毫秒后出现数字“2”,但它不会出现” !

有没有办法让程序在语句之间休眠而不是总是在函数的开头休眠?

提前致谢

【问题讨论】:

【参考方案1】:

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

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

 // SLEEP HERE

Thread.sleep(1000); 

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

addText(cmd, "2");

【讨论】:

【参考方案2】:

看起来您正试图让主要的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;
    

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

【讨论】:

【参考方案3】:

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

    您必须在 Swing 事件调度线程上完成所有 Swing 工作。 你真的,真的,不想让主 Swing 事件调度线程休眠!

您想要做的是创建一个帮助类来包装 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,则可以改用 Lambda,在这种情况下,LazyAction 将采用 Runnable 而不是实现 Runnable...)

【讨论】:

以上是关于JFrame:在语句之间休眠的主要内容,如果未能解决你的问题,请参考以下文章

在没有选择语句的情况下强制休眠插入

使用正则表达式语句在休眠中使用 createSQLQuery 获取计数(*)

Java多线程02

休眠和准备好的语句

休眠中索引和@NaturalId之间的区别

休眠 - 两个日期之间的差异