0

I really can't figure this out and I need your help. I've created a simple applet. I have a panel and a canvas. I draw on the canvas. I add the canvas to the panel. I add the panel to the applet. I'm trying to draw a circle on canvas but I can't see it. If I resize the applet, I can see the circle flickering behind the canvas. Please help.

        import java.applet.*;
        import java.awt.*;


        public class TestCanvas extends Applet implements Runnable
        {
            Panel myPanel = new Panel();
            int x = 50;
            int y = 50;
            int width = 100;
            int height = 100;
            boolean startBall = false;

            Graphics bufferGraphics;
            Image offscreen;

            Thread t;

            public void init()
            {
                canvas.setSize(500,500);

                //canvas.setMaximumSize(new Dimension(500,500));
                //canvas.setMinimumSize(new Dimension(50,50));
                myPanel.add(canvas);
                add(myPanel);
                //For double buffering
                offscreen = createImage(canvas.getWidth(),canvas.getHeight());
                bufferGraphics = offscreen.getGraphics();

            }

            public void start()
            {
                t = new Thread();
                t.start();
                startBall = true;

            }

            public void stop()
            {
                t = null;
            }

            public void destroy()
            {
                t = null;
            }

            public void run()
            {
                for ( ; ; )
                {
                    try
                    {
                        canvas.repaint();
                        Thread.sleep(100);
                    }catch(InterruptedException e){}



                }
            }

            class myCanvas extends Canvas
            {
                private static final long serialVersionUID = 1L;

                public myCanvas()
                {
                    setBackground(Color.yellow);
                    setSize(500, 300);
                    //setBounds(0, 0, 500, 300);

                }   

            }

            myCanvas canvas = new myCanvas();

            public void paint(Graphics g)
            {
                g = canvas.getGraphics();
                bufferGraphics.clearRect(0,0,canvas.getWidth(), canvas.getHeight());
                bufferGraphics.setColor(Color.black);
                //x++;
                //y++;
                bufferGraphics.setColor(Color.black);
                bufferGraphics.fillOval(x, y, width, height);       
                g.drawImage(offscreen,0,0,null);        
            }

            public void update(Graphics g)
            {
                canvas.paint(g);
            }



        }
  • You have defined an object and a bunch of functions. How are you calling those items? – zipzit Mar 29 '16 at 01:24
  • When the applet starts, it runs the thread automatically. The paint method paints a ball on the canvas, well it's supposed to. The ball appears in the back though. I think it's something to do with calling graphics on a component and making the component transient, but I can't figure it out yet. – Jeremy Mwangelwa Mar 29 '16 at 01:44
  • 1
    Let's start with; applets are a dead technology, with just about all browsers no actively blocking them and discontinuation of Java plugin; awt was basically superseded by swing 16 years ago, so unless you're intending to use BufferStrategy, you really don't need to use awt based components, swing components are also double buffered by default. Now, having said all that, your attempt at double buffering is generally wrong, you should be using a BufferedImage, not what ever your doing. Your `canvas` doesn't actually appear on the screen, but that's what you're attempting to paint to – MadProgrammer Mar 29 '16 at 01:52
  • Simple [Swing based example](http://stackoverflow.com/questions/27681998/smooth-animation-in-java-for-fast-moving-objects/27682530#27682530) – MadProgrammer Mar 29 '16 at 01:56
  • Simple [BufferStrategy](http://stackoverflow.com/questions/34689176/bufferstrategy-not-showing-on-java-awt-frame/34689291#34689291) – MadProgrammer Mar 29 '16 at 01:58
  • We can't use Swing. My professor wants us to use awt because if you know the basics, then you can do Swing and everything that supersedes awt. Thanks for your help, though. – Jeremy Mwangelwa Mar 29 '16 at 01:59
  • 2
    Your professor needs to move into the modern age (sorry), swing and awt use a fundamentally different approach to painting, I've personally never used awt based framework in over 16 years professionally GUI development. You need to know that swing is underpinned by awt, but generally that's about it. However, it doesn't negate the fact the applet is a dead technology and, as much as I might not like it, Swings days are probably numbered and JavaFX would be a better starting point (if not html5) and you attempt at double buffering is wrong :P (for both awt and Swing) – MadProgrammer Mar 29 '16 at 02:07
  • I know it's wrong. I'm a student. I'm learning. You're obviously experienced. I really just wanted help. But I'll figure it out. It's no biggie. – Jeremy Mwangelwa Mar 29 '16 at 02:45
  • 1
    Show your professor [Why CS teachers should stop teaching Java Applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/). You are learning material that should actually be avoided. Saying "*if you know AWT, you can learn Swing and everything that supersedes it*" is like saying "*The newer frameworks contain nothing new*", which is wrong. You should really avoid using outdated systems. – Vince Mar 29 '16 at 03:14
  • Thanks Vince, you have been very helpful. I appreciate that. I think I might just show him that article. I doubt he'll change though. He teaches FORTRAN, so yeah, he's old school. – Jeremy Mwangelwa Mar 29 '16 at 03:28
  • *"I think I might just show him that article."* Please do! *"I doubt he'll change though."* If he resists, ask him to present an 'Hello World' applet that the class can visit on the web. It is a lot harder than it sounds - given 1) every applet must now be digitally signed with a certificate from a Certification Authority, & 2) [Java Plugin support deprecated](http://www.gizmodo.com.au/2016/01/rest-in-hell-java-plug-in/) and [Moving to a Plugin-Free Web](https://blogs.oracle.com/java-platform-group/entry/moving_to_a_plugin_free). – Andrew Thompson Mar 30 '16 at 01:51
  • 1
    @Andrew Thompson. Thank you Andrew! I very much appreciate it! I will show him that article. He's response might just be comical! – Jeremy Mwangelwa Apr 05 '16 at 10:22
  • `Graphics bufferGraphics;` this declaration is illegal. You cannot create an object of the `Graphics` class. –  Jun 05 '16 at 12:44

1 Answers1

1

It has gotten to the stage where I won't touch a problem involving either applets or AWT until the person asking the question had given reasonable responses as to why they were using either. OTOH you have already partly fulfilled that, so here is a working example of animating the ball.

Look carefully at the differences between your code and this code.

import java.applet.*;
import java.awt.*;

public class TestCanvas extends Applet implements Runnable {

    Panel myPanel = new Panel(new GridLayout());
    int x = 0;
    int y = 0;
    int width = 100;
    int height = 100;
    boolean startBall = false;
    myCanvas canvas = new myCanvas();
    Thread t;

    public void init() {
        myPanel.add(canvas);
        System.out.println("" + this.getLayout());
        /* A Single component added to a no args GridLayout will be stretched 
         to fill the avilable space. */
        this.setLayout(new GridLayout());
        add(myPanel);
        t = new Thread(this);
        t.start();
    }

    public void start() {
        t = new Thread();
        t.start();
        startBall = true;
    }

    public void stop() {
        t = null;
    }

    public void destroy() {
        t = null;
    }

    public void run() {
        for (;;) {
            try {
                canvas.repaint();
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }
    }

    class myCanvas extends Canvas {

        private static final long serialVersionUID = 1L;

        public myCanvas() {
            setBackground(Color.yellow);
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.clearRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.black);
            x++;
            y++;
            g.setColor(Color.black);
            g.fillOval(x, y, width, height);
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433