禁用后,JButtons会重新启用它们

时间:2010-04-14 19:26:53

标签: java user-interface swing awt

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

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

完整代码可用here

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

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

4 个答案:

答案 0 :(得分:3)

问题在于如何实例化框架(CashMachine),而不是(直接)实施框架。

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

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

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

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

答案 1 :(得分:1)

我想这段代码工作正常。

答案 2 :(得分:1)

程序混淆的一个可能原因是将数字键与控制键混合,ClearEnter。考虑使用单个侦听器单独处理数字键,如下面显示的NumberButton类所示。然后,您可以根据需要处理ClearEnter按钮。此外,使用List<NumberButton>可以更轻松地启用和禁用循环。

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);
            }
        });
    }
}

答案 3 :(得分:1)

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

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

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