java - 仅当 JFrame 中的某些内容发生更改时才使 JButton 可单击

标签 java swing jframe jbutton

我有一个带有 JTextFields、JComboBoxes 和 JLabel 的 JFrame。我想让按钮“UPDATE”只有在窗口中的某些内容已更改(字段)时才可单击。

最佳答案

I want to make the button "UPDATE" clickable only if something has been changed(fields) in the window.

您需要监听“字段”中的变化(无论它们应该是什么),并在该监听器中调用 setEnabled(true)setEnabled(false) 在您感兴趣的 JButton 上——或者在它的 Action 上更好,这取决于您的字段状态。为什么 Action 更好?您可以让多个按钮和 JMenuItems 共享相同的 Action,并且通过调用 Actions 上的方法,您可以同时禁用两者。

例如,如果字段是 JTextFields,则向您的字段添加一个 DocumentListener,并根据监听器中字段的状态,调用我上面提到的方法。

如果您需要更具体的帮助,那么您需要向我们提供更具体的信息和代码。


对于具有 5 个 JTextField 和一个 JButton 的示例,其中仅当文本出现在每个 JTextField 中时 JButton 才处于 Activity 状态:

package pkg;

import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

@SuppressWarnings("serial")
public class ButtonActiveTest extends JPanel {
    private static final int FIELD_COUNT = 5;

    private MyAction myAction = new MyAction("My Button"); // The Action
    private JButton myButton = new JButton(myAction);  // the button 
    private JTextField[] textFields = new JTextField[FIELD_COUNT];


    public ButtonActiveTest() {
        myAction.setEnabled(false); // initially disable button's Action

        // create single Doc listener
        MyDocumentListener myDocumentListener = new MyDocumentListener();
        // create jtext fields in a loop
        for (int i = 0; i < textFields.length; i++) {
            textFields[i] = new JTextField(5); // create each text field

            // add document listener to doc
            textFields[i].getDocument().addDocumentListener(myDocumentListener);

            // add to gui
            add(textFields[i]);
        }
        add(myButton);

    }

    private static void createAndShowGui() {
        ButtonActiveTest mainPanel = new ButtonActiveTest();

        JFrame frame = new JFrame("ButtonActiveTest");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }

    private class MyAction extends AbstractAction {
        public MyAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic); // to give button an alt-key hotkey
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(ButtonActiveTest.this, "Button Pressed");
        }
    }

    private class MyDocumentListener implements DocumentListener {

        @Override
        public void changedUpdate(DocumentEvent e) {
            checkFields();
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            checkFields();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            checkFields();
        }

        // if any changes to any document (any of the above methods called)
        // check if all JTextfields have text. If so, activate the action
        private void checkFields() {
            boolean allFieldsHaveText = true;
            for (JTextField jTextField : textFields) {
                if (jTextField.getText().trim().isEmpty()) {
                    allFieldsHaveText = false;
                }
            }

            myAction.setEnabled(allFieldsHaveText);
        }

    }
}

显示相似的代码,但现在有一个 JMenuItem 与 JButton 共享相同的 Action。请注意,菜单项和按钮同时处于 Activity/非 Activity 状态:

import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

@SuppressWarnings("serial")
public class ButtonActiveTest extends JPanel {
    private static final int FIELD_COUNT = 5;

    private MyAction myAction = new MyAction("Process Data in Fields"); // The Action
    private JButton myButton = new JButton(myAction);  // the button 
    private JTextField[] textFields = new JTextField[FIELD_COUNT];
    private JMenuBar menuBar = new JMenuBar();


    public ButtonActiveTest() {
        myAction.setEnabled(false); // initially disable button's Action

        // create single Doc listener
        MyDocumentListener myDocumentListener = new MyDocumentListener();
        // create jtext fields in a loop
        for (int i = 0; i < textFields.length; i++) {
            textFields[i] = new JTextField(5); // create each text field

            // add document listener to doc
            textFields[i].getDocument().addDocumentListener(myDocumentListener);

            // add to gui
            add(textFields[i]);
        }
        add(myButton);

        // create menu item with our action
        JMenuItem menuItem = new JMenuItem(myAction);
        JMenu menu = new JMenu("Menu");
        menu.setMnemonic(KeyEvent.VK_M);
        menu.add(menuItem);
        menuBar.add(menu);
    }

    public JMenuBar getMenuBar() {
        return menuBar;
    }

    private static void createAndShowGui() {
        ButtonActiveTest mainPanel = new ButtonActiveTest();

        JFrame frame = new JFrame("ButtonActiveTest");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.setJMenuBar(mainPanel.getMenuBar());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }

    private class MyAction extends AbstractAction {
        public MyAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic); // to give button an alt-key hotkey
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(ButtonActiveTest.this, "Action Performed!");
        }
    }

    private class MyDocumentListener implements DocumentListener {

        @Override
        public void changedUpdate(DocumentEvent e) {
            checkFields();
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            checkFields();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            checkFields();
        }

        // if any changes to any document (any of the above methods called)
        // check if all JTextfields have text. If so, activate the action
        private void checkFields() {
            boolean allFieldsHaveText = true;
            for (JTextField jTextField : textFields) {
                if (jTextField.getText().trim().isEmpty()) {
                    allFieldsHaveText = false;
                }
            }

            myAction.setEnabled(allFieldsHaveText);
        }

    }
}

关于java - 仅当 JFrame 中的某些内容发生更改时才使 JButton 可单击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31924400/

相关文章:

java - SpringBoot > 在运行时以编程方式添加 Jetty 服务器连接器端口?

java - 在多个服务器上查找相同的 EJB

java - hadoop : 1 map multiple reducers with each reducer having different functionality? 可能吗?

Java将文本放置到图像上不显示

java - JFrame颜色变化

Java抽象类和接口(interface)方法实现

java - Java中的paintComponent()没有被调用

java - 减少 JFrame 绘画中的延迟

java - 当我更改组件时,为什么必须在 JFrame 上使用 setvisible()?

java - 对除最后 2 行之外的 JTable 进行排序