2012-02-23 93 views
5

我正在使用JList爲我的聊天程序保存聊天數據。
它使用自定義列表渲染器來呈現自定義JPanel對象作爲元素類型。
此JPanel包含兩個JLabel(錨定在頂部,名稱和時間)和一個JTextArea(錨定在底部,用於聊天消息)。重新驗證JList - 自定義元素

它看起來像這樣:

a pic1 http://oi44.tinypic.com/20jiix5.jpg

一切都很正常,但我想添加一個隱藏/顯示功能。
使用先前編程的PopupMenu處理程序,當右鍵單擊某個元素時,會彈出對話框。

a pic2 http://oi42.tinypic.com/2m5exxt.jpg

當您單擊隱藏(或顯示,這是一個切換),那麼它應該儘量減少像這樣的元素...

a pic3 http://oi41.tinypic.com/kf3apx.jpg

唯一的問題是...它不不會更新JList單元格大小,因爲您可以看到文本曾經是大的空白區域。
然而,當I型的另一消息......

a pic4 http://oi40.tinypic.com/35jdoo7.jpg

JList的固定單元尺寸完成「隱藏」操作。
我的問題是如何讓JList以編程方式重新驗證/重新繪製/ etc。
不要以爲我沒有試過所有的解決方案明顯...

public void setHidden(boolean hidden) { 
    // this is in the custom JPanel class 
    System.out.println("Initial: " + this.getPreferredSize()); 

    // TextArea is the JTextArea which we set invisible when we want to hide it. 
    TextArea.setVisible(!hidden); // TextArea is a variable btw 
    this.invalidate(); 
    this.validate(); 
    this.repaint(); 

    System.out.println("After: " + this.getPreferredSize()); 
    container.revalidate(); 
} 

/* 
* This is what the above printlns show when you hide, then show the element. 
* 
* Initial: java.awt.Dimension[width=176,height=38] 
* After: java.awt.Dimension[width=176,height=20] 
* Initial: java.awt.Dimension[width=176,height=20] 
* After: java.awt.Dimension[width=176,height=38] 
*/ 

public void revalidate() { 
    // container.revalidate() ^^^ 
    // list is the list containing the chat elements 
    list.invalidate(); 
    list.validate(); 
    list.repaint(); 
} 

自定義JPanel類使用的GroupLayout來渲染組件。
你們有沒有關於如何編程導致JList重新驗證其單元大小的任何知識?
...除了我發佈的方法? :)

解決方案:
方法後,搜索方法和測試他們是否會解決我的問題後,我發現一個隱藏/顯示操作後,執行該代碼會導致細胞的高度(和寬度)進行重新計算和沒有JList的任何不需要的視覺「閃爍」。

list.setFixedCellHeight(0); 
list.setFixedCellWidth(0); 
list.setFixedCellHeight(-1); 
list.setFixedCellWidth(-1); 
+0

請學習java命名約定並堅持到他們 – kleopatra 2012-02-23 09:55:57

+0

我知道java的命名約定,我只是想讓我的swing變量大寫。但我並不總是遵循這一點...... – 2012-02-23 21:38:20

回答

2

這是JTable與在TableModel和可見Chat列兩列(ChatBoolean)作業只,關鍵是通過使用實現RowFilter,你作爲參數設置爲第二列只String "false" (在JTableBooleanObject是在String "true"/"false"返回值可以過濾)

+0

你的語法讓你的答案難以理解。這個JTable將如何修復單元格大小調整?你必須記住我正在使用自定義的單元格渲染器來渲染這個JList。如果沒有它,它將不會顯示它的功能。 – 2012-02-23 21:47:47

+0

@Bradley Odell請閱讀教程[JList](http://docs.oracle.com/javase/tutorial/uiswing/components/list.html)關於模型(有數據存儲)和視圖及其渲染,而不是從來沒有't use invalidate() – mKorbel 2012-02-23 22:18:45

3

沒有看到任何代碼,我只能猜測:最可能的原因是你下的L的腳做皮這是沒有其模型通知其聽衆。該列表的用戶代理將單元格大小緩存在內部,在接收ListEvents時清除。

+0

你認爲我是右鍵單擊並將物理元素隱藏在JList的物理下方嗎?當我「隱藏」元素時發生的所有事情是JTextArea(持有聊天消息)被設置爲不可見。所以當它的可見性發生變化時,我需要JList重新計算它的單元大小。 – 2012-02-23 21:50:46

0

這是JList類的一個非常特殊的缺點。我在清理不相關領域的一些代碼的過程中遇到了這個問題。

對於什麼是值得的,從ListModel中刪除元素,然後再次添加元素將爲JList中的關聯渲染組件生成適當的尺寸。這是一種奇怪的方式去了解它,似乎會導致列表中的行爲方式相同的接受(和首選)解決方案:

list.setFixedCellHeight(0); 
list.setFixedCellWidth(0); 
list.setFixedCellHeight(-1); 
list.setFixedCellWidth(-1); 

我偶然發現了這個問題,因爲我的項目代碼原文調用ListModelremoveAllElements()方法,然後使用addElement()逐個添加所有元素。一切工作都很好,直到我決定重寫程序,以便只要用戶請求JList中顯示組件的尺寸更改時,它就會讓模型獨立。換句話說,沒有必要牽涉到模型,因爲元素沒有被添加或從列表中刪除。不幸的是,在更改渲染器的首選大小後,或revalidate()方法調用JList將導致它正確地佈局其元素。在我的情況下,只調整父組件(一個JFrame)產生了預期的行爲。