java – 来自JFrame的JDialog,为什么我的监听器不能工作?

大约一周前,我开始研究选项类型的GUI.我从一个JFrame开始,并添加了相当多的功能与各种按钮和键监听器.我有这一切工作,并决定我希望窗口是模态的.我将JFrame转换为JDialog,虽然它仍然是非模态的,但所有功能仍然存在但是当我将其设置为模态(true或false)时,我失去了所有听众的功能.什么是错的?

我正在努力将我的SVN上传到GitHub.如果你需要查看代码只是评论这样说并给我几分钟.提前致谢.

package main;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.*;
import Twitter.SearchTweets;

public class OptionsGUI {

// auto generated
private static final long serialVersionUID = 1L;

private JDialog f;
private JPanel buttonPanel;
private JPanel optionsLabelPanel;
private JPanel optionsSetPanel;

private JLabel sortLocationLabel;
private JLabel timeoutLabel;
private JLabel maxTweetsLabel;
private JLabel keywordsLabel;   
private JLabel currentKeywordsLabel;

private JButton add;
private JButton remove;
private JButton save;
private JButton cancel; 

private JCheckBox sortLocationField;
private JTextField setTimeoutField;
private JTextField setMaxTweetsField;
private JTextField addKeywordField;
private JComboBox currentKeywordsField;

public OptionsGUI() {
    f = new JDialog(f, "Options");
    buttonPanel = new JPanel();
    optionsLabelPanel = new JPanel();
    optionsSetPanel = new JPanel();

    sortLocationLabel = new JLabel("Sort by location: ");
    sortLocationLabel.setHorizontalAlignment(JLabel.RIGHT);
    timeoutLabel = new JLabel("Timeout (in seconds): ");
    timeoutLabel.setHorizontalAlignment(JLabel.RIGHT);
    maxTweetsLabel = new JLabel("Maximum Tweets to show: ");
    maxTweetsLabel.setHorizontalAlignment(JLabel.RIGHT);
    keywordsLabel = new JLabel("Keyword to add: ");
    keywordsLabel.setHorizontalAlignment(JLabel.RIGHT);
    currentKeywordsLabel = new JLabel("Current keywords: ");
    currentKeywordsLabel.setHorizontalAlignment(JLabel.RIGHT);

    add = new JButton("Add Keyword");
    remove = new JButton("Remove Keyword");
    save = new JButton("Save");
    cancel = new JButton("Cancel");

    sortLocationField = new JCheckBox();
    setTimeoutField = new JTextField(10);
    setMaxTweetsField = new JTextField(10);
    addKeywordField = new JTextField(10);
    currentKeywordsField = new JComboBox();
    currentKeywordsField.setEditable(false);

    buttonPanel.setLayout(new GridLayout(2,2));
    buttonPanel.add(add);
    buttonPanel.add(remove);
    buttonPanel.add(save);
    buttonPanel.add(cancel);

    optionsLabelPanel.setLayout(new GridLayout(5,1));
    optionsLabelPanel.add(sortLocationLabel);
    optionsLabelPanel.add(timeoutLabel);
    optionsLabelPanel.add(maxTweetsLabel);
    optionsLabelPanel.add(keywordsLabel);
    optionsLabelPanel.add(currentKeywordsLabel);

    optionsSetPanel.setLayout(new GridLayout(5,1));
    optionsSetPanel.add(sortLocationField);
    optionsSetPanel.add(setTimeoutField);
    optionsSetPanel.add(setMaxTweetsField);
    optionsSetPanel.add(addKeywordField);
    optionsSetPanel.add(currentKeywordsField);

    sortLocationField.setSelected(BasicGUI.isSortedByLocation());
    setTimeoutField.setText("" + SearchTweets.getTimeout());
    setMaxTweetsField.setText("" + BasicGUI.getMaxTweets());
    if (SearchTweets.getKeywords().size() > 0) {
        for (String keyword: SearchTweets.getKeywords()) {
            currentKeywordsField.addItem(keyword);
        }
    }
    else
        currentKeywordsField.addItem("(none)");

    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
    f.getContentPane().add(optionsLabelPanel, BorderLayout.WEST);
    f.getContentPane().add(optionsSetPanel, BorderLayout.CENTER);
    f.setBounds(50, 50, 300, 235);
    f.setResizable(false);
    f.setAlwaysOnTop(true);
    f.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    f.setVisible(true);
    addKeywordField.requestFocus();


    add.addActionListener(new ButtonListener());
    addKeywordField.addKeyListener(new KeyChecker());
    remove.addActionListener(new ButtonListener());
    save.addActionListener(new ButtonListener());
    cancel.addActionListener(new ButtonListener());
}

public class ButtonListener implements ActionListener {

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == add) {
            String newKeyword  = addKeywordField.getText();
            if (newKeyword != null && newKeyword.length() > 0) {
                boolean duplicate = false;
                ArrayList<String> keywords = SearchTweets.getKeywords();
                for (int i = 0; i < keywords.size(); i++) {
                    if (keywords.get(i).equalsIgnoreCase(newKeyword)) {
                        duplicate = true;
                        break;
                    }
                }
                addKeywordField.transferFocus();
                if (duplicate ==  false) {
                    if (keywords.size() == 0)
                        currentKeywordsField.removeItem("(none)");
                    currentKeywordsField.addItem(addKeywordField.getText());
                    currentKeywordsField.setSelectedItem(addKeywordField.getText());
                }
                else {
                    JOptionPane.showMessageDialog(null, "Please enter a keyword that is not already in the list.", "Duplicate Keyword", JOptionPane.ERROR_MESSAGE);
                    f.toFront();
                    addKeywordField.requestFocus();
                    addKeywordField.setText("");
                }
            }
            else {
                JOptionPane.showMessageDialog(null, "Please enter a keyword before clicking \"Add\".", "Empty Field", JOptionPane.ERROR_MESSAGE);
                f.toFront();
                addKeywordField.requestFocus();
            }
            f.toFront();
            addKeywordField.requestFocus();
            addKeywordField.setText("");
        }

