Java applet多次显示自身

时间:2012-10-31 22:00:45

标签: java swing applet awt

我正在为学校制作一个Java小程序,其功能是随机选择六个数字作为三个坐标的坐标并连接它们以形成一个三角形。它应该只绘制一个三角形并找到“边长”。但是,当我把它放在我的网站上时,它会多次重绘。

我制作了另一个小程序,更简单,只选择4个随机数作为坐标来绘制一条线。同样的问题。

当用户移动屏幕时,似乎会发生重绘问题,例如当我滚动或在Eclipse中调整applet查看器的大小时。我的源代码发布在这里。

我感谢任何帮助!谢谢!

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

@SuppressWarnings("serial")
public class LineApplet extends JApplet {

    /**
     * Create the applet.
     */

    static int width;
    int height;


    public void init() {

          width = getSize().width;
          height = getSize().height;

       }

    public static int[] randomLine() {
        int[] pointArray = new int[4];
        int x;
        for (int i = 0; i < 4; i++) {
            x = ((int)(Math.random()*(width/10-2)))*20+10;
            pointArray[i] = x;
        }
        return pointArray;
    }

    public void paint(Graphics g) {
        g.setColor(Color.blue);
        int[] coords = new int[4];
        coords = randomLine();
        g.drawLine(coords[0], coords[1], coords[2], coords[3]);
        g.drawString(coords[0]/10 + ", " + coords[1]/10, coords[0], coords[1]);
        g.drawString(coords[2]/10 + ", " + coords[3]/10, coords[2], coords[3]);
        int midpointx = (coords[0] + coords[2])/2;
        int midpointy = (coords[1] + coords[3])/2;
        g.drawString(midpointx/10 + ", " + midpointy/10, midpointx, midpointy);
    }
}

3 个答案:

答案 0 :(得分:2)

每次调用paint()时,您都在计算新的坐标。

每次调整applet窗口大小或重新获得焦点时,都会调用

paint()

要修复,你可以制作

int[] coords = new int[4];

一个类成员变量并移动

coords = randomLine();

init()方法,只在初始化时调用一次。

<强>附录:

  • 覆盖super.paint(g);时始终致电paint()

  • 对于使用Swing的自定义绘制,首选方法是扩展JComponent组件,利用使用paintComponent提供的增强绘制功能。

有关详情,请参阅:Performing Custom Painting

答案 1 :(得分:2)

正如Reimues指出的那样,每次重绘小程序时,你都会重新生成你的坐标。

你的paint方法的另一个问题实际上是你不清楚图形上下文的先前状态(这可能是由paint完成的,但你没有尊重它的功能超越它)。

你有两个选择。

  1. 致电super.paint(g)
  2. 致电super.paint(g)并致电Graphics#clearRect(int, int, int, int)Graphics#fillRect(int, int, int, int)
  3. 您也应该很少需要覆盖顶级容器的paint方法。其中一个原因是它们不是双重缓冲,另一个是油漆链复杂且容易破碎......

    您最好使用JPanel(或类似)并覆盖paintComponent方法而不是......

    <强>已更新

    我更新了您的代码以演示问题。

    public class TestBadApplet extends JApplet {
    
        public void init() {
        }
    
        @Override
        public void start() {
    
            final LinePane linePane = new LinePane();
    
            setLayout(new BorderLayout());
            JButton update = new JButton("Update");
            add(linePane);
            add(update, BorderLayout.SOUTH);
    
            update.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    linePane.regenerate();
                }
            });
    
        }
    
        protected class LinePane extends JPanel {
    
            private int[] coords = new int[4];
    
            public void regenerate() {
                coords = randomLine();
                repaint();
            }
    
            public int[] randomLine() {
                int[] pointArray = new int[4];
                int x;
                for (int i = 0; i < 4; i++) {
                    x = ((int) (Math.random() * (Math.min(getWidth(), getHeight()) / 10 - 2))) * 20 + 10;
                    pointArray[i] = x;
                }
                return pointArray;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.blue);
                g.drawLine(coords[0], coords[1], coords[2], coords[3]);
                g.drawString(coords[0] / 10 + ", " + coords[1] / 10, coords[0], coords[1]);
                g.drawString(coords[2] / 10 + ", " + coords[3] / 10, coords[2], coords[3]);
                int midpointx = (coords[0] + coords[2]) / 2;
                int midpointy = (coords[1] + coords[3]) / 2;
                g.drawString(midpointx / 10 + ", " + midpointy / 10, midpointx, midpointy);
            }
        }
    }
    

    使用super.paintComponent

    Good applet

    没有super.paintComponent

    Bad Applet

答案 2 :(得分:0)

每次组件需要重新绘制时,似乎都会调用paint()

paint()方法应该以不产生副作用的方式编写,并且不应该改变applet的内部状态。 paint()必须限于这样做:绘画。