使用 Jframe/textfields 打印数字

Printing numbers using Jframe/textfields

如何使用 Eclipse 中的 WindowBuilder 将 for 循环中的数字打印到文本字段中,我已经为计数器创建了 for 循环,以便在单击开始时开始(最多计数 60)。我只是想知道当我点击开始时,你如何让它显示在不同的文本字段中。 如果这个解释不是很清楚,换句话说,我正在制作一个秒表,当您单击开始时,它会在 eclipse 控制台中打印多达 60 个。当我单击开始时,我希望这些数字显示在 window 的 JTextfield 中。感谢任何帮助:)

这里是代码页面,希望大家(或姑娘)能帮帮我:)(这就是我尝试做的。

package com.racecar484.user;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingConstants;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.JTable;

public class StopWatch extends ForLoopTesting {

    private JFrame frmStopWatchPro;
    private JTextField txtClickMeTo;
    private JButton Terminate;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    StopWatch window = new StopWatch();
                    window.frmStopWatchPro.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public StopWatch() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     * @param i 
     */



    private void initialize(String i) {
        frmStopWatchPro = new JFrame();
        frmStopWatchPro.getContentPane().setBackground(new Color(255, 127, 80));
        frmStopWatchPro.setTitle("Stop Watch Pro");
        frmStopWatchPro.setBounds(100, 100, 450, 300);
        frmStopWatchPro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmStopWatchPro.getContentPane().setLayout(null);

        txtClickMeTo = new JTextField();
        for(int i1 = 0; i1 < 60; i1++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }

        txtClickMeTo.setText(i);
        txtClickMeTo.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {

            System.out.println("Oh my god this worked!");

            }
        });
        txtClickMeTo.setEditable(false);
        txtClickMeTo.setBounds(19, 24, 300, 58);
        frmStopWatchPro.getContentPane().add(txtClickMeTo);
        txtClickMeTo.setColumns(10);

        JButton btnNewButton = new JButton("Start");
        btnNewButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Stop-Watch activated.");
                for(int i = 0; i < 60; i++){
                    System.out.println(i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            }
        });
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            }
        });
        btnNewButton.setBounds(53, 121, 108, 40);
        frmStopWatchPro.getContentPane().add(btnNewButton);

        JButton btnStop = new JButton("Stop");
        btnStop.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
            String Meow = "hey";
                System.out.println("Stop-Watch stopped.");
            }
        });
        btnStop.setBounds(211, 121, 108, 40);
        frmStopWatchPro.getContentPane().add(btnStop);

        Terminate = new JButton("Terminate");
        Terminate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

            frmStopWatchPro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                System.out.println("Closing Application.");
            System.exit(0);
            }
        });
        Terminate.setBounds(329, 0, 105, 261);
        frmStopWatchPro.getContentPane().add(Terminate);

        JLabel lblonlyOneThat = new JLabel("(Only one that actually works without console ->)");
        lblonlyOneThat.setBounds(53, 211, 266, 39);
        frmStopWatchPro.getContentPane().add(lblonlyOneThat);

        JLabel lblStopWatchPro = new JLabel("Stop Watch Pro V.1- made by Andrew Lopez ");
        lblStopWatchPro.setBounds(53, 187, 257, 29);
        frmStopWatchPro.getContentPane().add(lblStopWatchPro);
    }
}

我认为您对 Java swing 框架的理解有些有限。你有两个主要问题。您已经在问题中描述了其中之一。另一个是你不会做定时器。

目前您正在使用 Thread.sleep(1000) 来输入 "wait" 1 秒。但是你把它放在 initialize 方法中。为什么 window 初始化时要等待 60 秒?这对我来说毫无意义。

我看到您在开始按钮的点击侦听器中还有另一个 Thread.sleep(1000)。这是有道理的,但你没有设置 txtClickMeTo 的文本。

应该是这样的:

for(int i = 0; i < 60; i++){
    System.out.println(i);
    try {
        Thread.sleep(1000);
        txtClickMeTo.setText(Integer.toString(i));
     } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

如果这样做,您还需要将 txtClickMeTo 标记为 final

final JTextField txtClickMeTo = new JTextField();

这样,开始按钮就可以正常工作了。

但是停止按钮呢?为什么当我启动定时器时它不起作用?

这是因为Thread.sleep导致阻塞。该方法阻止线程继续进行,因此只能在 60 秒后响应用户交互。

因此,Thread.sleep 不推荐用于秋千应用。您使用的是 javax.swing.Timer。它非常人性化。它提供了很多方便的方法供你用来实现你的停止按钮。

这是相关文档:https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

这里有一个教程: https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

编辑:

我将向您展示使用摆动计时器来满足要求的代码。

首先您需要创建一个(当然!)

Timer t = new Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // blah blah blah
    }
});

在此代码中,1000 表示计时器每 1000 毫秒或 1 秒触发一次。而第二个参数是定时器触发时需要执行的动作,在这种情况下,您应该将 txtClickMeTo 的文本设置为某个数字。

当然,您需要跟踪数字应该是多少,所以创建一个变量来存储它:

int secondsElapsed = 0;

你基本上只是将 JTextField 的文本设置为 secondsElasped 并递增它。

Swing 是单线程的,这意味着如果你做任何阻塞事件调度线程的事情,比如 运行 一个循环,使用 Thread.sleep 或其他一些长的 运行 进程, UI 不会更新(并且不会处理任何新事件)。

Swing 也不是线程安全的,这意味着你不应该从 EDT

以外的任何线程更新 UI

首先查看 Concurrency in Swing 了解更多详情。

那么问题来了,怎么解决呢?您可以使用 ThreadSwingUtilities.invokeLater,但这有点混乱。您可以使用 SwingWorker,但对于这个问题来说,这有点笨拙。最好的解决方案是使用 Swing Timer,它会定期从 EDT 中调用已注册的回调 (ActionListener),从而可以安全地从内部更新 UI。

查看 How to use Swing Timers 了解更多详情。

举个例子...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class StopWatch {

    public static void main(String[] args) {
        new StopWatch();
    }

    public StopWatch() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextField field;
        private Timer timer;
        private int counter;

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            field = new JTextField(4);
            add(field, gbc);

            JButton btn = new JButton("Start");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (timer.isRunning()) {
                        timer.stop();
                        btn.setText("Start");
                    } else {
                        counter = 0;
                        timer.start();
                        field.setText(Integer.toString(counter));
                        btn.setText("Stop");
                    }
                }
            });
            add(btn, gbc);

            timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    counter++;
                    if (counter >= 60) {
                        timer.stop();
                        btn.setText("Start");
                    }
                    field.setText(Integer.toString(counter));
                }
            });

        }

    }

}

注意事项: 这是一个简单的例子。 Swing Timer 只保证它会在规定的延迟后调用 ActionListener,这使得它稍微不准确(以毫秒为单位)。一个更 "appropriate" 的解决方案是比较 Timer 开始的时间和 ActionListener 被通知的时间

您可能还想查看 How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listeners 以获得更合适的按钮处理机制