        else if (e.getSource() == remove) {
            if (currentKeywordsField.getSelectedItem() != null) {
                if (!(((String)currentKeywordsField.getSelectedItem()).equals("(none)"))) {
                    currentKeywordsField.removeItem(currentKeywordsField.getSelectedItem());
                    if (currentKeywordsField.getItemCount() == 0) {
                        currentKeywordsField.addItem("(none)");
                    }
                }
                else
                    JOptionPane.showMessageDialog(null, "No keywords have been entered yet.", "Empty List", JOptionPane.ERROR_MESSAGE);
                f.toFront();
            }
        }

        else if (e.getSource() == save) {

            boolean inputFail = false;
            //input checking try block
            try {

                int tempTimeout = Integer.parseInt(setTimeoutField.getText());
                if (tempTimeout < 0)
                    throw new Exception();

                int tempMaxTweets = Integer.parseInt(setMaxTweetsField.getText());
                if (tempMaxTweets < 0)
                    throw new Exception();

                BasicGUI.setSortedByLocation(sortLocationField.isSelected());
                SearchTweets.setTimeout(tempTimeout);
                BasicGUI.setMaxTweets(tempMaxTweets);

            } catch (NumberFormatException error) {
                inputFail = true;
                JOptionPane.showMessageDialog(null, "Please insure that Timeout and Maximum\nTweets are both integers.", "Invalid Input", JOptionPane.ERROR_MESSAGE);
                f.toFront();
            } catch (Exception error) {
                inputFail = true;
                JOptionPane.showMessageDialog(null, "Please be sure to enter a nonzero\ninteger for Timeout and Maximum Tweets.\n0 for either insures no timeout or a\nmaximum amount of tweets shown.", "Invalid Input", JOptionPane.ERROR_MESSAGE);
                if (Integer.parseInt(setTimeoutField.getText()) < 0) 
                    setTimeoutField.setText("" + SearchTweets.getTimeout());
                if ( Integer.parseInt(setMaxTweetsField.getText()) < 0)
                    setMaxTweetsField.setText("" + BasicGUI.getMaxTweets());
                f.toFront();
            } 

            if (inputFail == false) {
                SearchTweets.deleteKeywords();
                for (int i = 0; i < currentKeywordsField.getItemCount(); i++) {
                    SearchTweets.addKeyword((String)currentKeywordsField.getItemAt(i));
                }
                BasicGUI.setOptionsOpen(false);
                f.dispose();
            }
            BasicGUI.setSettingsPaneValues();
        }

        else if (e.getSource() == cancel) {
            BasicGUI.setOptionsOpen(false);
            f.dispose();
        }

        else {
            JOptionPane.showMessageDialog(null, "Error: Button not recognized");
        }

    }

}

public class KeyChecker implements KeyListener {
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                add.doClick();
        }
    }

    public void keyReleased(KeyEvent arg0) {
        //ignore
    }

    public void keyTyped(KeyEvent arg0) {
        //ignore
    }
}

public class ListenCloseWdw extends WindowAdapter{
    public void windowClosing(WindowEvent e){
        BasicGUI.setOptionsOpen(false);
        f.dispose();
    }
}
}

解决方法:

不要使用KeyListener.将ActionListener添加到文本字段,如下所示. Enter键已绑定到接受输入文本的Action.

另见How to Use ActionsHow to Use Key Bindings.

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

/** @see https://*.com/a/11085850/230513 */
public class EnterTest extends JPanel {

    public EnterTest() {
        super(new GridLayout(0, 1));
        final JButton add = new JButton(new AbstractAction("Add") {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Add");
            }
        });
        JTextField addKeywordField = new JTextField("Press enter.");
        addKeywordField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                add.doClick();
            }
        });
        this.add(addKeywordField);
        this.add(add);
    }

    private void display() {
        JFrame f = new JFrame("EnterTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new EnterTest().display();
            }
        });
    }
}
上一篇:java – JDialog在它的JFrame父级前面


下一篇:java – 在JTabbedPane标头中添加JLabel