简体   繁体   中英

What's the value of “Graphics g” in “paint()” for a Java applet?

I am a beginner when it comes to making Java applets, and for my first applet, I drew a smiley face using paint(). Now, I want to make the smiley face blink. I have managed to get my timers and everything set up, but I need to use the start() method to get the timers going, and it seems that by including other methods, the paint method does not invoke itself. Because of this, I am assuming that I need to invoke paint() from start(), but the problem is I do not know what I am supposed to initialize the Graphics variable to in order to get paint() to actually work.

SSCCE

import java.awt.*;
import javax.swing.*;
import java.applet.Applet;
import java.awt.event.*; 

public class Project2_15 extends Applet
{   
    public void paint(Graphics g)
    {
setBackground(Color.lightGray);
    }

    // This handles the starting of timer execution.
    public void start()
    {
            Graphics g; // What do I initialize this to?
    paint(g);
    }

    // Timer Stuff
    ActionListener blinkShut;
    public Project2_15(final Graphics g) {
        this.blinkShut = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)       {
                g.setColor(Color.black);
            }
        };
    }
}

You need your timer to change the state of the applet, suggest that it be repainted, and then have your applet's paint method to react to the state. Some suggestions:

  • Use a Swing Timer for your timer
  • Give your applet a non-static boolean field called blink.
  • In the Timer's actionPerformed method, change the boolean field of the applet, blink, to its opposite state: blink = !blink;
  • Then call repaint() . This will tell the JVM to possibly repaint the applet.
  • In your paint(...) method use the state of the blink variable in an if block, and if true paint an eye, if false paint a closed eye.
  • You're better off using a Swing applet or JApplet.
  • If you're using a JApplet, then you'll do your painting in a JPanel's paintComponent(...) method, not in the paint method.
  • Either way, be sure to call the super method as the first method call in your painting method, either super.paint(g) if in the Applet's paint method or super.paintComponent(g) if in a JPanel's paintComponent method. This allows your GUI to erase previous painting.

Edit
Regarding your code:

public void start()
{
   Graphics g; // What do I initialize this to?
   paint(g);
}

and:

public Project2_15(final Graphics g) {
    this.blinkShut = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e)       {
            g.setColor(Color.black);
        }
    };
}

Please throw this code out as you almost never paint this way or call paint directly. Please read or re-read my recommendations above.


Edit 2
Regarding your comments:

So I can't just create a separate timer and put the code in their?

I never said this. Feel free to use a separate timer, and put in decent code inside of it. You of course will have to discard your current code since you do not want to manipulate the Graphics object directly as you're trying to do.

In addition to his eyes blinking, I was also hoping to have his tongue go in and out using a separate timer.

Then go for it!

Here is the code with some corrections:

import java.awt.*;
import javax.swing.*;
import java.applet.Applet;
import java.awt.event.*;

public class Project2_15 extends Applet
{

    public boolean wink = false;
    Timer timer;

    public void paint(Graphics g)
    {
        super.paint(g);
        // Graphics g; // What do I initialize this to?  ALREADY INITIALIZED
        //paint(g);
        if (wink) {
            g.drawLine(1,1,100,100);
        } else {
            g.drawOval(1,1,100,100);
        }
    }

    // This handles the starting of timer execution.  NO IT DOES NOT!
    // public void start()
    @Override
    public void init()
    {
        setBackground(Color.lightGray);
        timer = new Timer(250,blinkShut);
    }


    @Override
    public void start() {
        timer.start();
    }

    @Override
    public void stop() {
        timer.stop();
    }
    // Timer Stuff
    ActionListener blinkShut = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            wink = !wink;
            repaint();
        }
    };
}

See Performing Custom Painting . It would be the same basic process with applet or frame.

  1. Add a container ( Panel / JPanel ) to the top-level container.
  2. Override the paint(..) AWT or paintComponent(..) Swing method.
  3. Call super.. as the first statement.
  4. Do the custom painting to the supplied Graphics instance.

Animation can be achieve using a Swing based Timer.

Of course I would tend to replace steps 1) to 4) with painting to a BufferedImage displayed in a JLabel / ImageIcon .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM