problem with super.paintComponent(g)

2019-07-01 18:53发布

问题:

This is the snippet :

protected void paintComponent(final Graphics g) {

 Runnable r=new Runnable() {

 @Override

  public void run() {
   while(true) {
     super.paintComponent(g);  // <----- line of error
     g.setColor(Color.red);
     g.drawOval(x,y,width,height);
     g.fillOval(x,y,width,height);
     x++;
     y++;
     width++;
     height++;
       if(width==20)
          break;
     try {
        Thread.sleep(100);
     } catch(Exception exc) {
         System.out.println(exc);
       }
   }
  }
};
 Thread moveIt=new Thread(r);
 moveIt.start();
}

The following error is produced when i compile the complete code :

d:\UnderTest>javac mainClass.java
mainClass.java:18: cannot find symbol
     super.paintComponent(g);
          ^
symbol:   method paintComponent(Graphics)
location: class Object
1 error

Why do i get this error?

In case this is my complete code :

import java.awt.*;
import javax.swing.*;
import java.lang.Thread;

class movingObjects extends JPanel {
int x=2,y=2,width=10,height=10;

@Override

protected void paintComponent(final Graphics g) {

Runnable r=new Runnable() {

 @Override

  public void run() {
   while(true) {
     super.paintComponent(g);
     g.setColor(Color.red);
     g.drawOval(x,y,width,height);
     g.fillOval(x,y,width,height);
     x++;
     y++;
     width++;
     height++;
       if(width==20)
          break;
     try {
        Thread.sleep(100);
     } catch(Exception exc) {
         System.out.println(exc);
       }
   }
  }
 };
   Thread moveIt=new Thread(r);
    moveIt.start();
    }
   }

class mainClass {

 mainClass() {
 buildGUI();
}

 public void buildGUI() {
 JFrame fr=new JFrame("Moving Objects");
 movingObjects mO=new movingObjects();
 fr.add(mO);
 fr.setVisible(true);
 fr.setSize(400,400); 
 fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

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

回答1:

You should use a Qualified Super.

movingObjects.super.paintComponent(g);

Because, when you use this or super inside an inner class (in this case: Runnable), you will get the innerclass. If you want to use the outer class from the inner class, use a Qualified This or a Qualified Super.

YourOuterClassName.this
YourOuterClassName.super

Qualified Super is a term I can't find in the JLS, I invented it by myself.



回答2:

If you want animation on a Swing panel then use a Swing Timer.

You should not use a while (true) loop and that code should definitely not be a part of the paintComponent() method or invoke the paintComponent() method directly.

In you custom panel you need to set properties like setOvalLocation(Point). Then when the Timer fires you update the oval location and invokd repaint on the panel.

I suggest you start by reading the Swing tutorial on Custom Painting for a more detailed explanation and example.



回答3:

Because Runnable has no paintComponent() method. This is one of the drawbacks of using anonymous inner classes, it makes it hard to see what the current context is, but in your case, the context is the run() method, therefore super refers to the superclass of your anonymous inner class, which is Runnable.

If you want to refer to the superclass of the outer class from an inner class, you should use movingObjects.super.paintComponent()