0

Java2Dの基本的な概念を理解するのに苦労しています。
具体的な例を挙げます。
独自のバージョンのメソッドを実装することで、swingコンポーネントをカスタマイズできpaintComponent(Graphics g)
ます。メソッドの本体でグラフィックを使用できます。
質問:
このGraphicsオブジェクトとは正確には何ですか、つまり、メソッドを持つオブジェクトとどのように関連しているのpaintComponentですか?わかりました。次のようなことができることを理解しています。

g.setColor(Color.GRAY);
g.fillOval(0, 0, getWidth(), getHeight());

灰色の楕円形をペイントします。私が理解できないのは、Graphicsオブジェクトがコンポーネントとキャンバスにどのように関連しているかです。この描画は実際にどのように行われますか?
もう一つの例:

public class MyComponent extends JComponent {

     protected void paintComponent(Graphics g) {

                System.out.println("Width:"+getWidth()+", Height:"+getHeight());

            }

    public static void main(String args[]) {

                JFrame f = new JFrame("Some frame");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setSize(200, 90);
                MyComponent  component = new MyComponent  ();
                f.add(component);
                f.setVisible(true);       
          }
 }

このプリント

幅:184、高さ:52

このサイズはどういう意味ですか?サイズ(200,90)のフレームには何も追加していません。

更新:再ペイントを実行するために必要なヒントをオブジェクト
に与えるには、ペイントをオーバーライドする必要があること、およびプラットフォームによって提供されるオブジェクトを作成する必要がないことを理解しています。 その後何が起こるかは私には理解できません。 たとえば、画面を表し、さまざまなメソッドを呼び出し始めるとすぐにオブジェクトが画面にペイントされますか? それはキューに保存され、それぞれの間に1-1の関連付けがありますか?では、フレームワークは各コンポーネントを使用して、一度に1つずつペイントしますか? これはどのように作動しますか?これに関するどんな助けも大歓迎ですGraphics gGraphics

Graphicsg.setXXX
gcomponentg

ありがとう

4

4 に答える 4

2

私がJavaグラフィックスを学んでいたときにしばらく苦労していたので、あなたの問題を理解しています。これはJava2Dグラフィックスだけでなく、AWTの一部です。

JFrameまたはその他のトップレベルオブジェクトを作成すると、「舞台裏」で多くの作業が実行されます。その一部は、Graphicsオブジェクトの作成です。(これについての明示的な通知はありませんが、デバッガーを使用してコードをステップ実行すると、グラフィックを作成するクラスが表示される場合があります)。

次に、最上位オブジェクトに追加または登録するコンポーネントを作成します。これらはすべて、以下を含むコールバックメソッドを実装する必要があります。

paint(Graphics g);

次に、これらのメソッドを@Overrideして、コンポーネントがレンダリングされるときにあなたのペイントメソッドを使用するようにします。

グラフィックを保存したり、新しいグラフィックを作成したりしないでください。それをあなたの責任を取り除くフレームワークと考えてください。

コンポーネントのサイズは、多くの場合、手から取り出されます。レイアウトマネージャーを使用している場合は、コンポーネントのサイズを変更することがあります。

手続き上の命令型のバックグラウンドから来ている場合は、問題が発生する可能性があります(私はFORTRANから来ました)。私のアドバイスは、いくつかのチュートリアルを試してみることです。ある段階で、悟りが訪れ始めます。

Javaグラフィックスの一般的なドキュメントは不十分です。不透明な概念はたくさんあります(Java Graphics.drawImage()のしくみとImageObserverの役割を参照してください)。初期の実装は急いで行われ、多くのバグがありました。今でも、やなどのメソッドを呼び出す必要があるかどうか、またどのような順序で呼び出す必要があるかが不明なことがよくsetPack()ありsetVisible()ます。

これはあなたがそれを使うべきではないという意味ではありません!学習曲線がIMOよりも少し長いというだけです。

詳細:また、何かがいつペイントされるかは決定しませんが、フレームワークは決定します。paint(g)本当に「framweorkはそのコンポーネントを塗り直しています。この段階でこのコンポーネントに何を提供してほしいか」という意味です。

多分providePaintingInstructionsWhenRequiredForComponentGraphics(Graphics g)役に立つ名前でしょう。

同様repaint()に、注文時に再描画しませんが、システムが再描画する必要があると判断した場合。私はそれが役に立つとは思いませんでした。

(たとえば)コンポーネントのサイズをインタラクティブに変更する場合、通常、わずかな変更を行うたびにがトリガーされますpaint(g)。ペイントコードにLOG.debug()を入れて、いつ呼び出されるかを確認してみてください。

于 2011-01-02T10:45:49.337 に答える
2

このサイズはどういう意味ですか?サイズ(200,90)のフレームには何も追加していません。

コンポーネントをフレームに追加し、フレームのサイズを(200、90)に設定しました。フレームのコンテンツペインのデフォルトのレイアウトマネージャーはBorderLayoutです。これは、追加したコンポーネントが使用可能なすべてのスペースを取得することを意味します。フレームにはタイトルバーと境界線用のスペースが必要なため、コンポーネントは残りのスペースを取得します。

于 2011-01-02T16:51:05.030 に答える
1

コンポーネントは、静的なGraphicsオブジェクトの関連付けを作成しません。

グラフィックオブジェクトは、画面などの物理デバイスへのアクセスを提供するプラットフォームハンドルのラッパーです。「ペイント」を実行している間のみ有効で、保存して後で再利用することはできません。「ツールキット」が管理するリソースです。

コンポーネント自体は、ウィンドウシステムの上位にある抽象化であり、レンダリングされるためにこのデバイスにすぐに関連付けられます。

編集

「paint」コールバックからペイントする必要があると感じた場合は、「getGraphics」を呼び出すこのような関連付けを強制できます。これは非常にまれなケースであり、常に後でグラフィックを破棄する必要があります。

于 2011-01-02T11:52:52.063 に答える
1

その瞬間Graphicsの様子を示すために描く一枚の紙のようなものをComponent考えてみてください。描画した後、フレームワークツールキットはエッジをトリミングし、コンポーネントを表示するために描画したものを表示します。さらに、次にコンポーネントを描画するときは、別の紙に描画することになりますので、古いものを残さないでください。Graphics

于 2011-01-02T12:04:50.887 に答える