JButtons 在被禁用后重新启用

发布于 2024-08-28 21:33:56 字数 563 浏览 11 评论 0原文

我有一个 JButton 数组,它们形成了键盘界面。输入六个数字后,我想禁用键盘,以便用户无法输入更多数字。

我已经编写了代码,并且按钮会禁用,直到鼠标悬停在其中任何一个按钮上方,然后按钮似乎会重新启用自身并运行添加到其中的 actionEvents。

完整代码可在此处获取。

我认为可能是错误的事情。

  1. 当我设置 button.setEnabled(false); 时,有某种 MouseListener 被忽略,
  2. 我没有正确地将属性与 buildGUI(); 分开,我只是这样做了无论如何,这样内部类就可以访问它们。
  3. 可能与gridLayout有关,因为禁用按钮似乎适用于我的services JPanel按钮。

I have an array of JButtons which form a keypad interface. After six numbers are entered I want to disable the keypad so that no further numbers can be entered by the user.

I have written the code and the buttons do disable until the mouse hovers above any of them, then the buttons seem to re-enable themselves and run actionEvents added to them.

The full code is available here.

Possible things that I think are wrong.

  1. There is some sort of MouseListener which is ignoring when I set button.setEnabled(false);
  2. I haven't separated attributes from the buildGUI(); correctly, I only did this anyway so that the inner class could access them.
  3. Possibly something to do with the gridLayout as disabling the buttons seems to work for my services JPanel buttons.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

治碍 2024-09-04 21:33:56

问题在于您如何实例化您的框架 (CashMachine),而不是(直接)及其实现。

您将调用 buildGUI 两次,一次在对象的构造函数中,然后在实例化该对象的 Driver 类中。因此,您将创建(并布置)两组按钮。

当第一组按钮最终被禁用时,您的鼠标活动会显示第二组按钮。 ActionListener 实现中的缺陷可能会导致 inputCount 的值大于 6,因此第二组中的按钮最终不会像第一组中的按钮那样被禁用。

buildGUI 应该是私有的;它应该在 CashMachine 构造函数中调用,而不是由您的 Driver 类调用。

相反,在我看来,CashMachine.setVisible 应该由 Driver 类调用,而不是由 CashMachine 构造函数调用。

The problem lies in how you instantiated your Frame (CashMachine), not (directly) with its implementation.

You are calling buildGUI twice, one in the object's constructor, and then in the Driver class that instantiates the object. As a result, you are creating (and laying out) two sets of buttons.

When the buttons of the first set were eventually disabled, your mousing activity was revealing the second set of buttons. And a flaw in your ActionListener implementation can cause inputCount to take on values greater than 6, so buttons in the second set were not eventually disabled like those from the first set.

buildGUI should be private; it should be called in the CashMachine constructor, and not by your Driver class.

Conversely, in my opinion, CashMachine.setVisible should be called by the Driver class, and not by the CashMachine constructor.

呆头 2024-09-04 21:33:56

我猜代码工作得很好。

The code works just fine I guess.

拥抱我好吗 2024-09-04 21:33:56

