java-为什么动作执行3次?
作者:互联网
我想要具有历史记录的命令窗口.我做了okAction并将其绑定到Ok按钮.发出命令时将调用此命令.
如果命令成功执行,则命令文本将从输入单元格中删除并添加到历史记录中.这是通过可编辑的JComboBox制成的.
如果用户从历史记录中选择了某些命令,则与按“确定”按钮时相同.因此,我也将相同的动作绑定到组合框.
不幸的是,使用组合框进行操作也会导致调用操作.在以下模拟命令失败的示例中,此操作称为3次.
为什么?
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
import javax.swing.border.*;
public class JCommandWindow extends JFrame {
private static final Random rnd = new Random();
private static final long serialVersionUID = 1L;
private AbstractAction okAction = new AbstractAction("Ok") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (issue((String) inputComboBox.getSelectedItem())) {
inputComboBox.setSelectedItem("");
} else {
inputComboBox.getEditor().selectAll();
}
}
};
private AbstractAction cancelAction = new AbstractAction("Cancel") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
close();
}
};
private JTextArea logTextArea = new JTextArea();
{
logTextArea.setWrapStyleWord(true);
logTextArea.setBorder(new EtchedBorder());
logTextArea.setEditable(false);
}
private JScrollPane logScrollPane = new JScrollPane(logTextArea);
{
logScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
logScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
}
private JPanel logPanel = new JPanel();
{
logPanel.setLayout(new BorderLayout());
logPanel.setBorder(new EmptyBorder(5, 5, 0, 5));
logPanel.add(logScrollPane, BorderLayout.CENTER);
}
private DefaultComboBoxModel historyModel = new DefaultComboBoxModel();
private JComboBox inputComboBox = new JComboBox();
{
inputComboBox.setModel(historyModel);
inputComboBox.setEditable(true);
inputComboBox.addActionListener(okAction);
}
private JPanel inputPanel = new JPanel();
{
inputPanel.setLayout(new BorderLayout());
inputPanel.setBorder(new EmptyBorder(5, 5, 5, 0));
inputPanel.add(inputComboBox, BorderLayout.CENTER);
}
private JButton okButton = new JButton(okAction);
private JButton cancelButton = new JButton(cancelAction);
private JPanel buttonPanel = new JPanel();
{
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
}
private JPanel bottomPanel = new JPanel();
{
bottomPanel.setLayout(new BorderLayout());
bottomPanel.add(inputPanel, BorderLayout.CENTER);
bottomPanel.add(buttonPanel, BorderLayout.EAST);
}
private final JRootPane rootPane = getRootPane();
{
rootPane.setLayout(new BorderLayout());
rootPane.add(logPanel, BorderLayout.CENTER);
rootPane.add(bottomPanel, BorderLayout.SOUTH);
rootPane.setDefaultButton(okButton);
rootPane.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
cancelAction.actionPerformed(null);
}
}
});
addWindowFocusListener(new WindowFocusListener() {
@Override
public void windowLostFocus(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowGainedFocus(WindowEvent e) {
inputComboBox.requestFocusInWindow();
}
});
}
public JCommandWindow() {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
public void close() {
WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
}
@Override
public void pack() {
super.pack();
// Get the size of the screen
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = dim.width * 2 / 3;
int h = dim.height * 2 / 3;
setSize(w, h);
int x = (dim.width - w) / 2;
int y = (dim.height - h) / 2;
// Move the window
setLocation(x, y);
}
public void addText(String text) {
logTextArea.append(text + "\n");
logTextArea.setCaretPosition(logTextArea.getDocument().getLength());
}
public void rememberCommand(String command) {
historyModel.addElement(command);
}
public boolean issue(String command) {
/*
if( rnd.nextBoolean() ) {
addText(command + " succeeded");
rememberCommand(command);
return true;
}
else {
addText(command + " failed");
return false;
}
*/
addText(command + " failed");
return false;
}
public static void main(String[] args) {
JCommandWindow commandWindow = new JCommandWindow();
commandWindow.pack();
commandWindow.setVisible(true);
}
}
解决方法:
当可编辑的组合框失去焦点时,将触发JComboBox事件的contentChanged方法,从而触发ActionListener的actionPerformed.然后,focusLost再次调用相同的actionPerformed.
然后,最终触发按钮按下动作.
标签:jcombobox,swing,combobox,action,java 来源: https://codeday.me/bug/20191031/1978756.html