新しいコンポーネントがNull Layout Managerに表示されないのはなぜですか?
-
02-10-2019 - |
質問
にパネルがあります JFrame
aと呼ばれます WatchPanel extends JPanel
aを使用します GroupLayout
と含む WatchListPanel extends JPanel
. 。 WatchListPanel
aを使用します null
LayoutManager
のいくつかのインスタンスが含まれています WatchItemPanel extends JPanel
. 。 WatchItemPanel
その内容をaでレイアウトします GridBagLayout
.
フレームをロードしてインスタンス化するとき WatchPanel
, 、私は事前ロードします WatchListPanel
3で WatchItemPanel
データを使用したインスタンス。これらは正常に動作します。私の実装により、これらをドラッグしてドロップすることでこれらを並べ替えることができます(したがって、 null
レイアウト)、それも機能します。に WatchPanel
新しい時計を追加するボタンです。 JFrame
時計を追加できる場所。この新しいパネルに「保存」ボタンが押されたら、新しい時計が追加されます WatchPanel
, 、それを滴下します WatchListPanel
そして閉じます JFrame
新しい時計を追加するため。
問題は、これが新しいときです WatchItemPanel
追加されます、私がサイズを変更しない限り、それは塗装されません JFrame
を含む WatchPanel
. 。 drag-n-dropを介してやり取りすることができます。特定のパネルをドラッグすることもできますが、空白です。私がサイズを変更した瞬間 WatchPanel
, 、それは現れて正しく塗装されています。
今、私はオーバーライドしました setBounds
メソッドオン WatchListPanel
電話する setSize
と repaint
それぞれに WatchItemPanel
リストのインスタンスですが、私は呼んでいます setBounds
と repaint
新しいで WatchItemPanel
私がそれを追加するようにすでに。追加してみました repaint
と invalidate
考えられるあらゆる場所に電話して、私は何かを逃したかもしれないが、運はありません。私は絶対に追加しました WatchItemPanel
に WatchListPanel
と呼ばれました setBounds
, setVisible(true)
, 、 と repaint
新しいパネルに。
ここにあります addWatch
と updatePositions
の方法 WatchListPanel
:
public void addWatch(Watch watch) { WatchItemPanel watchPanel = new WatchItemPanel(watch); synchronized (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(); } private void updatePositions() { int count = 0; synchronized (this.watches) { for (Watch watch: this.watches) { if ((this.selectedWatchPanel != null) && (count == this.selectedWatchPanelPosition)) count++; WatchItemPanel panel = this.watchPanels.get(watch); if (panel == this.selectedWatchPanel) continue; panel.setBounds(0, count * WatchItemPanel.PANEL_HEIGHT, this.getWidth(), WatchItemPanel.PANEL_HEIGHT); count++; } } if (this.selectedWatchPanel != null) this.selectedWatchPanel.setBounds(0, (this.selectedWatchPanelPosition * WatchItemPanel.PANEL_HEIGHT) + this.selectedWatchPanelDragOffset, this.getWidth(), WatchItemPanel.PANEL_HEIGHT); this.repaint(); }
そして、ここにあります setBounds
メソッドオン WatchListPanel
:
@Override public void setBounds(Rectangle r) { super.setBounds(r); for (WatchItemPanel panel: this.watchPanels.values()) { panel.setSize(r.width, WatchItemPanel.PANEL_HEIGHT); panel.repaint(); } } @Override public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); for (WatchItemPanel panel: this.watchPanels.values()) { panel.setSize(width, WatchItemPanel.PANEL_HEIGHT); panel.repaint(); } }
ここでの別の情報 - 4つのパネルすべてが塗装されています。私は覆しました paintComponent
の中に WatchItemPanel
追加しました 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()
パッケージ名が削除された出力。
解決
コンポーネントを追加した後、呼び出します this.revalidate()
. 。これにより、コンテナがコンポーネントを再レイアウトするようにマークされます。このコード行が追加されると、完全に機能します。