私は今Swingクラスとそれに関するすべてを学んでいます。私はこのおもちゃプログラムを手に入れて、名前の入力を求め、「You've Enterd(Your Name)」というメッセージとともにJOptionPaneを提示します。使用する送信ボタンはクリックすることしかできませんが、Enterボタンでも機能するようにしたいと思います。使用しているJava本(Eventful Java、Bruce Danyluk、Murtagh)で推奨されているように、KeyListenerを追加しようとしました。
これは私のコードです:
import Java.awt.BorderLayout;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class NamePrompt extends JFrame{
private static final long serialVersionUID = 1L;
String name;
public NamePrompt(){
setLayout(new BorderLayout());
JLabel enterYourName = new JLabel("Enter Your Name Here:");
JTextField textBoxToEnterName = new JTextField(21);
JPanel panelTop = new JPanel();
panelTop.add(enterYourName);
panelTop.add(textBoxToEnterName);
JButton submit = new JButton("Submit");
submit.addActionListener(new SubmitButton(textBoxToEnterName));
submit.addKeyListener(new SubmitButton(textBoxToEnterName));
JPanel panelBottom = new JPanel();
panelBottom.add(submit);
//Add panelTop to JFrame
add(panelTop, BorderLayout.NORTH);
add(panelBottom, BorderLayout.SOUTH);
//JFrame set-up
setTitle("Name Prompt Program");
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
NamePrompt promptForName = new NamePrompt();
promptForName.setVisible(true);
}
}
そして、これはactionListener、keyListenerクラスです:
import Java.awt.Component;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import Java.awt.event.KeyEvent;
import Java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class SubmitButton implements ActionListener, KeyListener {
JTextField nameInput;
public SubmitButton(JTextField textfield){
nameInput = textfield;
}
@Override
public void actionPerformed(ActionEvent submitClicked) {
Component frame = new JFrame();
JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput.getText());
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("Hello");
}
Component frame = new JFrame();
JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput.getText());
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
}
}
これには簡単なトリックがあります。すべてのitボタンでフレームを構築したら、次の操作を行います。
frame.getRootPane().setDefaultButton(submitButton);
各フレームに対して、Enterキーを自動的にリッスンする既定のボタンを設定できます(おそらく、私が知らない他のイベントもあります)。そのフレームでEnterキーを押すと、ActionListenerのactionPerformed()
メソッドが呼び出されます。
私の知る限り、コードの問題は、キーを押すたびにダイアログがポップアップすることです。これは、if-bodyに入れていないためです。これに変更してみてください:
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("Hello");
JOptionPane.showMessageDialog(null , "You've Submitted the name " + nameInput.getText());
}
}
PDATE:あなたのコードの何が問題なのかがわかりました。キーリスナーをTextFieldの代わりにSubmitボタンに追加しています。コードをこれに変更します。
SubmitButton listener = new SubmitButton(textBoxToEnterName);
textBoxToEnterName.addActionListener(listener);
submit.addKeyListener(listener);
最上位のコンテナのルートペインを使用してデフォルトボタンを設定し、Enterに応答できるようにします。
SwingUtilities.getRootPane(submitButton).setDefaultButton(submitButton);
もちろん、これはボタンが有効なコンテナに追加されていることを前提としています;)
更新
これは、JRootPane#setDefaultButton
およびキーバインディングAPIを使用した基本的な例です
public class DefaultButton {
public static void main(String[] args) {
new DefaultButton();
}
public DefaultButton() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton button;
private JLabel label;
private int count;
public TestPane() {
label = new JLabel("Press the button");
button = new JButton("Press me");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
add(label, gbc);
gbc.gridy++;
add(button, gbc);
gbc.gridy++;
add(new JButton("No Action Here"), gbc);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doButtonPressed(e);
}
});
InputMap im = button.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
ActionMap am = button.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
am.put("spaced", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
doButtonPressed(e);
}
});
}
@Override
public void addNotify() {
super.addNotify();
SwingUtilities.getRootPane(button).setDefaultButton(button);
}
protected void doButtonPressed(ActionEvent evt) {
count++;
label.setText("Pressed " + count + " times");
}
}
}
もちろん、これは、フォーカスのあるコンポーネントが問題のキーイベントを消費しないことを前提としています(2番目のボタンが space または enter キー
ActionListenerクラスでは、簡単に追加できます
public void actionPerformed(ActionEvent event) {
if (event.getSource()==textField){
textButton.doClick();
}
else if (event.getSource()==textButton) {
//do something
}
}
switch(KEYEVENT.getKeyCode()){
case KeyEvent.VK_ENTER:
// I was trying to use case 13 from the ascii table.
//Krewn Generated method stub...
break;
}
これが最善の方法ではないことはわかっていますが、問題のボタン、イベント、キー、キー入力を右クリックします。これは簡単な方法ですが、どのキーにも反応します
フレームなしでこれは私のために働く:
JTextField tf = new JTextField(20);
tf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ENTER){
SwingUtilities.getWindowAncestor(e.getComponent()).dispose();
}
}
});
String[] options = {"Ok", "Cancel"};
int result = JOptionPane.showOptionDialog(
null, tf, "Enter your message",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,0);
message = tf.getText();