Java Applet 在屏幕上打印额外的圆圈

JavaApplet extra circles printing on screen

我是新手。我试图在 javaApplet 中画一个圆圈,但不知何故在输出中它显示了 3 个圆圈。任何的想法?

import javax.swing.JApplet;
import java.util.*;
import java.awt.*;

public class Shapes extends JApplet
{
    public void paint (Graphics page)
    {
        resize(400,300);
        Random rand = new Random();

        // Declare size constants
        final int circleMax = 160,circleMin = 40; // circle max and min diameter
        final int locMaxX = 360, locMaxY = 260;
        int radiusSize = 0, locationx = 0,locationy = 0 ;

        // Declare variables
        radiusSize = (rand.nextInt(circleMax)+ circleMin); 
        locationx =20 ;//rand.nextInt(locMaxX)+ 20;
        locationy =20 ;// rand.nextInt(locMaxY) + 20;

        // Draw the circle 1
        page.drawOval(locationx, locationy, radiusSize,radiusSize);
    }
}

您的主要问题是您在绘画方法中调用 resize(...) 而不是调用 super 的绘画方法。话虽如此,我的建议是:

  • 切勿在顶级 window(例如 JApplet 或 JFrame)的绘制方法中绘制。
  • 而是在显示在顶层 window 中的 JPanel 的 paintComponent 方法中绘制。
  • 在你的绘画方法中调用 super 的方法,通常是先调用。

例如

import javax.swing.JApplet;
import java.util.*;
import java.awt.*;

public class Shapes extends JApplet {

    @Override
    public void init() {
        add(new ShapesPanel());
    }

}    

class ShapesPanel extends JPanel {
    private Random rand = new Random();
    // Declare size constants
    final int circleMax = 160,circleMin = 40; // circle max and min diameter
    final int locMaxX = 360, locMaxY = 260;
    int radiusSize = 0, locationx = 0,locationy = 0 ;

    public ShapesPanel() {
        radiusSize = (rand.nextInt(circleMax)+ circleMin); 
        locationx =20 ;//rand.nextInt(locMaxX)+ 20;
        locationy =20 ;// rand.nextInt(locMaxY) + 20;
    }

    @Override
    protected void paintComponent (Graphics page)   {
        super.paintComponent(page);
        // Draw the circle 1
        page.drawOval(locationx, locationy, radiusSize,radiusSize);
    }
}

传递给您的组件的 Graphics 上下文是共享资源,这意味着它将包含以前绘制给它的内容。

由于在您进行任何自定义绘制之前未能调用 super.paint,您已经阻止了小程序执行它设计的许多关键任务(其中之一是填充 Graphics 上下文与背景颜色)。

查看 Painting in AWT and Swing and Performing Custom Painting 了解有关 Swing 和 AWT 绘画工作原理的更多详细信息。

现在,您可以简单地调用 super.paint,但通常不鼓励覆盖像 JApplet 这样的顶级容器的 paint 方法,它实际上包含一个 JRootPane,其中包含一个 contentPane,可能会导致绘画过程出现问题。

更好的解决方案是从 JPanel 开始,覆盖它的 paintComponent 方法(首先调用 super.paintComponent)并在那里执行自定义绘制。然后你可以将它添加到你想要的任何容器中

您还应该避免调用任何可能导致使用绘画方法发出重绘请求的方法,这将导致永无止境的重绘循环,这将消耗您的 CPU 周期并带来您的系统崩溃

例如...

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
import javax.swing.JApplet;
import javax.swing.JPanel;
import test.Shapes.TestPane;

public class Shapes extends JApplet {

    @Override
    public void init() {
        super.init();
        add(new TestPane());
    }

    public class TestPane extends JPanel {

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            Random rand = new Random();

            // Declare size constants
            final int circleMax = 160, circleMin = 40; // circle max and min diameter
            final int locMaxX = 360, locMaxY = 260;
            int radiusSize = 0, locationx = 0, locationy = 0;

            // Declare variables
            radiusSize = (rand.nextInt(circleMax) + circleMin);
            locationx = 20;//rand.nextInt(locMaxX)+ 20;
            locationy = 20;// rand.nextInt(locMaxY) + 20;

            // Draw the circle 1
            g2d.drawOval(locationx, locationy, radiusSize, radiusSize);
            g2d.dispose();
        }

    }
}

考虑到几乎所有浏览器都在主动禁用它们以及它们在开发过程中带来的复杂性,我也会质疑现在 JApplet 的使用