首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java小程序多次显示自身

Java小程序多次显示自身
EN

Stack Overflow用户
提问于 2012-11-01 06:00:45
回答 3查看 575关注 0票数 1

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

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

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

感谢大家的帮助!谢谢!

代码语言:javascript
复制
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);
    }
}
EN

回答 3

Stack Overflow用户

发布于 2012-11-01 06:15:15

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

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

要修复此问题,您可以使

代码语言:javascript
复制
int[] coords = new int[4];

类成员变量并移动

代码语言:javascript
复制
coords = randomLine();

添加到init()方法中,该方法只会在初始化时调用一次。

附录:

  • 在重写paint()时始终调用super.paint(g);
  • 对于使用Swing的自定义绘画,首选的方法是利用paintComponent提供的增强的绘画功能来扩展JComponent组件。

有关详细信息,请参阅:Performing Custom Painting

票数 2
EN

Stack Overflow用户

发布于 2012-11-01 06:25:29

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

paint方法的另一个问题是,您实际上不清楚图形上下文的先前状态(这将由paint完成,但是当您覆盖它时,您没有考虑到它的功能)。

你有两个选择。

  1. 调用super.paint(g)
  2. call super.paint(g)并调用Graphics#clearRect(int, int, int, int)Graphics#fillRect(int, int, int, int)

您还应该在极少数情况下需要覆盖顶级容器的paint方法。其中一个原因是它们没有双缓冲,另一个原因是油漆链很复杂,很容易断裂……

您最好使用JPanel (或类似方法)并覆盖paintComponent方法……

已更新

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

代码语言:javascript
复制
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

不使用super.paintComponent

票数 2
EN

Stack Overflow用户

发布于 2012-11-01 06:15:52

问题似乎是每次组件需要重绘时都会调用paint()

paint()方法应该以不产生副作用的方式编写,并且它们不应该改变小程序的内部状态。必须限制paint()只做这件事:绘画。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13168078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档