JDialog from JFrame, why won't my listeners work?
java, jdialog, keylistener, swing, twitter
Solution
Don't use `KeyListener` for this. Add an `ActionListener` to your text field as shown below. The Enter key is already bound to an `Action` that accepts the text entered.
See also How to Use Actions and How 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 http://stackoverflow.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();
}
});
}
}
Problem
About a week ago I started working on an options type GUI. I started with a JFrame and added quite a bit of functionality with various button and key listeners. I had all this working and decided I wanted the window to be modal. I converted the JFrame to a JDialog, and while it is still NOT modal, all the functionality is still there but when I set it to be modal (true OR false) I lose all functionality of my listeners. Any idea on what is wrong? I am working to upload my SVN to GitHub. If you need to see the code just comment saying so and give me a few minutes. Thanks in advance. ``` 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(); } } } ```