在 JTextField 中插入值后,不会显示它们的随机值。我该如何解决?

After inserting values in JTextField, their random value is not shown. How can I fix it?

我写了这个 Java 应用程序,它用于在启动计数器后从输入到 JTextFields 中的值中提取随机值。编译并没有给出错误,但不显示 ("" +randomElement) 值。

我在启动计数器的 actionPerformed() 方法中的 TimerListener class 中创建了 randomElement 属性。在计数结束时,必须显示从四个 JTextField 中获取的随机值(正如您从下面的代码中看到的那样)。

你能告诉我我错在哪里吗?我该如何解决?

public class Merge extends JPanel {
    public static final int TIMER_DELAY = 1000;
    public static final String TEST_TEXT = "123456";
    public JTextField textField = new JTextField(16);
    public JButton button = new JButton(new ButtonAction());
    public Timer timer;
    JTextField t1Text = new JTextField();
    JTextField t2Text = new JTextField();
    JTextField t3Text = new JTextField();
    JTextField t4Text = new JTextField();
    JLabel f1Label = new JLabel("Filippo film 1");
    JLabel f2Label = new JLabel("Filippo film 2");
    JLabel l1Label = new JLabel("Laura film 1");
    JLabel l2Label = new JLabel("Laura film 2");

    public Merge() {
        add(button);
        add(textField);
    }

    public static void main(String[] args) {
        Merge me = new Merge();
        me.createAndShowGui();
    }

    public void createAndShowGui() {
        Merge mainPanel = new Merge();
        JFrame frame = new JFrame("Film roulette");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.setLayout(new GridLayout(11, 4));
        frame.pack();
        frame.setBounds(100, 10, 400, 400);
        frame.add(f1Label);
        frame.add(t1Text);
        frame.add(f2Label);
        frame.add(t2Text);
        frame.add(l1Label);
        frame.add(t3Text);
        frame.add(l2Label);
        frame.add(t4Text);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public class ButtonAction extends AbstractAction {

        public ButtonAction() {
            super("The movie you will see...");
            putValue(MNEMONIC_KEY, KeyEvent.VK_P);
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            if (timer != null && timer.isRunning()) {
                return;
            }
            textField.setText("");
            timer = new Timer(TIMER_DELAY, new TimerListener());
            timer.start();
        }
    }

    private class TimerListener implements ActionListener {
        private String text = "";
        private int counter = 0;

        @Override
        public void actionPerformed(ActionEvent e) {
            
            String filmFilippo1, filmFilippo2, filmLaura1, filmLaura2;

            filmFilippo1 = t1Text.getText();
            filmFilippo2 = t2Text.getText();
            filmLaura1 = t3Text.getText();
            filmLaura2 = t4Text.getText();

            List<String> givenList = Arrays.asList(filmFilippo1, filmFilippo2, filmLaura1, filmLaura2);
            Random rand = new Random();
            String randomElement = givenList.get(rand.nextInt(givenList.size()));
            
            text += TEST_TEXT.charAt(counter);
            textField.setText(text);
            counter++;
            if (counter >= TEST_TEXT.length()) {
                timer.stop();
                textField.setText("" +randomElement);
            }
        }
    }
}

要回答您的实际问题,它为空的原因是因为您在 createAndShowGui:

中这样做
Merge mainPanel = new Merge();
// ...
frame.getContentPane().add(mainPanel);

您创建了 Merge class 的新实例,然后将其添加到您在 main(string[] args):

中已经完成的 JFrame
public static void main(String[] args) {
    Merge me = new Merge();
    me.createAndShowGui();
}

所以现在您有 2 个 Merge class 实例,其中一个对用户不可见。您应该在 createAndShowGui:

中简单地执行此操作
frame.getContentPane().add(this);

然而

  1. 不要不必要地扩展 JPanel
  2. 通过 SwingUtilities.invokeLater
  3. 在EDT上创建所有Swing组件
  4. 使用 JFrame#setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 以便它完全退出应用程序,除非您只想处理?
  5. 仅在添加所有组件后调用JFrame#pack()
  6. 不要自己打电话给 setBounds 你正在使用 LayoutManager 留给那个吧!
  7. 无需调用JFrame#getContentPane()#add只需调用JFrame#add
  8. 您为计时器的每个刻度选择一个随机数,为什么不在计时器结束时选择一次呢?
  9. 您可能还想禁用您的 textField 这算作人们可以在那里输入并扰乱您的代码逻辑 哈哈
  10. 除非在不同的方法中需要,否则不要全局声明或初始化变量

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Merge {

    public static final int TIMER_DELAY = 1000;
    public static final String TEST_TEXT = "12345";
    private int counter = 1;
    private Random rand = new Random();
    private Timer timer;

    public Merge() {
        createAndShowGui();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Merge::new);
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame("Film roulette");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // create components
        JTextField textField = new JTextField(16);
        JButton button = new JButton("The movie you will see...");
        button.setMnemonic(KeyEvent.VK_P);
        JPanel mergePanel = new JPanel();
        JTextField t1Text = new JTextField();
        JTextField t2Text = new JTextField();
        JTextField t3Text = new JTextField();
        JTextField t4Text = new JTextField();
        JLabel f1Label = new JLabel("Filippo film 1");
        JLabel f2Label = new JLabel("Filippo film 2");
        JLabel l1Label = new JLabel("Laura film 1");
        JLabel l2Label = new JLabel("Laura film 2");

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (timer != null && timer.isRunning()) {
                    return;
                }

                // gather user input
                List<String> givenList = Arrays.asList(t1Text.getText(), t2Text.getText(), t3Text.getText(), t4Text.getText());

                // reset fields (if button is clicked more then once)
                textField.setText("");
                counter = 0;

                // start a timer
                timer = new Timer(TIMER_DELAY, (ActionEvent ev) -> {
                    if (counter >= TEST_TEXT.length()) {
                        ((Timer) ev.getSource()).stop();
                        String randomElement = givenList.get(rand.nextInt(givenList.size()));
                        textField.setText(randomElement);
                    } else {
                        textField.setText(textField.getText() + TEST_TEXT.charAt(counter));
                        counter++;
                    }
                });

                timer.start();
            }
        });

        // layout components
        mergePanel.add(button);
        mergePanel.add(textField);
        frame.add(mergePanel);
        frame.setLayout(new GridLayout(11, 4));
        frame.add(f1Label);
        frame.add(t1Text);
        frame.add(f2Label);
        frame.add(t2Text);
        frame.add(l1Label);
        frame.add(t3Text);
        frame.add(l2Label);
        frame.add(t4Text);
        frame.setLocationByPlatform(true);

        frame.pack();
        frame.setVisible(true);
    }
}