78092
Java Swingにて、Lights Outのゲームアプリを作成する課題を行っているのですが、  
ボタンを押下して左右上下の色を反転させるために、`ActionListener`を実装するクラスに引数を追加したところ、  
`JButton`を継承するクラスの「 **addActionListener(new LightsListener(this));**
」部分でコンパイルエラーが発生しました。

■エラー内容

> Exception in thread "main" java.lang.Error: Unresolved compilation problem:  
>  コンストラクター LightsListener(LightsButton) は未定義です
>
> at lightsOut.LightsButton.(LightsButton.java:17)  
>  at lightsOut.ButtonPanel.(ButtonPanel.java:22)  
>  at lightsOut.LightsOutJFrame.(LightsOutJFrame.java:33)  
>  at lightsOut.LightsOutJFrame.main(LightsOutJFrame.java:15)

引数が一致していないため発生していることは理解できているのですが、  
`JButton`を継承するクラスにどのようにして引数を追加したらよいのかわからず、詰まっています。  
お手数ですが、ご教示いただけますと幸いです。

■`JButton`を継承するクラス

```

    public class LightsButton extends JButton{
        
        /* buttonの初期値(今回は点灯なのでtrue) */
        private boolean buttonOn = true;
        
        /* JButtonの設定 */
        public LightsButton() {
            setBackground(Color.YELLOW);
            setPreferredSize(new Dimension(60, 60));
            addActionListener(new LightsListener(this));
            setEnabled(true);
        }
        
        /* on offの設定 */
        public void click() {
            if(buttonOn == true) {
                buttonOn = false;
                setBackground(Color.darkGray);
            }else {
                buttonOn = true;
                setBackground(Color.YELLOW);
            }
        }
    
    }
    
```

■`ActionListener`を実装するクラス

```

    public class LightsListener implements ActionListener{
        
        private LightsButton[][] buttonlist;
        private int x;
        private int y;
        
        /* 親buttonを呼び出し */
        public LightsListener(LightsButton button, LightsButton[][] buttonlist, int x, int y) {
            this.buttonlist = buttonlist;
            this.x = x;
            this.y = y;
        }
        
        /* 親button内のclickメソッドを呼び出し */
        @Override
        public void actionPerformed(ActionEvent e) {
            buttonlist[x][y].click();
            buttonlist[x + 1][y + 1].click();
        }
    
    }
    
```

■親パネルクラス

```

    public class ButtonPanel extends JPanel{
        
        LightsButton[][] button;
        
        /* Button */
        
        public ButtonPanel(){
            // buttonのレイアウト
            setLayout(new GridLayout(3,3));
            
            // buttonの設定(3 x 3)
            button = new LightsButton[3][3];
            for(int i = 0; i < button.length; i++) {
                for(int o = 0; o < button.length; o++) {
                    button[i][o] = new LightsButton();
                    add(button[i][o]);
                }
            }
        }
    
    }
    
```
CC BY-SA 4.0
2021-07-10T04:30:05.453
78088
2021-07-10T07:31:25.423
2021-07-10T07:29:45.417
15413
47246
question
java swing
ActionListenerを実装するクラスに引数を追加したら、JButtonを継承するクラスでコンパイルエラーになるのを解消したい。
`LightsListener`クラスの **コンストラクタ** に仮引数 (parameter) を追加したのであれば、それに対応する実引数
(argument) を渡してやればよいわけです。

`LightsButton`クラスの **コンストラクタ** 内で`LightsListener`の **コンストラクタ**
を呼び出しているので、`LightsButton`のコンストラクタ引数にも同じものを追加して転送します。

```

    // LightsButton.java
    
        public LightsButton(LightsButton[][] buttonlist, int x, int y) {
            setBackground(Color.YELLOW);
            setPreferredSize(new Dimension(60, 60));
            addActionListener(new LightsListener(this, buttonList, x, y));
            setEnabled(true);
        }
    
```

```

    // ButtonPanel.java
    public class ButtonPanel extends JPanel {
    
        private static final int NUM_ROWS = 3;
        private static final int NUM_COLS = 3;
    
        private final LightsButton[][] buttonList = new LightsButton[NUM_ROWS][NUM_COLS];
    
        public ButtonPanel() {
            setLayout(new GridLayout(NUM_ROWS, NUM_COLS));
    
            for (int x = 0; x < buttonList.length; ++x) {
                for (int y = 0; y < buttonList[x].length; ++y) {
                    buttonList[x][y] = new LightsButton(buttonList, x, y);
                    add(buttonList[x][y]);
                }
            }
        }
    }
    
```

ちなみに、「ボタンを押下して左右上下の色を反転させる」とのことですが、  
`LightsListener.actionPerformed()`メソッドの実装が間違っています。  
無条件に`buttonlist[x + 1][y +
1].click();`を実行すると、範囲外アクセスにより`ArrayIndexOutOfBoundsException`例外がスローされるケースがあります。

配列のインデックスは0以上かつ各次元の長さ未満である必要があります。  
あとは自分で考えてください。
CC BY-SA 4.0
2021-07-10T07:31:25.423
78092
2021-07-10T07:31:25.423
15413
78088
answer