为什么JLabel不能成为内部类声明

时间:2010-08-10 15:04:27

标签: java

为什么java J swing中的JLabel不能像JMenu或JMenuBar那样在内部类中声明

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class Chk extends JFrame 
{

private JLabel lbl ;

public Chk()
{

lbl = new JLabel("StatusBar");  
lbl.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
add(lbl,BorderLayout.SOUTH);


JMenuBar menubar=new JMenuBar();
JMenu file = new JMenu("File");
JMenu view = new JMenu("View");

JCheckBoxMenuItem sbar= new JCheckBoxMenuItem("Status-Bar");
sbar.setState(true);
sbar.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{


if (lbl.isVisible())
{lbl.setVisible(false);}
else
{lbl.setVisible(true);}


}});




menubar.add(file);
view.add(sbar);
menubar.add(view);
setJMenuBar(menubar);

setSize(300,200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

public static void main(String args[])
{new Chk();}

}

在上面的程序中为什么我要把这行“私人JLabel lbl;”
为什么我不能使用JLabel lbl = new JLabel(“Label”);

3 个答案:

答案 0 :(得分:3)

你可以,但是闭包中使用的变量需要被声明为final。

    final JLabel lbl = new JLabel("StatusBar");
    lbl.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
    add(lbl, BorderLayout.SOUTH);

这应该有用。

如果您想知道,闭包是您创建匿名内部类的实例并引用在封闭范围中声明的变量的部分。在这种情况下,'lbl'是在匿名ActionListener实例中引用的:

    sbar.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            if (lbl.isVisible()) {
                lbl.setVisible(false);
            } else {
                lbl.setVisible(true);
            }
        }
    });

答案 1 :(得分:0)

您不能将它设为私有构造函数,因为您试图在构造函数之外的actionPerformed方法中使用它。你可以通过宣布它是最终的来偷偷摸摸,但我一直认为这是一个可疑的技巧,我不知道它是否可以保证工作,或者它只是在愚弄编译器。

答案 2 :(得分:0)

我认为你可以,你只需要定义它最终

您可以在addActionListner之前将其定义为局部变量。