1

Javaで学校のプロジェクトを作成しています。何をしようとしているのか: GUI の一部として JScrollPane があり、JLayeredPane (「MapPane」としましょう) が含まれています。MapPane には国の地図 (下部) が含まれており、これはアイコン付きの JLabel です。これはうまく機能し、MapPane はスクロール可能で、すべて問題ありません。

ここで、クラス SpatialElement を拡張するカスタム グラフィック要素をさらに追加します。

すべての要素はクラス SpatialElement を拡張します (簡略化):

public abstract class SpatialElement extends JComponent{
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        // ...
        // ...
        paintElement(g2d);
    }

    public abstract void paintElement(Graphics2D g2d);
}

たとえば、要素 Polygon は (簡略化して) 次のようになります。

public class Polygon extends SpatialElement{  // SpatialElement extends JComponent

    ...

    @Override
    public void paintElement(Graphics2D g2d) {

        // set color, stroke etc.
        // ...
        // prepare an array of coordinates and size (as required in drawPolygon method)

        // draw fill
        g2d.fillPolygon(x, y, size);

        // draw polygon
        g2d.drawPolygon(x, y, size);
    }
}

したがって、ユーザーが新しいグラフィック要素を追加すると、メソッドaddSpatialElementが呼び出されます ( 内MapPane):

public class MapPane extends JLayeredPane implements MouseWheelListener, MouseInputListener, Observer{

 //...

     public void addSpatialElement(SpatialElement element) {
         element.updateBounds(); // set bounds of newly created element
         spatialElements.add(element); // local storage of created elements

         add(element, JLayeredPane.DRAG_LAYER + getComponentCount()); // put the element into another (higher) layer
         validate();
         // ???
    }
}

コードがシンプルで十分に説明的であることを願っています。問題は、新しく作成されたコンポーネントが MapPane (拡張された JLayeredPane) に追加されても、要素が描画されないことです。最初に、間違った境界 (updateBounds メソッドで計算) が原因であると考えましたが、問題ありません。

MapPane に追加した後に直接呼び出すとelement.repaintComponent(getGraphics())、要素が描画されますが、MapPane とのやり取り (ウィンドウのサイズ変更など) の後、MapPane が再描画されるため、オブジェクトは再描画されません。

サイズ変更時に MapPane に含まれているすべてのコンポーネントを強制的に再描画する方法は? MapPane のデフォルトの paintComponent メソッドをオーバーライドする必要がありますか (そのため、オブジェクトを繰り返し処理し、それぞれに対して repaintComponent() を呼び出します)。

または、それを行う方法がそれほどトリッキーではない、より良い解決策がありますか?

アドバイスありがとうございます。

4

0 に答える 0