2015-03-02 2 views
2

Я не понимаю особенность внутреннего класса Chameleon. Я не понимаю, что означает линия 8.Внутренний класс Мгновенное уточнение

Я думаю, что это означает создание дублирующей версии JFrame, доступ к которой будет осуществляться вне внутреннего класса, чтобы манипулировать предполагаемым объектом JFrame.

Редактировать: Код содержит ошибку исключения нулевого указателя, поскольку объект JFrame никогда не ссылается. Решение: изменить рамку JFrame на конечную рамку JFrame.

Это поднимает вопрос о том, что, если было несколько JFrames?

Например, если бы у меня был классный сад с различными овощами, и я создал внутренний класс цветов, который окрашивает эти овощи. Является единственным решением для создания определенных классов, которые нацелены на specfic veggies? Поэтому, чтобы ответить на мой собственный вопрос, в случае с несколькими 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); 
} 
+0

Я не понимаю переменную 'frameHolder' либо. Это неправильно, и похоже, что это приведет к исключению NullPointerException. –

+0

Это правильно. По-видимому, мой вопрос заключается в том, как связать объект JFrame с внешним классом во внутренний класс для манипуляции. – fungusanthrax

+0

Это, по сути, просто плохая конструкция ... здесь нет причин для вложенного класса. Просто используйте анонимную реализацию класса ActionListener и сделайте фрейм, необходимый для доступа к окончательному (если вам это действительно нужно). Если вы хотите, чтобы я опубликовал данные, дайте мне знать. – RudolphEst

ответ

4

Вы делаете слишком много в вашем основном методе, и большая часть этого кода принадлежит в другом месте, так как основной метод следует использовать в основном создавать основные объектов и начать их работу, но немного другие. Как отмечено в моем комментарии, ваш текущий код заставит вас переходить к исключению 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(); 
     } 
     }); 
    } 
} 
Смежные вопросы