代码之家  ›  专栏  ›  技术社区  ›  fungusanthrax

内部类实例化澄清

  •  3
  • fungusanthrax  · 技术社区  · 9 年前

    我不理解内部类CHamelion的一个特点。我不明白理论上第8行的意思。

    我认为这意味着要生成一个复制版本的JFrame,该版本将在内部类外部访问,以便操纵预期的JFrame对象。

    编辑:代码会导致空指针异常错误,因为从未引用JFrame对象。 解决方案:将JFrame帧修改为最终JFrame。

    这就提出了一个问题:如果有多个JFrame,会发生什么?

    例如,如果我有一个包含不同蔬菜的班级花园,我创建了一个内部班级的彩色图案来为这些蔬菜上色。创建针对特定蔬菜的特定类是唯一的解决方案吗?所以,为了回答我自己的问题,在多个JFrame的情况下,它们会显示为不同种类的类,我的情况是?

    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);
    }
    
    1 回复  |  直到 9 年前
        1
  •  5
  •   Hovercraft Full Of Eels    9 年前

    您在main方法中做的太多了,而且大部分代码都属于其他地方,因为main方法应该主要用于创建 主要的 对象,并启动它们运行,但其他很少。正如我在评论中所指出的,当前代码似乎会导致出现NullPointerException,因为您试图调用一个从未初始化过的字段上的方法。我可以将内部类用于简单的侦听器接口,正如所指出的,匿名的内部类可以很好地工作,但您必须小心操作。如果需要引用外部类变量,则有几个选项:

    • 如果外部变量是字段而不是局部变量,则内部类可以直接引用它。
    • 如果它是局部变量,则必须声明 最终的 .
    • 大多数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();
             }
          });
       }
    }