2

自分でバック バッファーとして実装する必要Imageがありますか、またはバック バッファーをアクティブにするためのコンポーネントまたはオプションが既に作成されていますか?

私の目標は、ウィンドウの移動と非表示/表示時に図面を保持することです...

アップデート

JPanel を使用しようとしたので、バッファがあれば動作するはずですが、失敗しました:

final JPanel panel = new JPanel();

            panel.addMouseListener(new MouseListener() {

                @Override
                public void mouseReleased(MouseEvent e) {
                }

                @Override
                public void mousePressed(MouseEvent e) {
                }

                @Override
                public void mouseExited(MouseEvent e) {
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                }

                @Override
                public void mouseClicked(MouseEvent e) {
                    Graphics2D g2d = (Graphics2D) panel.getGraphics();
                    g2d.drawOval(e.getX()-50, e.getY()-50, 100, 100);
                }
            });

            JFrame frame = new JFrame("JPanel Buffer Test");
            frame.add(panel, BorderLayout.CENTER);
            frame.pack();
            frame.setBounds(100,100, 800, 600);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.setVisible(true);

ここでは、マウス クリックで円が描画されますが、ウィンドウのサイズを変更すると消えます。したがって、明らかにバッファは存在しません。

コンポーネントにバッファがある場合、その上に何かを描画でき、サイズ変更しても保持されます。

JPanelのバッファにアクセスする方法があるかもしれgetGraphicsません。

更新 2

以下は、手動でバッファリングした方法です。私の質問は、図書館ですでに行われていないということです。例では、サイズ変更時にバッファーをリサンプリングしますが、これは必須ではありません。

    private BufferedImage bufferedImage = null;

@Override
protected void paintComponent(Graphics g) {
    if( bufferedImage != null ) {
        g.drawImage(bufferedImage, 0, 0, null);
    }
}

@Override
public void setBounds(int x, int y, int width, int height) {

    if( bufferedImage == null ) {
        bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    }
    else {
        if( bufferedImage.getWidth() != width || bufferedImage.getHeight() != height ) {
            BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

            AffineTransform at = new AffineTransform();
            at.scale((double)width/bufferedImage.getWidth(), (double)height/bufferedImage.getHeight());

            AffineTransformOp scaleOp = 
                   new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

            bufferedImage = scaleOp.filter(bufferedImage, scaledImage);
        }
    }
    super.setBounds(x, y, width, height);
}


public Graphics2D createImageGraphics() {
    if( bufferedImage != null ) {
        return bufferedImage.createGraphics();
    }
    else {
        return null;
    }
}
4

1 に答える 1

2

必要なのは だけでJPanel、デフォルトでは自動的にダブル バッファリングされます(詳細については、こちらを参照)。単純にオーバーライドpaintComponent(..)してそこですべての描画を行い、 のJPanelようなコンテナに を追加することができますJFrame

詳細については、こちらをご覧ください。

の再描画サイクルを完全に制御したい場合もありますJPanel。これは を呼び出すことで実行できますsetIgnoreRepaint(true)

別の方法として、 BufferStrategy と BufferCapabilitiesを確認することもできます (これにより、いくつかの高度な機能が可能になりますがJPanel、オーバーライドpaintComponentされた自動ダブル バッファリングを使用したすべての集中的な目的で同等でありsetIgnoreRepaint(true)、同等です)。これは通常、次のCanvasように実装されます。

BufferStrategy myStrategy;

while (!done) {
    Graphics g = myStrategy.getDrawGraphics();
    render(g);//draw the frame/graphics
    g.dispose();
    myStrategy.show();
}
于 2012-12-05T12:09:50.823 に答える