仅当 JFrame 中的某些内容发生更改时才使 JButton 可单击
Make a JButton clickable only if something is changed in JFrame
我有一个带有 JTextFields、JComboBoxes 和 JLabel 的 JFrame。我想让按钮 "UPDATE" 仅在 window.
中的某些内容已更改(字段)时才可单击
I want to make the button "UPDATE" clickable only if something has been changed(fields) in the window.
您需要监听 "fields" 中的变化(无论它们应该是什么),并在您感兴趣的 JButton 上调用 setEnabled(true)
或 setEnabled(false)
-- 或更好的行动,取决于你的领域的状态。为什么 Action 更好?您可以让多个按钮和 JMenuItems 共享相同的 Action,并且通过调用 Actions 上的方法,您可以同时禁用两者。
例如,如果字段是 JTextFields,则向您的字段添加一个 DocumentListener,并根据侦听器中字段的状态,调用我上面提到的方法。
如果您需要更多具体帮助,那么您需要向我们提供更具体的信息和代码。
对于具有 5 个 JTextField 和一个 JButton 的示例,其中仅当文本出现在 every JTextField 中时 JButton 才处于活动状态:
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。注意菜单项和按钮都是active/inactive并列的:
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);
}
}
}
我有一个带有 JTextFields、JComboBoxes 和 JLabel 的 JFrame。我想让按钮 "UPDATE" 仅在 window.
中的某些内容已更改(字段)时才可单击I want to make the button "UPDATE" clickable only if something has been changed(fields) in the window.
您需要监听 "fields" 中的变化(无论它们应该是什么),并在您感兴趣的 JButton 上调用 setEnabled(true)
或 setEnabled(false)
-- 或更好的行动,取决于你的领域的状态。为什么 Action 更好?您可以让多个按钮和 JMenuItems 共享相同的 Action,并且通过调用 Actions 上的方法,您可以同时禁用两者。
例如,如果字段是 JTextFields,则向您的字段添加一个 DocumentListener,并根据侦听器中字段的状态,调用我上面提到的方法。
如果您需要更多具体帮助,那么您需要向我们提供更具体的信息和代码。
对于具有 5 个 JTextField 和一个 JButton 的示例,其中仅当文本出现在 every JTextField 中时 JButton 才处于活动状态:
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。注意菜单项和按钮都是active/inactive并列的:
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);
}
}
}