2010-09-13 57 views
0

JFrame中有一個面板,名爲WatchPanel extends JPanel,它使用GroupLayout幷包含WatchListPanel extends JPanelWatchListPanel使用nullLayoutManager幷包含WatchItemPanel extends JPanel的幾個實例。 WatchItemPanelGridBagLayout列出其內容。爲什麼我的新組件不顯示在空佈局管理器中?

當我加載框架並實例化WatchPanel時,我預加載了WatchListPanel以及三個帶有數據的WatchItemPanel實例。這些工作正常。我的實現允許通過拖放來重新排序(因此null佈局),並且這也適用。在WatchPanel是一個添加新手錶的按鈕,該手錶在其自己的JFrame中彈出一個新的面板,可以添加手錶。當在這個新面板上按下「保存」按鈕時,它會將新手錶添加到WatchPanel,該手錶會慢慢進入WatchListPanel,並關閉JFrame以添加新手錶。

問題是,當添加這個新的WatchItemPanel時,除非我調整包含WatchPanelJFrame的大小,否則它不會被繪製。我可以通過拖放進行交互。我甚至可以拖動特定的面板 - 但它是空白的。當我調整WatchPanel的大小時,它會顯示並正確繪製。現在

,我已經覆蓋了setBounds方法上WatchListPanel來調用每個在列表中的WatchItemPanel實例setSizerepaint,但我對新WatchItemPanel調用setBoundsrepaint已經爲我添加它。我曾嘗試在每個可以想象的地方添加repaintinvalidate來電,因爲我想我可能錯過了一些東西,但沒有運氣。我絕對已將WatchItemPanel添加到WatchListPanel,並在新面板上調用setBoundssetVisible(true)repaint

這裏是addWatchupdatePositions方法對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(); 
    } 
} 

另一條信息在這裏 - 所有四個面板被漆成。我在WatchItemPanel推翻paintComponent並增加了一個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()輸出與包名刪除

回答

0

添加組件後,請致電this.revalidate()。這將導致容器被標記爲重新佈局其組件。一旦添加這行代碼,它完美的作品。