我不完全确定"模态"是否是我需要描述问题的正确术语,但我有一个带有JDialog的独立应用程序。JDialog 设置为阻止应用程序的所有其他部分,直到对话框关闭。我最近开始使用JPopupMenu添加一种自动建议功能。这在应用程序的其余部分工作正常,但是当尝试将其作为对话框的一部分时,我似乎无法单击弹出窗口,我认为这是因为对话框的模式排除类型。有谁知道解决这个问题的黑客?
用于启动 JDialog 的代码:
NewPlayerDialog dialog = new NewPlayerDialog();
dialog.setLocation(Main.getWindow().getLocation().x + Main.getWindow().getWidth()/2 - dialog.getWidth()/2, Main.getWindow().getLocation().y + Main.getWindow().getHeight()/2 - dialog.getHeight()/2);
dialog.setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
dialog.setResizable(false);
dialog.setVisible(true);
JDialog 中的代码:
package com.etan.bracketrunner2;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import com.etan.dbhs.DBHSDatabaseIntermediary;
import com.etan.dbhs.DBHSPlayerInitializer;
import com.etan.widgets.UnderlinedLabel;
@SuppressWarnings("serial")
public class NewPlayerDialog extends JDialog implements ActionListener, MouseListener {
private JTextField fnTextField;
private JPopupMenu fnPopup;
private ActionListener fnActionListener;
private JTextField lnTextField;
private JPopupMenu lnPopup;
private ActionListener lnActionListener;
private JTextField idTextField;
private JTextField handicapTextField;
private JButton okButton;
private JButton cancelButton;
/**
* Constructor
*/
public NewPlayerDialog() {
super(Main.getWindow(), "New Player", Dialog.ModalityType.TOOLKIT_MODAL);
Font font = new Font("Arial Black", Font.PLAIN, 14);
JLabel fnLabel = new UnderlinedLabel("First Name");
fnLabel.setForeground(Color.BLACK);
fnLabel.setFont(font);
JPanel fnLabelPanel = new JPanel();
fnLabelPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
fnLabelPanel.add(fnLabel);
JLabel lnLabel = new UnderlinedLabel("Last Name");
lnLabel.setForeground(Color.BLACK);
lnLabel.setFont(font);
JPanel lnLabelPanel = new JPanel();
lnLabelPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
lnLabelPanel.add(lnLabel);
JLabel idLabel = new UnderlinedLabel("ID#");
idLabel.setForeground(Color.BLACK);
idLabel.setFont(font);
JPanel idLabelPanel = new JPanel();
idLabelPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
idLabelPanel.add(idLabel);
JLabel handicapLabel = new UnderlinedLabel("Handicap");
handicapLabel.setForeground(Color.BLACK);
handicapLabel.setFont(font);
JPanel handicapLabelPanel = new JPanel();
handicapLabelPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
handicapLabelPanel.add(handicapLabel);
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new GridLayout(1, 4));
labelPanel.add(fnLabelPanel);
labelPanel.add(lnLabelPanel);
labelPanel.add(idLabelPanel);
labelPanel.add(handicapLabelPanel);
fnTextField = new JTextField(7);
fnTextField.setForeground(Color.BLACK);
fnTextField.setFont(font);
fnPopup = new JPopupMenu();
PopupMenuListener fnListener = new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
fnPopup.setLocation(fnTextField.getLocationOnScreen().x,
fnTextField.getLocationOnScreen().y + fnTextField.getHeight());
fnPopup.setPopupSize(fnTextField.getWidth(), fnPopup.getComponentCount() * 20);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
;
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
;
}
};
fnPopup.addPopupMenuListener(fnListener);
fnTextField.setComponentPopupMenu(fnPopup);
fnActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fnTextField.setText(e.getActionCommand());
fnPopup.setVisible(false);
}// ends actionPerformed()
};
FocusListener fnFocusListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
resetFirstNamePopup();
}
@Override
public void focusLost(FocusEvent e) {
fnPopup.setVisible(false);
}
};
KeyListener fnKeyListener = new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
;
}
@Override
public void keyPressed(KeyEvent e) {
;
}
@Override
public void keyReleased(KeyEvent e) {
resetFirstNamePopup();
}
};
fnTextField.addActionListener(fnActionListener);
fnTextField.addFocusListener(fnFocusListener);
fnTextField.addKeyListener(fnKeyListener);
lnTextField = new JTextField(7);
lnTextField.setForeground(Color.BLACK);
lnTextField.setFont(font);
lnPopup = new JPopupMenu();
PopupMenuListener lnListener = new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
lnPopup.setLocation(lnTextField.getLocationOnScreen().x,
lnTextField.getLocationOnScreen().y + lnTextField.getHeight());
lnPopup.setPopupSize(lnTextField.getWidth(), lnPopup.getComponentCount() * 20);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
;
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
;
}
};
lnPopup.addPopupMenuListener(lnListener);
lnTextField.setComponentPopupMenu(lnPopup);
lnActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
lnTextField.setText(e.getActionCommand());
lnPopup.setVisible(false);
}// ends actionPerformed()
};
FocusListener lnFocusListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
resetLastNamePopup();
}
@Override
public void focusLost(FocusEvent e) {
lnPopup.setVisible(false);
}
};
KeyListener lnKeyListener = new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
;
}
@Override
public void keyPressed(KeyEvent e) {
;
}
@Override
public void keyReleased(KeyEvent e) {
resetLastNamePopup();
}
};
lnTextField.addActionListener(lnActionListener);
lnTextField.addFocusListener(lnFocusListener);
lnTextField.addKeyListener(lnKeyListener);
idTextField = new JTextField(3);
idTextField.setForeground(Color.BLACK);
idTextField.setFont(font);
handicapTextField = new JTextField(3);
handicapTextField.setForeground(Color.BLACK);
handicapTextField.setFont(font);
JPanel fnTextFieldPanel = new JPanel();
fnTextFieldPanel.add(fnTextField);
JPanel lnTextFieldPanel = new JPanel();
lnTextFieldPanel.add(lnTextField);
JPanel idTextFieldPanel = new JPanel();
idTextFieldPanel.add(idTextField);
JPanel handicapTextFieldPanel = new JPanel();
handicapTextFieldPanel.add(handicapTextField);
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new GridLayout(1, 4));
infoPanel.add(fnTextFieldPanel);
infoPanel.add(lnTextFieldPanel);
infoPanel.add(idTextFieldPanel);
infoPanel.add(handicapTextFieldPanel);
okButton = new JButton("OK");
okButton.setForeground(Color.BLACK);
okButton.setFont(font);
okButton.addActionListener(this);
cancelButton = new JButton("Cancel");
cancelButton.setForeground(Color.BLACK);
cancelButton.setFont(font);
cancelButton.addActionListener(this);
JPanel buttonPanel = new JPanel();
buttonPanel.setBorder(BorderFactory.createMatteBorder(4, 0, 0, 0, new Color(160, 0, 0)));
buttonPanel.setLayout(new GridLayout(1, 2));
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
JPanel content = new JPanel();
content.setBorder(BorderFactory.createLineBorder(new Color(160, 0, 0), 4));
content.setLayout(new BorderLayout());
content.add(labelPanel, BorderLayout.NORTH);
content.add(infoPanel, BorderLayout.CENTER);
content.add(buttonPanel, BorderLayout.SOUTH);
setPreferredSize(new Dimension(500, 200));
setContentPane(content);
pack();
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}// ends NewPlayerDialog()
@Override
public void actionPerformed(ActionEvent evt) {
if(evt.getSource().equals(okButton)) {
if(checkInfo()) {
DBHSPlayerInitializer init = new DBHSPlayerInitializer();
int id = 0;
float handicap = 0;
try {
if(!idTextField.getText().equals("")) {
id = Integer.parseInt(idTextField.getText());
}
}
catch(NumberFormatException e) {
Main.getControlPanel().showErrorMessage(
"Please make sure that all inputs under ID# are integer numbers.");
}
try {
if(!handicapTextField.getText().equals("")) {
handicap = Float.parseFloat(handicapTextField.getText());
}
}
catch(NumberFormatException e) {
Main.getControlPanel().showErrorMessage(
"Please make sure that all inputs under handicap are number values.");
}
Player player;
try {
player = init.initialize(fnTextField.getText(),
lnTextField.getText(), id, handicap, 0);
Main.getControlPanel().getScreen().getPlayers().addPlayer(player);
Main.getControlPanel().showPrizesDialog();
} catch (Exception e) {
Main.getControlPanel().showErrorMessage("There was an error while trying to add the new player.");
e.printStackTrace();
}
}
dispose();
Main.getControlPanel().updateInfo();
} else if(evt.getSource().equals(cancelButton)) {
dispose();
}
}// ends actionPerformed()
boolean checkInfo() {
String fn = fnTextField.getText();
String ln = lnTextField.getText();
String id = idTextField.getText();
String handicap = handicapTextField.getText();
if(id.equals("") && (fn.equals("") && ln.equals(""))) {
Main.getControlPanel().showErrorMessage("Please make sure that all players have either their first and last names, or their id number filled in.");
return false;
}
if(fn.equals("") && ln.equals("")) {
try{
Integer.parseInt(id);
}
catch(NumberFormatException e) {
if(!fn.equals("") && !ln.equals("")) {
Main.getControlPanel().showErrorMessage("Please make sure that " + fn + " " + ln + "'s ID is an integer number.");
} else {
Main.getControlPanel().showErrorMessage("Please make sure that each player's ID is an integer number.");
}
return false;
}
}
if(!handicap.equals("")) {
try{
Float.parseFloat(handicap);
}
catch(NumberFormatException e) {
Main.getControlPanel().showErrorMessage("Please make sure that " + fn + " " + ln + "'s handicap is numeric.");
return false;
}
}
return true;
}// ends checkInfo()
/**
* Used for an anonymous ActionListener in the
* PlayerPanel.
*
* @return cancelButton
*/
JButton getCancelButton() {
return cancelButton;
}// ends getCancelButton()
/**
* Used for an anonymous ActionListener in the
* PlayerPanel.
*
* @return okButton
*/
JButton getOkButton() {
return okButton;
}// ends getOkButton()
@Override
public void mouseClicked(MouseEvent evt) {
;
}// ends mouseClicked()
@Override
public void mouseEntered(MouseEvent evt) {
if(evt.getComponent().getClass().getName().equals("javax.swing.JMenuItem")) {
evt.getComponent().setBackground(new Color(120,145,170));
}
}// ends mouseEntered()
@Override
public void mouseExited(MouseEvent evt) {
if(evt.getComponent().getClass().getName().equals("javax.swing.JMenuItem")) {
evt.getComponent().setBackground(new Color(238,238,238));
}
}// ends mouseExited()
@Override
public void mousePressed(MouseEvent evt) {
;
}// ends mousePressed()
@Override
public void mouseReleased(MouseEvent evt) {
;
}// ends mouseReleased()
/**
* Repopulates fnPopup if necessary.
*/
private void resetFirstNamePopup() {
fnPopup.setVisible(false);
fnPopup.removeAll();
if(!(fnTextField.getText().equals("") && lnTextField.getText().equals(""))) {
JMenuItem item = null;
String[] names = DBHSDatabaseIntermediary.getFirstNames(fnTextField.getText(), lnTextField.getText());
for(int i=0; i < names.length; i++) {
item = new JMenuItem(names[i]);
item.addActionListener(fnActionListener);
item.addMouseListener(NewPlayerDialog.this);
fnPopup.add(item);
}
if(names.length > 0 && !names[0].equals("")) {
fnPopup.setVisible(true);
}
fnPopup.grabFocus();
}
}// ends resetFirstNamePopup()
/**
* Repopulates lnPopup if necessary.
*/
private void resetLastNamePopup() {
lnPopup.setVisible(false);
lnPopup.removeAll();
if(!(fnTextField.getText().equals("") && lnTextField.getText().equals(""))) {
JMenuItem item = null;
String[] names = DBHSDatabaseIntermediary.getLastNames(fnTextField.getText(), lnTextField.getText());
for(int i=0; i < names.length; i++) {
item = new JMenuItem(names[i]);
item.addActionListener(lnActionListener);
item.addMouseListener(NewPlayerDialog.this);
lnPopup.add(item);
}
if(names.length > 0 && !names[0].equals("")) {
lnPopup.setVisible(true);
}
lnPopup.grabFocus();
}
}// ends resetLastNamePopup()
}// ends Class
我将对话框上的模态类型更改为DOCUMENT_MODAL,一切正常。