我代码中有这样两个函数(是我自己为了对比而写的)1.     public    void    containerClass(){ 
2.        JPanel  jp_container    =   new JPanel(){ 
3.            public void setBackground(Color bg) { 
4.                super.setBackground(Color.BLUE); 
5.            } 
6.            public Component add(Component comp) { 
7.                JLabel  jl  =   new JLabel("你好!")   ; 
8.                return super.add(jl); 
9.            } 
10.        }   ; 
11.        add(jp_container)   ; 
12.    } 
13.    public  void    commonClass(){ 
14.        JPanel  jp_common   =   new JPanel(); 
15.        jp_common.setBackground(Color.red)  ; 
16.        add(jp_common)  ; 
17.         
18.        JLabel  jl  =   new JLabel("Welcome!")  ; 
19.        jp_common.add(jl)   ; 
20.    }结果,containerClass(){}不显示【你好!】两个字,问题:
1、containerClass(){}不显示【你好!】两个字,即使把JLabel jl放在内部类的最外面也不行!为什么?怎么改?2、commonClass(){}中,我重新写了些,大家看下:1.    public  void    commonClass(){ 
2.        JPanel  jp_common   =   new JPanel(); 
3.        jp_common.setBackground(Color.red)  ; 
4.        add(jp_common)  ; 
5.         
6.        JLabel  jl  =   new JLabel("Welcome!")  ; 
7.        jp_common.add(jl)   ; 
8.        Font    font    =   new Font("华文彩云",Font.BOLD,30)   ; 
9.        jl.setFont(font)    ; 
10.    }
问题:
2、一旦我把commonClass()中jp_common.add(jl) ;这一句放在函数的最下面,则“Welcome!”就不能显示 华文彩云 这种字体!为什么?

