需要帮助访问内部类中的变量for循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了需要帮助访问内部类中的变量for循环相关的知识,希望对你有一定的参考价值。

我在内部类Code中访问变量int i时遇到问题:

public class OnColumnSelectPanel {

JFrame jFrame;
JPanel mainJPanel;
//JPanel jPanel1;
//JTextField jTextField;
//JButton jButton;
//JComboBox jComboBox [];
MigLayout layout;
MigLayout frameLayout;
//column names
ColumnNames cn = new ColumnNames();
List<String> listedColumnNames = cn.getColumnNames();
String columnNames[] = listedColumnNames.toArray(new String[0]);

public OnColumnSelectPanel(int n) {

    //jPanel1 = new JPanel();
    jFrame = new JFrame("Create Structure of Columns");
    // mainJPanel = new JPanel();
    layout = new MigLayout("flowy", "[center]rel[grow]", "[]10[]");
    frameLayout = new MigLayout("flowx", "[center]rel[grow]", "[]10[]");
    //mainJPanel.setLayout(new BoxLayout(mainJPanel, BoxLayout.X_AXIS));
    //MigLayout mainJPanelLayout = new MigLayout("flowy", "[]rel[grow]", "[]5[]");

    // declare & initialize array
    JPanel jPanel[] = new JPanel[n];
    JComboBox jComboBox[] = new JComboBox[n];
    JButton jButton[] = new JButton[n];
    final int num = 0;
    for (int i = 0; i < n; i++) {

        //assign array
        jComboBox[i] = new JComboBox(columnNames);
        jButton[i] = new JButton("add Sub Heading");
        jPanel[i] = new JPanel();
        System.out.println("Loop number: " + i);

        jButton[i].addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {

                for (int j = 0; j < n; j++) {
                    if (j <= n) {
                        jComboBox[j] = new JComboBox(columnNames);
                        jPanel[j].add(jComboBox[j]);
                        jFrame.revalidate();
                    } else {
                        JOptionPane.showMessageDialog(null, "You have exceeded your limit");
                    }
                }

            }
        });
        //set layout
        jPanel[i].setLayout(layout);
        //jPanel[i].setPreferredSize(new Dimension(50, 400));
        //mainJPanel.setLayout(mainJPanelLayout);
        jFrame.setLayout(frameLayout);
        System.out.println(" height " + jPanel[i].getHeight());
        jPanel[i].add(jComboBox[i], new CC().newline());
        //jPanel.add(jTextField);
        jPanel[i].add(jButton[i]);
        //mainJPanel.add(jPanel[i], "spany");
        jPanel[i].repaint();

        jFrame.add(jPanel[i]);
        jFrame.pack();
        jPanel[i].revalidate();
        jFrame.revalidate();
        //mainJPanel.revalidate();
        //jFrame.revalidate();

    }
    //mainJPanel.setSize(600, 400);

    //jFrame.add(jPanel1);
    jFrame.setVisible(true);
    jFrame.setSize(600, 400);
    jFrame.setAlwaysOnTop(true);
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Output Frame

如您所见,输出图像。这里的问题是当我点击添加子标题按钮时,组合框被添加到每个jpanel。这是因为我可以将值i传递给内部类。知道可能的解决方案会很有趣。

仅供参考我正在使用Mig Layout。

提前致谢。

答案

只能从匿名类访问effectively final变量。 i被循环修改,所以它不是最终的。

解决方法如下所示:

for (int i = 0; i < n; i++) {
   ...

  final int effectivelyFinal = i;
  jButton[i].addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent ae) {
      ...
      // use effectivelyFinal instead of i
    });
}

但正如其他人所建议的那样,将匿名类提取到实际类中并使用构造函数传递所有必需参数会更好。这可能如下所示:

class MyListener implements ActionListener {

    private final int index;

    // add more fields for other required parameters

    public MyListener(int index) {
        this.index = index;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      // use index    
    }
}

用法:

jButton[i].addActionListener(new MyListener(i));

以上是关于需要帮助访问内部类中的变量for循环的主要内容,如果未能解决你的问题,请参考以下文章

在内部片段类中使用ListView

在 Activity 内部,如何暂停 for 循环以调用片段,然后在按钮单击片段后恢复循环以重新开始

如何访问在mapreduce中扩展reducer的静态内部类中的静态变量?

Core java for impatient 笔记

在 Laravel 中的 for 循环外访问变量

嵌套类:如何访问封闭类中的成员变量