繁体   English   中英

使用Jframe /文本字段打印数字

[英]Printing numbers using Jframe/textfields

如何在eclipse中使用WindowBuilder将for循环中的数字打印到文本字段中,我已经创建了for循环以使计数器在单击开始时开始计数(最多60个)。 我只是想知道当我单击“开始”时,如何使它显示在不同的文本字段中。 如果说不清楚,换句话说,我正在做秒表,当您单击开始时,它将在eclipse控制台中最多显示60。 当我单击开始时,我希望这些数字显示在窗口的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)进行1秒钟的“等待”。 但是您将其放在initialize方法中。 为什么在窗口初始化时要等待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秒后响应用户交互。

因此,不建议在swing应用程序中使用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

首先查看Swing中的并发以获取更多详细信息。

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

有关更多详细信息,请参阅如何使用Swing计时器

再举个例子

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));
                }
            });

        }

    }

}

Cavet:这是一个简单的示例。 Swing Timer仅保证在指定的延迟后将调用ActionListener ,这会使它稍微不准确(以毫秒为单位)。 一个更“合适”的解决方案是在Timer启动时间和通知ActionListener时间之间进行比较。

您可能还想看看如何使用按钮,复选框和单选按钮以及如何编写动作侦听器,以获得使用按钮的更合适的机制

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM