一位朋友最近要求我制作一个简单的 Buzzer 程序,并在我为他编写的内容中发现了一个奇怪的“错误”。
如果按下一个键并且蜂鸣器在几秒钟内快速复位,他会观察到在复位后的第一次按键和“蜂鸣”指示之间发生的 2 到 3 秒的程序冻结。他有以下 Java 安装:
build 1.7.0_25-b16
但是,我在我的计算机上没有遇到这个问题,安装了以下 Java:
$ java -version
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-10M4509)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)
解冻后,程序会返回相应的键(即,不是最后按下的键,而是在重置之后和冻结之前按下的第一个键)。这表明问题不在于听者,而在于听者的反应。
关于可能导致这种现象的任何想法?在此先感谢您的帮助。
源代码:
/**
* Buzzer.java
*
* Buzzer
*/
package org.lexingtonma.lhs.nhb;
import java.awt.Color;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* @author Arman D. Bilge
*
*/
public class Buzzer extends JFrame implements KeyListener {
private static final long serialVersionUID = 7492374642744742658L;
private static final String BUZZ_A = "BuzzA.wav";
private static final String BUZZ_B = "BuzzB.wav";
private Clip buzz = null;
private boolean listening = true;
private final JTextField display = new JTextField(3);
private final JButton reset = new JButton("Reset");
{
DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventDispatcher(new KeyEventDispatcher() {
public boolean dispatchKeyEvent(KeyEvent e) {
keyTyped(e);
return false;
}
});
setTitle("Buzzer");
final JPanel panel = new JPanel();
setSize(256, 162);
setDefaultCloseOperation(EXIT_ON_CLOSE);
display.setFont(new Font("Helvetica", Font.BOLD, 64));
display.setForeground(Color.WHITE);
display.setVisible(true);
display.setEditable(false);
display.setHorizontalAlignment(JTextField.CENTER);
panel.add(display);
reset.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
display.setText("");
display.setBackground(Color.WHITE);
listening = true;
reset.setEnabled(false);
}
});
reset.setEnabled(false);
panel.add(reset);
add(panel);
try {
buzz = AudioSystem.getClip();
} catch (LineUnavailableException e) {
JOptionPane.showMessageDialog(this, e.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
}
}
public static final void main(String args[]) {
Buzzer b = new Buzzer();
b.setVisible(true);
}
public void keyPressed(KeyEvent e) {
// Do nothing
}
public void keyReleased(KeyEvent e) {
// Do nothing
}
public void keyTyped(KeyEvent e) {
final char c = e.getKeyChar();
if (listening && Character.isLetterOrDigit(c)) {
buzz.close();
listening = false;
if (Character.isDigit(c)) {
display.setBackground(Color.RED);
try {
buzz.open(AudioSystem.getAudioInputStream(getClass().getResource(BUZZ_A)));
buzz.start();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
} else {
display.setBackground(Color.BLUE);
try {
buzz.open(AudioSystem.getAudioInputStream(getClass().getResource(BUZZ_B)));
buzz.start();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
display.setText("" + c);
reset.setEnabled(true);
}
}
}