1

学校用のJavaアプレットを作成しています。このアプレットの機能は、3点の座標に対して6つの数値をランダムに選択し、それらを接続して三角形を作成することです。1つの三角形を描き、「辺の長さ」を見つけることだけを想定しています。ただし、自分のWebサイトに配置すると、何度も再描画されます。

線を引くための座標に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);
    }
}
4

3 に答える 3

2

paint()が呼び出されるたびに、新しい座標を計算しています。

paint()アプレットウィンドウのサイズが変更されるか、フォーカスが回復するたびに呼び出されます。

修正するには、

int[] coords = new int[4];

クラスメンバー変数と移動

coords = randomLine();

メソッドに追加しますinit()。これは、初期化時に1回だけ呼び出されます。

補遺:

  • super.paint(g);オーバーライドするときは常に呼び出しますpaint()

  • Swingを使用したカスタムペイントの場合、推奨されるアプローチは、JComponentを使用して提供される拡張ペイント機能を活用してコンポーネントを拡張することpaintComponentです。

詳細については、「カスタムペイントの実行」を参照してください。

于 2012-10-31T22:15:15.460 に答える
2

Reimues が指摘したように、アプレットが再描画されるたびに座標を再生成しています。

メソッドのもう 1 つの問題paintは、実際にはグラフィックス コンテキストの以前の状態が明確でないことです (これは によって行われpaintますが、オーバーライドしたときにその機能を尊重できませんでした)。

選択肢は 2 つあります。

  1. 電話super.paint(g)
  2. 電話super.paint(g)して電話Graphics#clearRect(int, int, int, int)するか、Graphics#fillRect(int, int, int, int)

paintまた、ごくまれに、最上位コンテナーのメソッドをオーバーライドする必要があります。理由の 1 つは、それらがダブル バッファリングされていないことです。もう 1 つは、ペイント チェーンが複雑で壊れやすいことです...

(またはそのような)を使用して、代わりにメソッド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

良いアプレット

それなしsuper.paintComponent

悪いアプレット

于 2012-10-31T22:25:29.477 に答える
0

問題はpaint()、コンポーネントの再ペイントが必要になるたびに呼び出されることのようです。

paint()メソッドは、副作用を発生させない方法で記述し、アプレットの内部状態を変更しないようにする必要があります。paint()それだけを行うことに制限する必要があります:絵画。

于 2012-10-31T22:15:52.360 に答える