3

したがって、この質問には 2 つの部分があり、関連していると思われますが、ほとんどが抽象的です。簡単に言えば、ここで私がやっていることは次のとおりです。

私はそれにJFrameJPanelchild JPanelsそれぞれに 3JButtonsを持っています。また、JPanels とボタンをペイントできるようにする (ie ) のJComponent呼び出しも作成しました。glassPanelJFramemyJFrame.setGlassPane(glassPanel)

(1) 基本的に の 3 つのボタンすべてをクリックすることによってトリガーされJPanelglassPanelが に設定されVisibleます (これは を呼び出すように見えますpaintComponent())。これは最初の質問に関連しています。

(2) では、ダブル バッファpaintComponent()を使用して、長方形と画像を に描画してペイントします。これは2番目の質問に関連しています。glassPanel

関連する GlassPanel クラス コードは次のとおりです (これは今のところ抽象的な質問であるため、SSCCE ではありません)。

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JComponent;


public class GlassPanel extends JComponent {

     @Override
     protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        setDoubleBuffered(true);
        Graphics2D g2 = (Graphics2D) g;

        g2.drawRect(x,y,width,height);
        g2.fillRect(x,y,width,height);

        g2.drawImage(img, x, y, this);
    }
}

System.out.printpaintComponent() メソッド内にステートメントを配置することで、それが継続的に呼び出され、非同期にも呼び出されていることがわかりました。呼び出しがどのように行われると思うかについては、(1) を参照してください。また、コードのどこにも呼び出しがないことを絶対に確信しているとしましょうrepaint()(何度も何度もチェックしました)。これが最初の質問の基本です。

初めて3つのボタンをクリックすると、すべてスムーズに進みます。四角形と画像は両方ともすぐに描画されます。ただし、次の 3 つのボタンをクリックすると (この時点でglassPanelsetVisible(true)、最初の四角形と画像はまだ画面上にあり、最初の 3 つのボタンの上にペイントされています)、2 番目の四角形と画像は部分的にしか読み込まれませんJFrameプログラムを実行したEclipseウィンドウから離れてクリックすると、呼び出しの数がpaintComponent()毎回同じ量だけ急速に増加し、部分的にロードされた画像と長方形がすぐに完全に表示されますバックグラウンドでJFrame。クリックして JFrame に戻ると、呼び出しの数が再び正確に増加します)。これが 2 番目の質問の基本です。

更新:ここに私が読んだものがあります:

また、GUI が別のウィンドウで覆われ、その後覆われなくなった場合、ペイント システムは、新たに覆われた領域と等しいペイント領域で paintComponent メソッドを呼び出します。

私の質問は次のとおりです。

(1) がpaintComponent()なしで呼び出されるのはなぜrepaint()ですか? または、同様の質問で、paintComponent() を呼び出しているのは何ですか?

更新: 少し計算した後、すべてのコンポーネント (すべてのボタンとパネル) によって継続的に呼び出されていると強く信じています。それでも、repaint() の呼び出しはありません...

(2) JFrame ウィンドウからフォーカスを移すまで、画像が部分的に読み込まれるのはなぜですか?

私は多くのことを試したことに注意してください:(a)独自のdoubleBufferを作成し、ダブルバッファを使用しない(主にアニメーション用であることはわかっています)、(b)オーバーライドしてオーバーライドしないpaintComponent()、(c)画像を描画して描画しない(長方形はまだ読み込みに時間がかかる)、(d) がないことを完全に確認するrepaint()、(e) を使用する場合と使用しない場合SwingUtilities.invokeLater(new Runnable() { public void run() { //stuff});、(f) ifsetVisible(true) を 1 回だけ実行するステートメントを実行する。

必要に応じて SSCCE を試してみることもできますが、これらはより抽象的なものだと思います。ありがとう!

4

1 に答える 1

1

さて、私は両方の質問に答えたと思います。まず、paintComponent() が連続して呼び出された理由は、実際には連続して呼び出されていなかったからです。最初に GUI を表示したときに、すべてのコンポーネントによって呼び出されていました。Eclipse ウィンドウがそれを覆い隠してから明らかにすると、より多くの回数が呼び出されます。

第二に、それはオブジェクト/事物と関係clipBoundsがあります。ペイント呼び出しごとGraphics2Dに がどのように変化するかがわかったので、メソッドの開始時にクリップを設定すると、画像がすぐに表示されます。(ところで、それは素晴らしいですね!)。clipBoundspaintComponent()

ひねりを加えると、画像が表示された後、ボタンをクリックするたびに画像に対して何かが行われます。しかし、私は正確に何を理解していません。古い画像の上に同じ画像を再描画しているように見えます。

したがって、古い画像を保持する方法を理解する必要がありますが、必要に応じて新しい画像を描画し、新しい画像のみを に描画/追加しglassPanelます。

更新:repaint()各ボタンがクリックされた直後に呼び出すと、少し役立ちます。ただし、ボタンを押すと、別のレイヤーを追加するかのように画像がちらつき、ユーザーが離すと通常に戻ります。

于 2013-07-11T09:21:51.730 に答える