1. ホーム
  2. java

[解決済み] Javaです。ローカル変数miを内包するスコープで定義する場合は、finalまたはeffective finalである必要があります。

2022-02-26 12:17:50

質問

件名のようなエラーが発生しましたので、修復方法を教えてください。 ERRORはmenuItem-loopで、textAreaの前景色をmenuItemから選んだ色に設定しようとしているところです。(色[mi])

    String[] colors = {
            "blue", 
            "yellow",
            "orange",
            "red", 
            "white", 
            "black", 
            "green", 
            };

JMenu mnForeground = new JMenu("Foreground");
            for (int mi=0; mi<colors.length; mi++){
                String pos = Character.toUpperCase(colors[mi].charAt(0)) + colors[mi].substring(1);
                JMenuItem Jmi =new JMenuItem(pos);
                Jmi.setIcon(new IconA(colors[mi]));

                Jmi.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JMenuItem item = (JMenuItem) e.getSource();
                        IconA icon = (IconA) item.getIcon();
                        Color kolorIkony = getColour(colors[mi]); // ERROR HERE: (colors[mi])
                        textArea.setForeground(kolorIkony);
                    }
                });

                mnForeground.add(Jmi);
            }

public Color getColour(String colour){
  try {
      kolor = Color.decode(colour);
  } catch (Exception e) {
      kolor = null; 
  }
  try {
        final Field f = Color.class.getField(colour);
        kolor = (Color) f.get(null);
      } catch (Exception ce) {
        kolor = Color.black;
      }
return kolor;
}

解決方法は?

このエラーの意味は を使用することはできません。 mi 内部クラス .


インナークラス内で変数を使用するには、変数を宣言する必要があります。 final . このように mi はループのカウンタであり final 変数は代入できないので、回避策を作成して mi の値を final 変数にアクセスすることができます。

final Integer innerMi = new Integer(mi);

ですから、コードはこのようになります。

for (int mi=0; mi<colors.length; mi++){

    String pos = Character.toUpperCase(colors[mi].charAt(0)) + colors[mi].substring(1);
    JMenuItem Jmi =new JMenuItem(pos);
    Jmi.setIcon(new IconA(colors[mi]));

    // workaround:
    final Integer innerMi = new Integer(mi);

    Jmi.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JMenuItem item = (JMenuItem) e.getSource();
                IconA icon = (IconA) item.getIcon();
                // HERE YOU USE THE FINAL innerMi variable and no errors!!!
                Color kolorIkony = getColour(colors[innerMi]); 
                textArea.setForeground(kolorIkony);
            }
        });

        mnForeground.add(Jmi);
    }
}