线程java上的关键事件

时间:2017-06-30 22:09:19

标签: java multithreading swing

我被要求向用户显示一个随机字符,并在显示字符时检查用户是否在消失之前键入它并显示另一个字符。 我能够做到这一点,但用于THREAD测试实际上并没有进行。 这是我的代码:

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

import javax.swing.*;

  public class MyThread extends Frame implements Runnable{
    String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private JLabel lbl;  
    JPanel contentPane;
    public Random rnd;

    public MyThread() {
        lbl = new JLabel("Hello world");
        contentPane = new JPanel(null);

        setFocusable(true);
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                if (KeyEvent.getKeyText(keyCode) == lbl.getText()) {
                    System.out.println("nice");
                }
                else
                    System.out.println("not");

                  repaint();             

            }

        });

        add(lbl);
        setSize(200,100);
        setLocation(300,300);


        rnd = new Random();
        setVisible(true);

    }  

    public void run() {

        try {
          while (true) {
            if (lbl.getText() == null)
              lbl.setText(Character.toString(abc.charAt(rnd.nextInt(26))));
            else
              lbl.setText(null);

            Thread.sleep(900);
          }
        }
        catch (InterruptedException ex) {
        }
      }



    public static void main(String []args){
        new Thread(new MyThread()).start();

    }
  }

问题是什么?我该如何解决? 谢谢..

1 个答案:

答案 0 :(得分:3)

您在该代码中遇到了几个问题:

  • 您不必要地将AWT(例如,Frame)与Swing混合
  • 您正在启动Swing事件线程的Swing GUI off
  • 您正在将KeyListener添加到Frame对象
  • 您的代码通过更改事件线程的Swing组件状态来违反Swing线程规则。
  • 您正在将字符串与==运算符进行比较,运算符是检查引用相等的运算符,这是您真正感兴趣的。字符串应该与.equals(...).equalsIgnoreCase(...)方法进行比较,这些方法检查功能相等 - 两个字符串以相同的顺序保持相同的字符,这是你想要什么。
  • 当更好的构造使用while (true)或" Swing Timer"时,您正在使用javax.swing.Timer循环。

e.g。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class MyGui extends JPanel {
    private static final char[] ABC = "ABCDEFGHIJKLMNOPQURSTUVWXYZ".toCharArray();
    private static final int PREF_W = 250;
    private static final int PREF_H = 150;
    private static final int TIMER_DELAY = 900;
    private JLabel label = new JLabel();
    private DefaultListModel<String> statusListModel = new DefaultListModel<>();
    private JList<String> statusList = new JList<>(statusListModel);

    public MyGui() {
        JPanel centerPanel = new JPanel(new GridBagLayout());
        centerPanel.add(label);
        setPreferredSize(new Dimension(PREF_W, PREF_H));

        statusList.setPrototypeCellValue("   GOOD   ");
        JScrollPane statusPane = new JScrollPane(statusList);
        statusPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        setLayout(new BorderLayout());
        add(centerPanel, BorderLayout.CENTER);
        add(statusPane, BorderLayout.LINE_END);

        new Timer(TIMER_DELAY, new TimerListener()).start();

        setFocusable(true);
        requestFocusInWindow();

        addKeyListener(new MyKeyListener());
    }

    private class MyKeyListener extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();
            String keyText = KeyEvent.getKeyText(keyCode).toUpperCase();
            if (keyText.equals(label.getText())) {
                statusListModel.addElement("good");
            } else {
                statusListModel.addElement("bad");
            }
            statusList.ensureIndexIsVisible(statusListModel.size() - 1);
        }
    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String text = label.getText();
            if (text.isEmpty()) {
                int randomIndex = (int) (ABC.length * Math.random());
                text = String.valueOf(ABC[randomIndex]);
                label.setText(text);
            } else {
                label.setText("");
            }
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("MyGui");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MyGui());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}