ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-为什么动作执行3次?

2019-10-31 21:01:30  阅读:254  来源: 互联网

标签:jcombobox swing combobox action java


我想要具有历史记录的命令窗口.我做了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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有