解决方案 »

  1.   


    第一个问题中:add(Component comp);你可以放条输出语句进去测试一下第二个问题:是还没有刷新,再加个   jl.repaint();就可以了
      

  2.   


    第一个问题中:add(Component comp)并没有执行;你可以放条输出语句进去测试一下第二个问题:是还没有刷新,再加个   jl.repaint();就可以了 
      

  3.   

    速度跳过Swing部分,别再为Swing纠结了!
      

  4.   


    我第一个问题还是没解决,第二个问题,我自己这样做也可以: public Component add(Component comp) {
    JLabel jl = new JLabel("你好!") ;
    return super.add(jl);
    }此时,就可以了!但是,第一点该怎么做呢?求教!
      

  5.   

    我调试出来了,但出了问题!你看看:首先,是没有“你好”两个字的:
    package Example_1;import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JPasswordField;
    public class TestContainerClassContrastCommonObject extends JFrame {
    private static final long serialVersionUID = 1L;
    int width = 500 ;
    int height = 200 ;
    public void setupWindow(){
    setVisible(true);
    setMinimumSize(new Dimension(width,height)) ;
    setLocationRelativeTo(null) ;
    setLayout(new GridLayout(2,1)) ;//我设置为网格布局
    addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent arg0) {
    System.exit(0) ;
    super.windowClosing(arg0);
    }
    }) ;
    }
    public void containerClass(){
    JPanel jp_container = new JPanel(){
    private static final long serialVersionUID = 1L;
    public void setBackground(Color bg) {
    super.setBackground(Color.BLUE);
    }
    public Component add(Component arg0) {
    return super.add(new JLabel("你好!"));
    }
    } ;
    add(jp_container) ;

    // JPasswordField jpf = new JPasswordField(5) ;
    // jp_container.add(jpf) ;
    }
    public TestContainerClassContrastCommonObject() {
    setupWindow() ;
    containerClass() ;
    pack() ;
    }
    public static void main(String[] args) {
    new TestContainerClassContrastCommonObject() ;
    }
    }
    之后,把 注释 掉的部分取消掉注释,就有了JLabel("你好")。
    我有怪了,那个之前jp_container内部写add()就没有出现,但是我又放一个add(JPasswordField)在精JPanel 里,他不出现JPasswordField,反而出现JLabel,怪了,为什么呢?
      

  6.   

    第二个问题只是个刷新的问题,repaint()一下就OK根据你的描述,第一个问题原因应该是:在你初始化jp_container的时候重写了add函数,同时也只是重写了add函数并没有调用。所以当你执行
           
     JPasswordField jpf = new JPasswordField(5); 
           
             jp_container.add(jpf);时就调用了你重写的add函数所以“你好”出现了,而你之后在panel中调用add(JPasswordField),相当于调用了你重写的add函数,所以jabel出现了。而你的add(jpf)无效就是因为你重写add函数覆盖原来的add函数! 
      

  7.   

    鉴于我基础比较差,请允许我多啰嗦几句:你说这是由于重写造成的,那么:
    我可不可以这样讲:JPanel jp = new JPanel(){...},这里跟一个大括号,括号里的东西时重写?
    假设是吧,但是,如果没有那句add(),我一直认为JPanel jp = new JPanel(){...}在new的时候就已经初始化并且调用了{...}大括号里的东西,不然的话,为什么我写一句jFrame.add(jp),就显示出jp的背景颜色【假设JPanel jp = new JPanel(){public void setBackground(){...super.(red)}}】。望指明我上面这几句话的错误之处,我一直在犯糊涂!
      

  8.   


    大括号里的函数是重写了,但不一定会被调用,而你的、setBackground()执行了是由于有其他函数调用了它,add函数没有被调用!你可以写个简单的例子试一下:创建一个新类继承JPanel并在类中重写setBackground(),在测试一下该类你会发现setBackground()被自动调用,原因如上面说的,setBackground被其他函数调用了。再说一个例子为什么有些函数会被调用了在学习java的画图功能时候,经常会看到super.paintComponent,书上说一定要有而且必须是在第一句,不然就会出问题!可恨的是书上没有解析这是为什么。下面简单的解析一下这个语句的作用。
      首先我们要知道GUI组件(如JPanel,JButton等)本身并没有paintComponent的方法,它的paintComponent是JComponent继承下来的。
      然后我们来看看JComponent的paintComponent
       protected void paintComponent(Graphics g) {
            if (ui != null) {
                Graphics scratchGraphics = SwingGraphics.createSwingGraphics(g);
                try {
                    ui.update(scratchGraphics, this);
                }
                finally {
                    scratchGraphics.dispose();
                }
            }
    }
    createSwingGraphics的有什么用呢?  只是用于创建一个新的画图对象而与
    public static Graphics createSwingGraphics(Graphics g) {
            if (g == null) {
                Thread.dumpStack();
                return null;
            }
            return g.create();
    }
    那update呢?  明显是用于画出组件的背景色
    public void update(Graphics g, JComponent c) {
        if (c.isOpaque()) {
            g.setColor(c.getBackground());
            g.fillRect(0, 0, c.getWidth(),c.getHeight());
        }
        paint(g, c);
    }
    最后就用dispose把画图的对象占用的资源释放掉!
    综合以上,我们发现paintComponenet的作用是给组件画上背景色。如果不调用此方法,我们之前对组件设置的背景色等属性将不会被展现。如果此方法在子类的实现中最先被调用,背景就处于最底下的一层,子类其他利用g进行的绘图将在有一个背景的基础下进行。
      

  9.   


    假设有一个JComponent JComponent_Name = new JComponent{...Method...}
    我来根据这个JComponent来做些思考,劳烦你指点下:1、根据你所述:在JComponent JComponent_Name = new JComponent{...Method...}中,Method只是重写被new 的JComponent 的方法,而之所以能运行,是因为【隐藏的方法】将其调用了,而未被调用的,则不被运行!请问这句话我分析的正确不?2、突然想起你之前说我很多方法之所以不被显示,需要repaint(),也就是说,只要repaint(),就可以调度所有new 里面的 被重写的 Method ?3、我自己直接在new {...}里面重写repaint(),没反应!拿到外面写也没反应,作为初学者,我渴望你能否写个(或说修改下)某个用了repaint的方法我看看?如果能,请看下文:   我自己写了个监听,目的是解决JPasswordField中setText()的文字不能显示的问题,我是这样想的,同时放JTextField(JTF)和JPasswordField(JPF)在JPanel中,先jpanel.add(JTF),等到MouseListener监听到有鼠标移动到jpanel,再隐藏JTF,然后再jpanel.add(JPF),为了不影响代码,于是,我做了个实验。这个实验,是在监听器里写一个add(JComponent),看看有没有用!但让我惊讶的是,我发现,没有用,我思考了很久,突然发现,我点击放大或缩小窗口,这JComponent就出现了,我马上想到你上次所说的repaint(),可惜,我不会用!望指点【我把我写的实验代码贴出来供你修改】:package Example_1;
    import java.awt.BorderLayout;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JTextField;public class TestContainerClassContrastCommonObject extends JFrame {
    private static final long serialVersionUID = 1L;
    TestContainerClassContrastCommonObject(){
    JTextField jl_1 = new JTextField("点我,我是老大!") ;
    final JLabel jl_2 = new JLabel("点我,我是老二!") ;
    getContentPane().add(jl_1,BorderLayout.SOUTH) ;
    jl_1.addFocusListener(new FocusListener(){
    public void focusGained(FocusEvent arg0) {
    getContentPane().add(jl_2,BorderLayout.CENTER);
    repaint();
    }
    public void focusLost(FocusEvent arg0) {
    }
    }) ;
    this.setBounds(50, 50, 300, 300);
    this.setVisible(true) ;
    this.setDefaultCloseOperation(DISPOSE_ON_CLOSE) ;
    }
    public static void main(String[] args) {
    new TestContainerClassContrastCommonObject() ;
    }
    }
      

  10.   


      函数重写了,但不一定被调用就是这个意思,而repaint是重画的意思,不是可以调度所有new 里面的 被重写的 Method ,这个完全两码事。如你最初问的那个关于字体的问题,repaint就是重新画图的意思,那么我们才能看到最新的!问题总是问不完了,建议你先看java的基础书籍,掌握基本后再去看进阶!
      

  11.   

    谢谢你提供资料,不过真心想知道,我上面那个,最后那个代码,就是[点我,我是老大]这个代码,怎么做才能使得FocusListener有用呢?换句话说,怎么做才能使repaint()有用呢?
      

  12.   

    好的,我去看书!但真心想说最后一句,那个监听怎么用repaint()才有用,
    我听了这么久的理论,可找不到一个实例!希望你直接修改下我的{点我,我是老大,点我,我是老二}这个用了FocusListener的代码。我想看看实例,这样思考就不会空泛了,而是具体了!谢谢
      

  13.   


    你写的FocusListener中的repaint没有起到具体作用,因为一开始你的输入框就已经获得焦点调用你函数内的代码,举个简单的例子,你为输入框添加个鼠标点击事件,然后在里面写:removeall();
    //repaint();如果没有repaint()将看不到界面重画,有repaint()则看到界面中的控件全部没了好吧,记得结贴哦亲!
      

  14.   


    好的!
    我先看下你提供的removeall的用法!