我想要有历史的命令窗口。我做了okAction
并将它绑在Ok
按钮上。发出命令时调用此命令。
如果命令成功,则从输入单元格中删除命令文本并添加到历史记录中。这是用 editable 制作的JComboBox
。
Ok
如果用户从历史记录中选择了某个命令,则与按下按钮时相同。所以我也将相同的动作绑定到组合框。
不幸的是,使用组合框进行操作也会导致调用动作。在下面的例子中,这是模拟命令失败,一个动作被调用了 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);
}
}