3

静的な背景と移動するオブジェクトを含む前景の2つのレイヤーを持つウィンドウがあります。私の考えは、背景を1回だけ描​​画することです(変更されないため)。そこで、変更パネルを透明にして、静的な背景の上に追加します。このためのコードは次のとおりです。

public static void main(String[] args) {
    JPanel changingPanel = new JPanel() {

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(100, 100, 100, 100);
        }
    };
    changingPanel.setOpaque(false);

    JPanel staticPanel = new JPanel();
    staticPanel.setBackground(Color.BLUE);
    staticPanel.setLayout(new BorderLayout());
    staticPanel.add(changingPanel);

    JFrame frame = new JFrame();
    frame.add(staticPanel);
    frame.setSize(800, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

このコードは私が望む正しい画像を与えてくれますが、塗り直すたびにchangingPanelstaticPanel同様に塗り直されます(これは明らかに静的パネルを一度だけペイントするという考え全体に反します)。誰かが私に何が悪いのか見せてもらえますか?

参考までに、私はjavax.swing.Timerを使用して、変更するパネルを1秒に24回再計算して再描画しています。

4

3 に答える 3

7

透明なコンポーネントを別のコンポーネントの上に再描画すると、下のコンポーネントが「汚れ」たままになり、再描画されます。下のレイヤーを塗り直さないと、その上に画像がにじんでしまいます。

ここで利用できる唯一の最適化は、下位レベルで使用されるイメージを再生成することではありません。上のレイヤーが変更されるたびに、ラスターをグラフィックス バッファーに描画する必要があります。

于 2010-04-23T05:05:10.850 に答える
3

これはまさに絵画のしくみです。Swingは、背景が不透明でない最初のコンポーネントを検索する必要があります。次に、そのコンポーネントと子をペイントして、すべてのペイントが正しく行われていることを確認します。

移動するコンポーネントがある場合でも、SWingはコンポーネントの最後の位置を「クリア」する必要があります。つまり、移動したコンポーネントを再ペイントする前に、少なくとも背景パネルのその領域を再ペイントする必要があります。

ペイントをより効率的にするには、子パネルを不透明にする必要があります。なぜデフォルト設定を変更したのかわかりません。

于 2010-04-23T05:04:43.337 に答える
2

本当に簡単な方法は、jxlayerを使用することです。AbstractLayerUIを実装し、それをコンポーネントに追加します。開始するには、こちらを参照してください。

于 2010-04-23T05:24:24.780 に答える