16

thisthis、およびthis投稿 (問題の GUI のコードについては、最後の投稿を参照)からいくつかの興味深いアイデアと批判を得ました。それにもかかわらず、私はまだいくつかのことについてかなり混乱しています. 主に、ユーザー紹介グラフィックを表示する最も安価な方法は何ですか?

より具体的には、メソッド内でこのクラスのオブジェクトをメソッド (およびそれに応じて)と一緒に作成することにより、クラスpaintComponent()からメソッドを使用しました。JPanelMouseDragged()paintComponent(getGraphics())AuxClass2AuxClass1

どうやら、getGraphics()andpaintComponent()の代わりに使用するのrepaint()は悪い考えであり、メモリの使用に関係があると思われます。AuxClass2また、ユーザーがマウスをドラッグするたびにを呼び出すのも悪い考えです。

また、JPanel と Canvas (つまり、swing と awt) は少し混乱します。いつ、何を使用しますか?

回避策を見つけようとしましたが、特にgetGraphics()方法については見つかりませんでした。他にどのようにグラフィックをパネルに追加できますか?

4

3 に答える 3

23

重い vs 軽い

基本的に、重量コンポーネントは独自のネイティブ ピアにリンクされ、軽量コンポーネントは共通のネイティブ ピアを共有します。

一般に、z オーダーに問題があるため、重いコンポーネントと軽いコンポーネントを混在させることはお勧めできません。また、私の経験では (現在は改善されているはずですが) 描画の問題が発生する可能性があります。

Canvasこれが、おそらく軽量コンポーネントに配置しようとしていたため、クラスの使用を思いとどまらせた理由です...私は推測します

コントロールの錯覚

Swing APIの初心者にとって最大の問題の 1 つは、描画プロセスを何らかの形で制御できるのに、制御できないという幻想です。受け入れるだけなら簡単です。

あなたができる最善の方法は、再描画マネージャーにできるだけ早い時期に更新を実行するよう依頼することです。

また、呼び出しgetGraphicsが null 以外の値を返すことは保証されていません。

物事の正しい順序

paintpaintComponent

ここでの問題paintは、多くの重要な仕事をしていることです。呼び出しpaintComponentはその 1 つにすぎません。

SwingpaintComponentでは、カスタム ペイントを実行したいときはいつでも使用することを強くお勧めします。これは通常、コンポーネントの最下位レベルであり、子コンポーネントがペイントされる前に呼び出されます。

オーバーライドして呼び出し後にpaintペイントすると、すべての上にペイントされることになります。これは必ずしも望ましい結果ではありません。Graphicssuper.paint

たとえそうであったとしても、子コンポーネントは親コンテナーとは独立してペイントでき、追加したペイント効果を「上書き」することができます。

便利なリンク

別れの思い

ネイティブ ピアにアタッチされているコンポーネントに実際に追加されたコンポーネントのみが、paintメソッドが呼び出されます。したがって、コンテナにまだ追加されていないコンポーネントにペイントしようとするのは、かなり無意味です...

于 2012-08-29T10:24:44.403 に答える
11

..絵筆型GUI..

BufferedImageを塗装面として使用します。で表示しJLabelます。ラベルを の内側のパネルの中央に置きJScrollPaneます。

必要に応じて呼び出しbufferedImage.getGraphics()ますが、完了したら忘れずに呼び出してからdispose()、 を呼び出しますlabel.repaint()

全体を通して Swing コンポーネントを使用し、何もオーバーライドしないでください。

これは、画像を塗装面として使用する例です

そして、これはより良いものです!

スクリーンショットの方が優れているとは言いませんが、優れているのはコードです。;)

于 2012-08-29T11:15:50.423 に答える
6

回避策を見つけようとしましたが、特にgetGraphics()メソッドの場合は見つかりませんでした。他にどのようにしてグラフィックをパネルに追加できますか?

変数としてペイントする必要があるものを覚えており、それをpaintComponent()で使用します。たとえば、他の質問でやろうとしているように見えることは、次のようになります。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PaintRectangle extends JPanel {

    private Point mouseLocation;

    public PaintRectangle() {
        setPreferredSize(new Dimension(500, 500));

        MouseAdapter listener = new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                updateMouseRectangle(e);
            }

            private void updateMouseRectangle(MouseEvent e) {
                mouseLocation = e.getPoint();
                repaint();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                updateMouseRectangle(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                mouseLocation = null;
                repaint();
            }
        };
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }

    private Rectangle getRectangle() {
        if(mouseLocation != null) {
            return new Rectangle(mouseLocation.x - 5, mouseLocation.y - 5, 10, 10);
        }
        else {
            return null;
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Rectangle rectangle = getRectangle();
        if(rectangle != null) {
            Graphics2D gg = (Graphics2D) g;
            gg.setColor(Color.BLUE);
            gg.fill(rectangle);
            gg.setColor(Color.BLACK);
            gg.draw(rectangle);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(new PaintRectangle());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

http://docs.oracle.com/javase/tutorial/uiswing/painting/も参照してください。

于 2012-08-29T10:36:59.883 に答える