Java小程序多次显示自己

Java小程序多次显示自己,java,swing,applet,awt,Java,Swing,Applet,Awt,我正在为学校制作一个Java小程序,其功能是随机选择六个数字作为三个点的坐标,并将它们连接成一个三角形。它只需要画一个三角形,然后求出“边的长度”。然而,当我把它放在我的网站上时,它会多次重画自己 我制作了另一个更简单的小程序,它只选择4个随机数作为坐标来画一条线。同样的问题 重画问题似乎发生在用户移动屏幕时,例如在Eclipse中滚动或调整小程序查看器大小时。我的源代码发布在这里 谢谢你的帮助!谢谢 import javax.swing.JApplet; import java.awt.*;

我正在为学校制作一个Java小程序,其功能是随机选择六个数字作为三个点的坐标,并将它们连接成一个三角形。它只需要画一个三角形,然后求出“边的长度”。然而,当我把它放在我的网站上时,它会多次重画自己

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

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

谢谢你的帮助!谢谢

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);
    }
}
import javax.swing.JApplet;
导入java.awt.*;
@抑制警告(“串行”)
公共类LineApplet扩展了JApplet{
/**
*创建小程序。
*/
静态整数宽度;
内部高度;
公共void init(){
宽度=getSize().width;
高度=getSize()。高度;
}
公共静态int[]randomLine(){
int[]pointArray=新的int[4];
int x;
对于(int i=0;i<4;i++){
x=((int)(Math.random()*(width/10-2))*20+10;
点阵列[i]=x;
}
返回点数组;
}
公共空间涂料(图g){
g、 setColor(Color.blue);
int[]坐标=新的int[4];
coords=randomLine();
g、 抽绳(坐标[0]、坐标[1]、坐标[2]、坐标[3]);
g、 抽绳(坐标[0]/10+”,“+coords[1]/10,坐标[0],坐标[1]);
g、 拉丝(coords[2]/10+”,“+coords[3]/10,coords[2],coords[3]);
int midpointx=(坐标[0]+coords[2])/2;
int midpointy=(坐标[1]+coords[3])/2;
g、 抽绳(中点X/10+”,“+中点Y/10,中点X,中点Y);
}
}

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

每次调整小程序窗口的大小或重新聚焦时,都会调用
paint()

要解决这个问题,你可以

int[] coords = new int[4];
类成员变量和move

coords = randomLine();
到您的
init()
方法,该方法仅在初始化时调用一次

附录:

  • 始终调用
    super.paint(g)重写
    paint()

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


有关详细信息,请参见:。

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

每次调整小程序窗口的大小或重新聚焦时,都会调用
paint()

要解决这个问题,你可以

int[] coords = new int[4];
类成员变量和move

coords = randomLine();
到您的
init()
方法,该方法仅在初始化时调用一次

附录:

  • 始终调用
    super.paint(g)重写
    paint()

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


有关更多信息,请参阅:。

问题似乎在于每次组件需要重新喷漆时都会调用该函数


paint()
方法的编写方式不应产生副作用,也不应更改小程序的内部状态
paint()
必须仅限于执行以下操作:绘制。

问题似乎在于每次组件需要重新绘制时都会调用此函数


paint()
方法的编写方式不应产生副作用,也不应更改小程序的内部状态
paint()
必须仅限于执行以下操作:绘制。

正如Reimues所指出的,每次重新绘制小程序时,您都会重新生成坐标

paint
方法的另一个问题实际上是您没有清除图形上下文的先前状态(这本可以由
paint
完成,但您在重写它时没有尊重它的功能)

你有两个选择

  • 呼叫super.paint(g)
  • 调用super.paint(g)并调用或
  • 您还应该很少需要重写顶级容器的
    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);
            }
        }
    }
    
    公共类TestBadApplet扩展了JApplet{
    公共void init(){
    }
    @凌驾
    公开作废开始(){
    最终LinePane LinePane=新建LinePane();
    setLayout(新的BorderLayout());
    JButton update=新JButton(“更新”);
    添加(行窗格);
    添加(更新,BorderLayout.SOUTH);
    update.addActionListener(新ActionListener(){
    @凌驾
    已执行的公共无效操作(操作事件e){
    linePane.regenate();
    }
    });
    }
    受保护类LinePane扩展了JPanel{
    私有int[]坐标=新int[4];
    公共无效重新生成(){
    coords=randomLine();
    重新油漆();
    }
    公共int[]随机行(){
    int[]pointArray=新的int[4];
    int x;
    对于(int i=0;i<4;i++){
    x=((int)(Math.random()*(Math.min(getWidth(),getHeight())/10-2))*20+10;
    点阵列[i]=x;
    }
    返回点数组;
    }
    @凌驾
    受保护组件(图形g){
    超级组件(g);