super.paintComponent();
Why is this important?
super.paintComponent() is normally called as one of the first lines in your own paintComponent() method, the one that you get when you make a subclass of JPanel.
What does it do?
This runs the paintComponent() method of the JPanel class. What this standard paintComponent method does is to completely repaint the screen with the backround colour, thus essentially clearing it and repaiting it with the background colour.
There are two potential problems with this:
Let's assume that the drawing that we're doing requires a black background. How do we get this to show up only once, and then never get cleared?
boolean firstTime = true;
public void paintComponent(Graphics g) {
/******* trying various methods to get the background to only paint once. ********/
if (firstTime) {
super.paintComponent(g);
firstTime = false;
}
//rest of method does the painting
This DOES NOT WORK. I think that it might actually run before the JPanel is displayed, and then when it's displayed, it gets shown with the default gray background.
boolean firstTime = true;
public void paintComponent(Graphics g) {
/******* trying various methods to get the background to only paint once. ********/
if(this.isVisible()) {
if (firstTime) {
super.paintComponent(g);
firstTime = false;
}
}
//rest of method does the painting
This DOES NOT WORK. I don't know why.
When the JPanel is first created its size is (0,0). It only gets a size when it is displayed, so keep clearing and redrawing the background until the size is more than 10 pixels wide.
boolean firstTime = true;
public void paintComponent(Graphics g) {
if (firstTime) {
super.paintComponent(g);
scrW = this.getWidth();
scrH = this.getHeight();
cx = scrW/2;
cy = scrH/2;
if (cx > 10) firstTime = false;
return;
}
This DOES NOT WORK. I don't know why.
private int countDown = 10;
public void paintComponent(Graphics g) {
if (countDown > 0) {
super.paintComponent(g);
countDown--;
return;
}
This works!!! countDown can be reduced down to about 6 and it still works. Below that the background doesn't draw.
This is a bit of a kludge though. It's kind of embarassing that Java Swing doesn't have a proper draw system that tells you when something is first visible.
Now that it's working, you can add in the code that calculated the centre of the screen:
private int countDown = 10;
public void paintComponent(Graphics g) {
if (countDown > 0) {
scrW = this.getWidth();
scrH = this.getHeight();
cx = scrW/2;
cy = scrH/2;
super.paintComponent(g);
countDown--;
return;
}
All that this does is it stops the program for having to recalculate the centre of the screen every time that the JPanel is redrawn.
public void paintComponent(Graphics g) {
try {
java.awt.Robot rb = new java.awt.Robot();
Color pixel = rb.getPixelColor(100,100);//gets the color of the pixel at screen coordinate 0,0.
if (pixel.getRed() > 0) { // if the background is any shade of gray (or red)
super.paintComponent(g);
}
} catch (AWTException e) {
e.printStackTrace();
System.exit(0);
}
This works!! BUT it is REALLY slow and slows the program down tremendously.
It's too much work to create a robot object and get the pixel every single time we draw the screen. Even moving the creation of the rb object to the DrawingPanel constructor does not speed the program up. It's the getPixelColor that is slowing it down.
This works only when a timer is used as well (for some reason). What happens is when the JFrame is first drawn, it is resized from (0,0) to the size that you specify via setSize() or pack(). This event only happens when the screen is resized, so we're not using a lot of resources checking something every time we draw the screen.
... code to come ...
Please see Spiral.java