程序中可能造成混乱的一个原因是将数字键与控制键、ClearEnter 混用。考虑使用单个侦听器单独处理数字键,如下面所示的 NumberButton 类中的建议。然后您可以根据需要处理 ClearEnter 按钮。此外,使用 List 使启用和禁用循环变得更容易。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class KeyPadPanel extends JPanel implements ActionListener {

    private static final int MAX = 6;
    private final List<NumberButton> numbers = new ArrayList<NumberButton>();
    private final JTextArea text = new JTextArea(1, MAX);
    private final JButton clear = new JButton("Clear");
    private final JButton enter = new JButton("Enter");

    public KeyPadPanel() {
        super(new BorderLayout());

        JPanel display = new JPanel();
        text.setEditable(false);
        display.add(text);
        this.add(display, BorderLayout.NORTH);

        JPanel pad = new JPanel(new GridLayout(4, 4));
        for (int i = 0; i < 10; i++) {
            NumberButton n = new NumberButton(i);
            numbers.add(n);
            if (i > 0) {
                pad.add(n);
            }
        }
        pad.add(clear);
        pad.add(numbers.get(0));
        pad.add(enter);
        clear.addActionListener(this);
        enter.addActionListener(this);
        this.add(pad, BorderLayout.CENTER);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        text.setText("");
        enableButtons();
    }

    private void enableButtons() {
        for (NumberButton n : numbers) {
            n.setEnabled(true);
        }
    }

    private void disableButtons() {
        for (NumberButton n : numbers) {
            n.setEnabled(false);
        }
    }

    private class NumberButton extends JButton implements ActionListener {

        public NumberButton(int number) {
            super(String.valueOf(number));
            this.addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            NumberButton b = (NumberButton) e.getSource();
            if (text.getText().length() < MAX) {
                text.append(b.getText());
            }
            if (text.getText().length() == MAX) {
                disableButtons();
            }
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new KeyPadPanel());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

One possible source of confusion in your program is mixing number keys with control keys, Clear and Enter. Consider handling number keys separately with a single listener, as suggested in the NumberButton class shown below. Then you can handle the Clear and Enter buttons as desired. Also, using a List<NumberButton> makes the enable and disable loops easier.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class KeyPadPanel extends JPanel implements ActionListener {

    private static final int MAX = 6;
    private final List<NumberButton> numbers = new ArrayList<NumberButton>();
    private final JTextArea text = new JTextArea(1, MAX);
    private final JButton clear = new JButton("Clear");
    private final JButton enter = new JButton("Enter");

    public KeyPadPanel() {
        super(new BorderLayout());

        JPanel display = new JPanel();
        text.setEditable(false);
        display.add(text);
        this.add(display, BorderLayout.NORTH);

        JPanel pad = new JPanel(new GridLayout(4, 4));
        for (int i = 0; i < 10; i++) {
            NumberButton n = new NumberButton(i);
            numbers.add(n);
            if (i > 0) {
                pad.add(n);
            }
        }
        pad.add(clear);
        pad.add(numbers.get(0));
        pad.add(enter);
        clear.addActionListener(this);
        enter.addActionListener(this);
        this.add(pad, BorderLayout.CENTER);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        text.setText("");
        enableButtons();
    }

    private void enableButtons() {
        for (NumberButton n : numbers) {
            n.setEnabled(true);
        }
    }

    private void disableButtons() {
        for (NumberButton n : numbers) {
            n.setEnabled(false);
        }
    }

    private class NumberButton extends JButton implements ActionListener {

        public NumberButton(int number) {
            super(String.valueOf(number));
            this.addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            NumberButton b = (NumberButton) e.getSource();
            if (text.getText().length() < MAX) {
                text.append(b.getText());
            }
            if (text.getText().length() == MAX) {
                disableButtons();
            }
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new KeyPadPanel());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}
你是我的挚爱i 2024-09-04 21:33:56

检查类文件很有帮助!问题出在 Driver 类中:
buildGUI() 方法被调用两次:一次在 CashMachine 的构造函数中,第二次在调用构造函数后的 main 方法中。

public static void main(String args[])
{
    CashMachine cashmachine = new CashMachine();
    cashmachine.buildGUI();
}

这样,您最终会得到双倍数量的按钮,即每个位置有一对按钮。但其中只有一个被禁用。
只需从 main(或从构造函数)中删除对 buildGUI 的调用即可。
(我会将 buildGUI 更改为私有,因为它不应该从类外部调用......)

Examining the class files was helpful! The problem is in the Driver class:
the buildGUI() method is being called 2 times: once in the constructor of CashMachine and second in the main method after calling the constructor.

public static void main(String args[])
{
    CashMachine cashmachine = new CashMachine();
    cashmachine.buildGUI();
}

This way you end up with the double number of buttons, that is, a pair of buttons at each position. But only one of each is being disabled.
Just remove the call to buildGUI from main (or from the constructor).
(I would change buildGUI to private as it should not be called from outside the class...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文