簡體   English   中英

JButton被禁用后會重新啟用自己

[英]JButtons re-enable themselves after being disabled

我有一個JButtons數組,它們組成一個鍵盤接口。 輸入六個數字后,我要禁用鍵盤,以便用戶無法輸入其他數字。

我已經編寫了代碼,並且按鈕一直處於禁用狀態,直到鼠標懸停在它們中的任何一個之上,然后這些按鈕似乎可以重新啟用自身並運行添加到其中的actionEvents。

完整代碼可在此處獲得

我認為可能是錯誤的事情。

  1. 當我設置button.setEnabled(false);時,會忽略某種MouseListener button.setEnabled(false);
  2. 我沒有將屬性與buildGUI();分開buildGUI(); 正確地,我還是這樣做,以便內部類可以訪問它們。
  3. 可能與gridLayout因為禁用按鈕似乎對我的services JPanel按鈕有效。

問題在於您如何實例化框架( CashMachine ),而不是(直接)實例化其實現。

您要兩次調用buildGUI ,一次在對象的構造函數中,然后在實例化該對象的Driver類中。 因此,要創建(和布局) 兩組按鈕。

當第一組按鈕最終被禁用時,您的鼠標活動顯示了第二組按鈕。 而且ActionListener實現中的缺陷可能導致inputCount值大於6,因此第二組按鈕最終不會像第一組按鈕那樣被禁用。

buildGUI應該是私有的; 應該在CashMachine構造函數中調用它,而不是在Driver類中調用它。

相反,我認為CashMachine.setVisible應該由Driver類而不是CashMachine構造函數CashMachine

我猜代碼很好用。

程序中可能引起混亂的一種原因是數字鍵與控制鍵“ Clear和“ Enter混用。 考慮使用單個偵聽器分別處理數字鍵,如下面所示的NumberButton類中所建議。 然后,您可以根據需要處理“ Clear和“ Enter按鈕。 另外,使用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);
            }
        });
    }
}

檢查類文件很有幫助! 問題出在Driver類中: buildGUI()方法被調用兩次:一次在CashMachine的構造函數中,一次在main方法中,之后調用構造函數。

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

這樣,您最終會得到兩倍數量的按鈕,即每個位置都有一對按鈕。 但是每個都只有一個被禁用。
只需從main (或從構造函數)中刪除對buildGUI的調用即可。
(我會將buildGUI更改為private,因為不應從類外部調用它。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM