ビデオゲームのコーディングを始めたばかりですが、JPanelですべての描画を行い、そのパネルをJFrameにアタッチする方が、単にJFrameに描画するよりも優れていると聞きました。なぜこれが良いのかと思っていました。
3 に答える
次のようなさまざまな理由で優れています。
- ほとんどのSwingコンポーネントでは、カスタムペイントは
paintComponent(Graphics)
メソッドをオーバーライドすることで実現されます。トップレベルのSwingコンテナ(たとえば、、JFrame
)JApplet
には。JWindow
のみがありpaint(Graphics)
ます。ペイントの一般的な方法の結果として、答える人は、一般的なコンポーネントとトップレベルのコンポーネントのこの違いを忘れることが多いため、ばかげたアドバイスを提案します。;) - 、、、、、、またはのレイアウトの制約に
JComponent
追加することができます。、、、、JFrame
またはJApplet
a .. GUIが完成したと思うと、クライアントは「ねえ、それは素晴らしいことではないだろう」と言います。ツールバーを投入してアプレットとしても提供するには?」アプローチはそれに簡単に適応します。JDialog
JPanel
JInternalFrame
JComponent
- Richanteによって説明されているように(コードで完了!)、カスタムコンポーネントのペイントに必要な座標を計算する方が簡単です。また
JFrame
、適切なサイズがある場合は、GUIを含めるために「正確に正しいサイズ」にサイズ設定する方が簡単です。 (を使用pack()
)。これは、他のコンポーネントも追加される場合に特に当てはまります。
さて、提供されたアドバイスとの2つの小さな意見の相違。
コンポーネント全体がカスタムペイントされている場合は、 /コンボのBufferedImage
内側に配置する方がよい場合があります。これは、画像にペイントする例です。それを更新するときが来たら:ImageIcon
JLabel
- またはを呼び出す
getGraphics()
_Graphics
createGraphics()
Graphics2D
- そのグラフィックスインスタンスにカスタムペイントを描画します
- グラフィックインスタンスを破棄します
repaint()
ラベルを呼び出します。
これは、ダブルバッファリングを行う簡単な方法です。
少し詳しく説明させてください。ビデオゲームでは、再描画によって引き起こされるちらつきを回避し、より滑らかなグラフィックを表示するために、通常、ダブルバッファリングを使用します。オフスクリーンサーフェスを作成し、その上にすべてを描画してから、オフスクリーンサーフェス全体を一度に画面に表示します。
Java2DとSwingでは、これを行う最も簡単な方法は、JPanelでゲームのスプライトを描画してから、JPanelをJFrameに追加することです。
次に、JPanelで描画することにより、ゲームループで手動でペイントしなくても、より多くのGUIウィジェットやその他のグラフィカルオブジェクトをJFrameに表示できるようになります。たとえば、ボタン、メニュー、その他のパネル、さらにはその他のレンダリングJPanelsです。
第三に、それはあなたがあなたのゲームのために自動的に翻訳された座標を使うことを可能にします。ウィンドウの境界線の幅、作業ウィンドウ、タイトルなど、ウィンドウマネージャ固有のことを気にすることなく、左上から右下まですべてを描画できます。
さらに、これはJavaのゲームプログラマーだけが使用する規則ではありません。GUIツールキットなどの内部メインループを備えたライブラリを使用してゲームをプログラミングする場合、個別のゲームボード、レンダリングパネル、またはグラフィックウィジェットを作成することは非常に人気があります。Windowsフォームではユーザーフォームを使用でき、GTK+では製図板を使用できます。
JFrameには、メニュー、タイトルバー、境界線などが含まれます。したがって、座標を参照するときは、これらを考慮する必要があります。メニューバーやその他のコンポーネントをフレームに追加することもできます。絵がすべてJPanelにある場合、これによって座標の参照方法が変わることはありません。
たとえば、次のことを試してください。
public class Test extends JFrame {
public Test() {
super();
setVisible(true);
setBounds(100, 100, 200, 100);
}
@Override
public void paint(Graphics g) {
g.fillRect(0, 0, 50, 50);
}
public static void main(String[] args) {
new Test();
}
}
黒い四角は四角ではないことがわかります!(0、0)はフレーム全体の左上隅であり、表示領域の隅ではないためです。