0

私はJavaアプレットプログラミングに慣れていないので、これが非常に基本的な質問である場合はすみませんが、私はそれを広範囲にグーグルで検索し、半関連の問題と解決策しか見つけていません。

私はいくつかの幾何学的アルゴリズムの簡単なデモンストレーションを書いています、そして私がそうするときrepaint()、私のグラフィックスプリミティブのいくつかだけがスクリーンにレンダリングされます。アプレットが再描画されるたびに、一見ランダムに見える線と楕円のサブセットがペイントされます。唯一のパターンは、レンダリングされるプリミティブ常に図面の最初からのものであるということです。IE、場合によってはプリミティブ0〜2、場合によっては0〜5、場合によってはバッチ全体を描画します。

私が知る限り、これはダブルバッファリングで解決できる古典的な「ちらつき」ではないことを指摘したいと思います。私の理解では、ちらつきとは、レンダリングが完了する前に、部分的にレンダリングされたアプレットを短時間表示できる場合です。しかし、私の場合、レンダリングが終了しないとredraw()もう一度運が良ければ終了しません。ダブルバッファリングを試しました:

public void update(Graphics g) {
    Graphics offgc;
    Image offscreen = null;
    Dimension d = size();

    // create the offscreen buffer and associated Graphics
    offscreen = createImage(d.width, d.height);
    offgc = offscreen.getGraphics();
    // clear the exposed area
    offgc.setColor(getBackground());
    offgc.fillRect(0, 0, d.width, d.height);
    offgc.setColor(getForeground());
    // do normal redraw
    paint(offgc);
    // transfer offscreen to window
    g.drawImage(offscreen, 0, 0, this);
}

しかし、それはまったく役に立たないようです。それが役に立つなら、ここに何が起こっているかのいくつかの写真があります。これは、次のように表示されるはずです。

満杯

しかし、ほとんどの場合、次のようになります。

部分1

またはこれ:

部分2

前もって感謝します!

4

1 に答える 1

1

これは、実際にはダブル バッファリングが機能する方法ではなく、ペイント プロセスが機能する方法でもありません。

  • オーバーライドしないでくださいupdate
  • paint可能な限りトップ レベルのコンテナー (Applet/JApplet/Frame/JFrame など) をオーバーライドしないでください。
  • レンダリングできる「ペイント」パネル、できれば のようなものを使用しますJPanel。Swing コンポーネントは、ダブル バッファリングのサポートを提供します
  • ダブル バッファは、ペイント サイクルの外でペイントし、必要な場合にのみ更新する必要があります。これにより、不必要にコンテンツを再レンダリングする必要がないため、ペイント プロセス全体が高速になります。
  • バッファを更新するときが来たら、最初に一時バッファにレンダリングします。これにより、更新中に発生する可能性のある再描画が時期尚早に画面に反映されなくなります...

ここに画像の説明を入力

public class TestPaintGeometry {

    public static void main(String[] args) {
        new TestPaintGeometry();
    }

    public TestPaintGeometry() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ShowPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ShowPane extends JPanel {

        private GeometryPane geoPane;

        public ShowPane() {
            setLayout(new BorderLayout());

            geoPane = new GeometryPane();
            JButton redrew = new JButton("Redraw");
            add(geoPane);
            add(redrew, BorderLayout.SOUTH);
            redrew.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    geoPane.redrew();
                }
            });
        }            
    }

    public class GeometryPane extends JPanel {

        private BufferedImage buffer;

        public void redrew() {
            Path2D.Float path = new Path2D.Float();
            int width = getWidth();
            int height = getHeight();

            int points = Math.max(10, (int) Math.round(Math.random() * 100));
            for (int index = 0; index < points; index++) {
                int x = (int) Math.round(Math.random() * width);
                int y = (int) Math.round(Math.random() * height);
                if (index > 0) {
                    path.lineTo(x, y);
                } else {
                    path.moveTo(x, y);
                }
            }

            BufferedImage tmp = createCompatibleImage(width, height);
            Graphics2D g2d = tmp.createGraphics();
            g2d.setColor(Color.BLACK);
            g2d.draw(path);
            g2d.dispose();

            buffer = tmp;
            repaint();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (buffer != null) {
                int x = (getWidth() - buffer.getWidth()) / 2;
                int y = (getHeight() - buffer.getHeight()) / 2;
                g.drawImage(buffer, x, y, this);
            }
        }
    }

    public static GraphicsConfiguration getGraphicsConfiguration() {
        return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    }

    public static BufferedImage createCompatibleImage(int width, int height) {
        return createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    }

    public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
        BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
        image.coerceData(true);
        return image;
    }
}

これにより、継承のレガシーによって制約されないGeometryPaneため、JFrameまたはに展開できます...JAppelt

于 2012-11-03T00:41:39.970 に答える