3

履歴付きのコマンド ウィンドウが必要です。ボタンを作っ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);
    }
}
4

1 に答える 1

4

編集可能なコンボボックスがフォーカスを失うcontentsChangedと、イベントのメソッドがJComboBoxトリガーされ、がトリガーされactionPerformedますActionListener。次に、focusLost同じを再度呼び出しますactionPerformed

次に、ボタンを押すためのアクションが最終的にトリガーされます。

于 2012-09-28T19:00:03.303 に答える