简体   繁体   中英

Updating a java Canvas that is a component of a JFrame

How do I update the graphics on my screen from any class for a canvas that is a component of a JFrame? I believe that it is JFrame.update(Graphics g). But I'm not sure. If it is JFrame.update(Graphics g), What is the correct way to call it, and where do I get the Graphics object for the parameters?

Just call repaint() .

Any custom painting you want to do should be done in paintComponent(Graphics) , and be sure to call super.paintComponent(g);

In general, leave the handling of the Graphics instances to Swing. It will provide its own in compliance with its own standard.

This Oracle tutorial shows just that


Here's an example that uses a Swing Timer to request repaint updates from the JFrame every 15 milliseconds.

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

/**
 * @author Obicere
 */
public class ShapeDrawer {

    public ShapeDrawer() {
        final JFrame frame = new JFrame("Shape Drawer");
        final MyPanel panel = new MyPanel();

        frame.add(panel);

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        createRepaintTimer(frame);
    }

    // Just makes calls for the frame to paint every 15 milliseconds
    private void createRepaintTimer(final JFrame frame) {
        final Timer timer = new Timer(15, null);

        timer.addActionListener(e -> {
            if (!frame.isVisible()) {
                timer.stop();
            } else {
                frame.repaint();
            }
        });

        timer.start();
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(ShapeDrawer::new);
    }

    public class MyPanel extends JPanel {

        private long start;

        public MyPanel() {
            start = System.currentTimeMillis();
        }

        @Override
        protected void paintComponent(final Graphics g) {
            // Calling to clear the artifacts!
            super.paintComponent(g);

            g.setColor(Color.RED);

            // Difference between when the current time and when we started
            final long difference = System.currentTimeMillis() - start;

            // Difference in seconds
            final double seconds = difference / 1000d;

            // 1 rotation per second
            final double rotation = seconds * 1440 / 1000;

            final int x = (int) (Math.cos(rotation) * 100);
            final int y = (int) (Math.sin(rotation) * 100);

            g.drawOval(200 + x - 5, 200 + y - 5, 10, 10);
        }

        // Just setting the default size of the panel
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

    }

}

As you can see, the createRepaintTimer(JFrame) method makes the calls to request the graphics to be updated. We don't have to provide a Graphics instance, Swing handles this for us. We then render to the Graphics swing has provided us in the MyPanel#paintComponent(Graphics) method after calling super.paintComponent(Graphics) .

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