web-dev-qa-db-ja.com

Swingでキャンバスを作成する方法は?

Javaでペイントエディターを作成しようとしています。このツールバーには、キャンバスに貼り付けたいオブジェクトを含むツールバーがあります。GUIを作成するためにSwingコンポーネントを使用しています。しかし、キャンバスの作成方法を探したところ、AWTのクラスキャンバスしか見つかりませんでした。

Swingでキャンバスに似たものを作成する方法はありますか? (たとえば、JPanel?)AWTのクラスキャンバスを、swingで作成されたGUIで使用すると正しく機能しないことを読みましたが、それは本当ですか?

24
mccrank

Swingでカスタム 'Canvas'を作成するには、通常 JPanel のサブクラスを記述します。次に、JPanelprotected paintComponent(Graphics g)メソッドを上書きする必要があります。

Paintメソッドでは、 Graphics オブジェクトのメソッドを呼び出して、実際にJPanelを描画できます。

いつものように、Javaチュートリアルには 大きな参照 があり、これを使って始めることができます。

45
jjnguy

おそらく JPanel のサブクラスを作成し、パネルに描画したいコンポーネントをペイントする独自の方法を実装する必要があります。

基本的なアプローチは、おそらくMouseListenerのサブクラスに JPanel を割り当ててから、ペイント機能を実装することになるでしょう。

基本的なアイデアは、次のようなものかもしれません。

class MyCanvas extends JPanel implements MouseListener
{
    Image img;      // Contains the image to draw on MyCanvas

    public MyCanvas()
    {
        // Initialize img here.
        this.addMouseListener(this);
    }

    public void paintComponent(Graphics g)
    {
        // Draws the image to the canvas
        g.drawImage(img, 0, 0, null);
    }

    public void mouseClicked(MouseEvent e)
    {
        int x = e.getX();
        int y = e.getY();

        Graphics g = img.getGraphics();
        g.fillOval(x, y, 3, 3);
        g.dispose();
    }

    // ... other MouseListener methods ... //
}

上記の例は不完全です(テストされていません-コンパイルされません)が、ユーザーがクリックして円を描くことができるMyCanvasクラスを実装する方法についてのアイデアを提供します。

imgオブジェクトは、キャンバスのイメージを保持するために使用されます。 paintComponentメソッドは、imgオブジェクトをキャンバスにペイントするために使用されます。 mouseClickedメソッドでは、Graphicsに関連付けられているimgオブジェクトが画像にfillOvalを取得するために取得されます。

キャンバスに画像を貼り付けることが要件の1つであるため、キャンバスに貼り付けたいImagesをいくつか保持しておくことをお勧めします。おそらく次のようなものがあります:

Image[] myImages;    // Used to store images to Paint to screen.

次に、imgに格納されているMyCanvasに画像をペイントするルーチンで、

g.drawImage(myImage[INDEX_OF_DESIRED_IMAGE], 0, 0, null);

drawImage オブジェクトの Graphics メソッドを使用すると、他のImagesをImagesに描画できます。


AWTとSwingに関する質問については、そうです。AWTとSwingのコンポーネントをGUIコンポーネントのレンダリング方法が異なるため、混在させたくないのは事実です。 AWTは重量コンポーネントに基づいています。つまり、GUIを描画するためのネイティブウィンドウ処理です。一方、Swingは軽量コンポーネントに基づいており、GUIはネイティブコンポーネントを使用せずにJava自体によって描画されます。

AWTとSwingの違いに関する優れたガイドは、Sunの AWTとSwingでのペイント の記事に記載されています。

16
coobird

単にJComponentをサブクラス化します。

JPanelは不適切なクラスです。 setOpaque(true)が自動的に呼び出されたように見えるため、多くの場合、推奨されます。それを行うのは実際にはPL&Fであり、それが実際に行われるかどうかは実装とベンダーに依存します。

Canvasは重量コンポーネントです。つまり、基盤となるウィンドウシステムによって制御されます。その結果、通常はZオーダーやクリッピングに関係なく、Swingコンポーネントの上に描画されます(スクロールペインに配置すると、奇妙な動作になります)。

13

Minueto APIを確認することをお勧めします。グラフィックAPIを使用するのは非常に簡単で、Javaイベントをリスニングして、描画機能を提供することができます。

http://minueto.cs.mcgill.ca/

2
Coyote