0

長い投稿で申し訳ありませんが、私が伝えようとしていることを人々が理解する可能性が高くなるように、できるだけ詳しく説明したかったのです。

さて、この問題の概要は、レジをシミュレートするプログラムを作成しようとしているということです。(これは「楽しい」プロジェクトです)。私が設定した方法は次のとおりです。

CashRegister: プログラムを開始するメイン クラスで、すべてのメイン ウィンドウとして機能します。

public class CashRegister extends JFrame {
    ...
}

その他のクラス: メインの CashRegister ウィンドウのさまざまなコンポーネントを提供する JPanel として機能します。例:

public class NorthPanel extends JPanel {
    ...
}

次に、CashRegister クラスで:

add(new NorthPanel(), BorderLayout.NORTH);

基本的に、ユーザーが入力した価格の値を保持する priceField と呼ばれる NorthPanel クラスに JTextField があります。JPanel を拡張し、メイン ウィンドウの中央に数字キーパッドとして機能する別のクラス (キーパッド) があります。CashRegisterで:

add(new NorthPanel(), BorderLayout.NORTH);
add(new Keypad()); // (default for BorderLayout is CENTER)

私が遭遇した問題の 1 つは、相互に通信する必要がある各 JPanel クラス (NorthPanel とキーパッドなど) にコンポーネントがあるため、プログラム全体のリスナー クラスとして機能する 1 つのクラス EventHandler を作成したことです。 ; ユーザーがキーパッドのボタンを押すと、NorthPanel の価格フィールドはキーパッドのどのキーが押されたかを知る必要があります。

これらのコンポーネントが異なるクラスから来ているため、異なる方法で参照されているという事実が問題なのか、それとも何なのかはわかりません。すべてのクラスは同じディレクトリにあります。私は NetBeans を使用しており、すべて同じパッケージの一部です。

私の EventHandler クラスでは、さまざまなクラスから相互に通信する必要があるすべてのコンポーネントを渡すことができるように、いくつかの異なるコンストラクターを作成しました。例えば:

public class EventHandler implements ActionListener {
    private JTextField priceField;
    private JButton[][] keypad;

    public EventHandler(JTextField priceField) {
        this.priceField = priceField;
    }

    public EventHandler(JButton[][] keypad) {
        this.keypad = keypad;
    }
}

私の NorthPanel クラスでは、最初に priceField をインスタンス化し、構成 (フォントの設定など) して、次のように言います。

EventHandler e = new EventHandler(priceField);

priceField をリスナー クラスに渡そうとしました。

次に、キーパッド クラスで、次のように言います。

EventHandler e = new EventHandler(keypad);
for(int i = 0; i < 4; i++) {
    for(int j = 0; j < 3; j++) {
        keypad[i][j].addActionListener(e);
    }
}

次に、EventHandler クラスで、これらの変数を渡します。

public void actionPerformed(ActionEvent e) {
    for(int i = 0; i < 4; i++) {
        for(int j = 0; j < 3; j++) {
            if(keypad[i][j] == e.getSource()) {
                // call a custom method to append the numbers to the text field
            }
        }
    }
}

この時点で、NullPointerException が発生します。理由はわかりませんが、相互に通信する必要がある各クラスから異なるオブジェクトを渡す必要があるため、リスナーオブジェクトが異なるクラスから来ており、異なるコンストラクターを使用しているためだと思います。私は100%確かではありません。これを回避する方法はありますか、それとも完全に間違っていますか?

4

1 に答える 1

0

CashRegisterはアプリケーションのメイン フレームであるため ( JFrameを拡張します)、すべてのユーザー入力をCashRegisterに処理させる必要があります。サブパネルについては、オーバーライドする keyPressed メソッドの本体内で、フレームから呼び出されるaKeyWasPressed( int keyCode )などのメソッドを作成します。

また、JFrame をフォーカス可能に設定し、できれば他のパネルをフォーカス不可にします。setFocusable(false);

CashRegisterのサンプル コードを次に示します。

public class CashRegister extends JFrame implements KeyListener
{
    private NorthPanel northPanel;
    private Keypad keypad;

    public CashRegister ()
    {
        this.setFocusable(true);
        this.addKeyListener(this);
        northPanel = new NorthPanel();
        keypad = new Keypad();

        /* Your code ... */
    }

    @Override
    public void keyTyped(KeyEvent ke) 
    {
        /*Do nothing*/
    }

    @Override
    public void keyPressed(KeyEvent ke) 
    {
        northPanel.aKeyWasPressed( ke.getKeyCode() );
        keypad.aKeyWasPressed( ke.getKeyCode() );
    }

    @Override
    public void keyReleased(KeyEvent ke) 
    {
        /*Do nothing*/
    } 
}


注: パネルのaKeyWasPressedメソッド内でどのキーが押されたかを区別するには、次のようにします。

private void aKeyWasPressed(int code)
{
    if(code == KeyEvent.VK_A)
    {
        /*If its letter 'A', do this...*/
    }
}

繰り返しますが、これには多くの方法がありますが、フレーム自体にすべてのユーザー入力を処理させることが、ほとんどの場合、主に複数のパネルを扱う場合に最適な方法だと思います。

于 2013-09-04T04:57:04.297 に答える