4

2 つの JPanel を持つアプリケーションを開発しています。最初の JPanel は描画ボードとして使用され、2 番目の JPanel はプロパティ/設定パネルとして使用されます。したがって、ドローイング ボードではアクティブ レンダリングを使用し、2 つ目のボードではパッシブ レンダリングを使用する必要があります。どちらも JFrame に追加されます。

Java でのアクティブ レンダリングについて読んでいましたが、JPanel が createBufferStrategy をサポートしていないことに気付きました。これは、キャンバスを使用する必要があるということですか? キャンバスの問題は、コンテナではないため、コンポーネントを追加できないことです。JFrame バッファリング戦略を使用することもできます (しかし、タイトルのために位置オフセットを修正する必要がありますか?).. JPanel を使用してアクティブにレンダリングすることはできますか?

4

1 に答える 1

1

「パッシブ」Swing コンポーネントとアクティブ アニメーションを組み合わせた例を次に示します。

public static void main ( String[] args )
{
    JFrame frame = new JFrame ();

    JPanel view = new JPanel ( null );
    view.setPreferredSize ( new Dimension ( 500, 500 ) );
    frame.add ( view );

    JButton button1 = new JButton ( "Button 1" );
    button1.setBounds ( 10, 10, 100, 40 );
    button1.setOpaque ( false );
    view.add ( button1 );

    Animator animator = new Animator ();
    animator.setBounds ( 0, 0, 500, 500 );
    view.add ( animator );

    JButton button2 = new JButton ( "Button 2" );
    button2.setBounds ( 390, 450, 100, 40 );
    button2.setOpaque ( false );
    view.add ( button2 );

    frame.setResizable ( false );
    frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
    frame.pack ();
    frame.setLocationRelativeTo ( null );
    frame.setVisible ( true );
}

public static class Animator extends JComponent
{
    private float angle = 0;

    public Animator ()
    {
        super ();
        setOpaque ( false );

        new Timer ( 1000 / 24, new ActionListener ()
        {
            public void actionPerformed ( ActionEvent e )
            {
                angle += 0.2f;
                if ( angle > 360 )
                {
                    angle = 0;
                }

                repaint ();
            }
        } ).start ();

        addMouseListener ( new MouseAdapter ()
        {
            //
        } );
    }

    protected void paintComponent ( Graphics g )
    {
        super.paintComponent ( g );

        Graphics2D g2d = ( Graphics2D ) g;
        g2d.setRenderingHint ( RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON );

        GeneralPath shape = getShape ();

        g2d.setPaint ( Color.BLACK );
        g2d.fill ( shape );
    }

    public boolean contains ( int x, int y )
    {
        return getShape ().contains ( x, y );
    }

    private GeneralPath getShape ()
    {
        GeneralPath gp = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
        gp.append ( new Rectangle2D.Double ( -250, 150, 1000, 200 ), false );

        AffineTransform at = new AffineTransform ();
        at.rotate ( angle * Math.PI / 90, 250, 250 );
        gp.transform ( at );
        return gp;
    }
}

ご覧のとおり、黒く回転した領域は右下のボタンをオーバーレイするだけでなく、ストライプ ボタンの部分でマウス イベントをブロックします。これは、アニメーターの contains() メソッドをオーバーライドしたために発生します。

public boolean contains ( int x, int y )
{
    return getShape ().contains ( x, y );
}

デフォルトでは、コンポーネントは親の境界全体でマウス イベントをキャッチしますが、このメソッドを変更することで、好きなように操作できます。

また、多くの最適化を行うこともできます。たとえば、各再描画後に形状を変数に保存し、「含む」値をチェックするときにそれを返します。

とにかく、これがあなたの質問に少しでも役立つことを願っています...

于 2012-04-20T16:07:21.370 に答える