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