内Class实例化澄清
Inner Class Instantiate Clarification
我不明白内部 class 变色龙的一个特征。我不明白第 8 行在理论上是什么意思。
我认为这意味着生成将在内部 class 外部访问的 JFrame 的副本版本,以便操作预期的 JFrame 对象。
编辑:代码带来空指针异常错误,因为从未引用 JFrame 对象。
解决方案:将JFrame 框架修改为最终的JFrame 框架。
这就提出了一个问题,如果有多个 JFrames 怎么办?
例如,如果我有一个种植了不同蔬菜的 class 花园,我创建了一个内部 class colorsplat 来为这些蔬菜着色。是创建针对特定蔬菜的特定 classes 的唯一解决方案吗?因此,为了回答我自己的问题,在多个 JFrame 的情况下,它们会显示为不同种类的 classes,我的情况是?
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);
}
你在 main 方法中做的太多了,大部分代码属于其他地方,因为 main 方法应该主要用于创建你的 main 对象并启动它们运行,但仅此而已。正如我在评论中指出的那样,您当前的代码看起来会将您引向 NullPointerException,因为您正试图在一个似乎从未初始化过的字段上调用一个方法。我同意您将内部 class 用于简单的侦听器接口,并且如前所述,匿名内部 class 可以正常工作,但您必须小心执行此操作。如果您需要引用外部 class 变量,您有几个选择:
- 如果外层变量是字段而不是局部变量,内层class可以直接引用
- 如果是局部变量,必须声明为final.
- 大多数 Swing 侦听器都有一个 XxxEvent 参数,该参数 returns 通过
getSource()
的事件源,这通常会导致您进入非内部 class 参考.
例如
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();
}
});
}
}
我不明白内部 class 变色龙的一个特征。我不明白第 8 行在理论上是什么意思。
我认为这意味着生成将在内部 class 外部访问的 JFrame 的副本版本,以便操作预期的 JFrame 对象。
编辑:代码带来空指针异常错误,因为从未引用 JFrame 对象。 解决方案:将JFrame 框架修改为最终的JFrame 框架。
这就提出了一个问题,如果有多个 JFrames 怎么办?
例如,如果我有一个种植了不同蔬菜的 class 花园,我创建了一个内部 class colorsplat 来为这些蔬菜着色。是创建针对特定蔬菜的特定 classes 的唯一解决方案吗?因此,为了回答我自己的问题,在多个 JFrame 的情况下,它们会显示为不同种类的 classes,我的情况是?
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);
}
你在 main 方法中做的太多了,大部分代码属于其他地方,因为 main 方法应该主要用于创建你的 main 对象并启动它们运行,但仅此而已。正如我在评论中指出的那样,您当前的代码看起来会将您引向 NullPointerException,因为您正试图在一个似乎从未初始化过的字段上调用一个方法。我同意您将内部 class 用于简单的侦听器接口,并且如前所述,匿名内部 class 可以正常工作,但您必须小心执行此操作。如果您需要引用外部 class 变量,您有几个选择:
- 如果外层变量是字段而不是局部变量,内层class可以直接引用
- 如果是局部变量,必须声明为final.
- 大多数 Swing 侦听器都有一个 XxxEvent 参数,该参数 returns 通过
getSource()
的事件源,这通常会导致您进入非内部 class 参考.
例如
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();
}
});
}
}