0

を使用し、を含む a とJFrame呼ばれるパネルがあります。はを使用し、 のインスタンスをいくつか含んでいます。は、その内容を でレイアウトします。WatchPanel extends JPanelGroupLayoutWatchListPanel extends JPanelWatchListPanelnull LayoutManagerWatchItemPanel extends JPanelWatchItemPanelGridBagLayout

フレームをロードして をインスタンス化するとき、データを含む3 つのインスタンスをWatchPanelプリロードします。これらは正常に動作します。私の実装では、これらをドラッグ アンド ドロップ (したがってレイアウト) で並べ替えることができ、それも同様に機能します。には、新しいウォッチを追加するためのボタンがあります。これにより、ウォッチを追加できる独自の新しいパネルがポップアップします。この新しいパネルで [保存] ボタンを押すと、新しいウォッチが に追加されます。新しいウォッチを追加するために、 にトリクル ダウンしてを閉じます。WatchListPanelWatchItemPanelnullWatchPanelJFrameWatchPanelWatchListPanelJFrame

問題は、この新しいWatchItemPanelものが追加されたときにJFrameWatchPanel. ドラッグアンドドロップで操作できます。その特定のパネルをドラッグすることもできますが、空白です。のサイズを変更するWatchPanelと、表示され、正しくペイントされます。

ここで、setBoundsメソッドWatchListPanelを呼び出しsetSizeてリスト内のrepaintWatchItemPanelインスタンスでオーバーライドしましたが、新しいものを追加すると、既にsetBounds呼び出しています。考えられるすべての場所に追加して電話をかけようとしましたが、何かを逃したのではないかと考えましたが、うまくいきませんでした。私は絶対に を に追加し、、、 を新しいパネルに呼び出しました。repaintWatchItemPanelrepaintinvalidateWatchItemPanelWatchListPanelsetBoundssetVisible(true)repaint

addWatchおよびupdatePositionsメソッドは次のWatchListPanelとおりです。

public void addWatch(ウォッチウォッチ) {
    WatchItemPanel watchPanel = new WatchItemPanel(watch);
    同期 (this.watches) {
        this.watches.add(watch);
    }
    this.watchPanels.put(watch, watchPanel);
    this.add(watchPanel);
    watchPanel.setOpaque(false);
    watchPanel.setForeground(this.getForeground());
    watchPanel.setBackground(this.getBackground());
    watchPanel.setVisible(true);
    watchPanel.setSize(this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    for (MouseListener l: this.mouseListeners)
        watchPanel.addMouseListener(l);
    for (MouseMotionListener l: this.mouseMotionListeners)
        watchPanel.addMouseMotionListener(l);
    this.updatePositions();
}

プライベート ボイド updatePositions() {
    int カウント = 0;
    同期 (this.watches) {
        for (ウォッチウォッチ: this.watches) {
            if ((this.selectedWatchPanel != null) && (count == this.selectedWatchPanelPosition))
                カウント++;
            WatchItemPanel パネル = this.watchPanels.get(watch);
            if (パネル == this.selectedWatchPanel)
                継続する;
            panel.setBounds(0, count * WatchItemPanel.PANEL_HEIGHT, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
            カウント++;
        }
    }
    if (this.selectedWatchPanel != null)
        this.selectedWatchPanel.setBounds(0, (this.selectedWatchPanelPosition * WatchItemPanel.PANEL_HEIGHT) + this.selectedWatchPanelDragOffset, this.getWidth(), WatchItemPanel.PANEL_HEIGHT);
    this.repaint();
}

そして、ここにsetBoundsメソッドがありますWatchListPanel

@オーバーライド
public void setBounds(Rectangle r) {
    super.setBounds(r);
    for (WatchItemPanel パネル: this.watchPanels.values()) {
        panel.setSize(r.width, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

@オーバーライド
public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x、y、幅、高さ);
    for (WatchItemPanel パネル: this.watchPanels.values()) {
        panel.setSize(幅, WatchItemPanel.PANEL_HEIGHT);
        panel.repaint();
    }
}

ここで別の情報 - 4 つのパネルすべてが塗装されています。を上書きpaintComponentしてWatchItemPanela を追加したところ、次のSystem.out.println結果が得られました。

WatchItemPanel[,0,66,366x22,invalid,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,44,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,22,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]
WatchItemPanel[,0,0,366x22,layout=java.awt.GridBagLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777219,maximumSize=,minimumSize=,preferredSize=]

パネルにある余分な「無効な」列は何ですか? サイズを変更するとWatchPanel、「無効」が消えます。ただし、余分な列のように見えます。他の行には、対応する無効でない値はありません。JPanel.toString()(これは、パッケージ名が削除されたデフォルトの出力です。

4

1 に答える 1

0

コンポーネントを追加した後、を呼び出しますthis.revalidate()。これにより、コンテナにそのコンポーネントを再レイアウトするようにマークが付けられます。このコード行を追加すると、完全に機能します。

于 2010-09-13T15:39:00.473 に答える