内部类实例化澄清

3
我不理解内部类CHameleon的一个功能。我不明白理论中第8行的含义。
我认为它意味着生成JFrame的副本,该副本将在内部类之外访问,以便操作预期的JFrame对象。
编辑:代码会带来空指针异常错误,因为从未引用JFrame对象。 解决方案:将JFrame frame修改为final JFrame frame。
这引出了一个问题,如果有多个JFrames怎么办?
例如,如果我有一个类花园,里面有不同的蔬菜,并且我创建了一个内部类colorsplat来对这些蔬菜进行着色。是创建针对特定蔬菜的特定类的唯一解决方案吗?回答我的问题,在多个JFrames的情况下,它们将显示为不同类型的类,如我的情况?
public class LabelsButtonsPanelsandSnakes {

public static void main(String[] args){
    final JFrame frame = new JFrame("Test"); 

    JMenuBar menuBar = new JMenuBar();  //menubar  
    JMenu menu = new JMenu("Menu");

    JMenuItem chameleon = new JMenuItem("Change Color"); 

    class CHameleonaction implements ActionListener{ //inside class opens 
        JFrame frameHolder;                          //line 8
        public void actionPerformed(ActionEvent e)
        {
            frame.getContentPane().setBackground(new Color(112,253,95));
        }
    }                                                //inside class ends 
    chameleon.addActionListener(new CHameleonaction()); 

    menuBar.add(menu);
    frame.setJMenuBar(menuBar);
}

我也不理解frameHolder变量。这是错误的,并且看起来会导致NullPointerException异常。 - Hovercraft Full Of Eels
没错。看来我的问题实际上是如何将一个JFrame对象从外部类传递到内部类以进行操作。 - fungusanthrax
这基本上只是糟糕的设计...这里没有嵌套类的理由。只需使用匿名ActionListener类实现,并使您需要访问的框架最终(如果您确实需要它)。如果您希望我发布详细信息,请告诉我。 - RudolphEst
如果你要询问的代码产生了异常,那么在你的问题中告诉我们这一点是明智而礼貌的。 - Hovercraft Full Of Eels
根据我的回答,您上述的问题可以通过将frame变量声明为final来解决:final JFrame frame = new JFrame("Test");,然后从ActionListener中引用frame并且删除frameHolder变量。但是无论如何,您的代码设计存在问题。 - Hovercraft Full Of Eels
请注意修改答案。 - Hovercraft Full Of Eels
1个回答

5
你在main方法中做了太多事情,而且大部分代码应该放在其他地方,因为主方法主要用于创建你的“主”对象并启动它们运行,但是其他工作应该很少。如我所指出的,在你当前的代码中,由于你试图调用一个从未被初始化过的字段的方法,这似乎会导致NullPointerException错误。我可以接受你使用内部类来实现简单的监听器接口,正如我所指出的,匿名内部类可以正常工作,但你必须小心谨慎。如果需要引用外部类变量,有几种选择:
  • 如果外部变量是一个字段而不是局部变量,则内部类可以直接引用它。
  • 如果是局部变量,则必须声明为final。
  • 大多数Swing监听器都有一个XxxEvent参数,通过getSource()返回事件源,这通常可以让你得到一个非内部类的引用。

例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class Foo2 extends JPanel {
   private static final Color NEW_COLOR = new Color(112,253,95);
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private JMenuBar menuBar = new JMenuBar();

   public Foo2() {
      JMenuItem chameleon = new JMenuItem(new ChangeColorAction("Change Color")); 
      JMenu menu = new JMenu("Menu");
      menu.add(chameleon);
      menuBar.add(menu);
   }

   public JMenuBar getMenuBar() {
      return menuBar;
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class ChangeColorAction extends AbstractAction {
      public ChangeColorAction(String name) {
         super(name);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         setBackground(NEW_COLOR);
      }
   }

   private static void createAndShowGui() {
      Foo2 mainPanel = new Foo2();

      JFrame frame = new JFrame("Foo2");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setJMenuBar(mainPanel.getMenuBar());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接