2012-08-01 229 views
2

我想添加一個我想你會稱之爲列表中的每個項目的子列表。我已經構建了一個自定義渲染器,它提供了下面的輸出。正如你可以看到有些事情不是在這裏,我沒有運氣追蹤我的問題的答案。我猜我需要在面板的佈局中改變一些東西來獲得正確的結果,但不知道是什麼。Jlist自定義渲染器

http://i.stack.imgur.com/jCKjJ.jpg

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Container; 
import java.awt.GridLayout; 
import java.util.Random; 
import javax.swing.JCheckBox; 
import javax.swing.JLabel; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JSeparator; 
import javax.swing.ListCellRenderer; 
import javax.swing.border.EmptyBorder; 

public class GAListRendererAdv extends Container implements ListCellRenderer { 
private static final long serialVersionUID = 1L; 
private JPanel pnl = new JPanel(); 
private Random rnd = new Random(); 

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, 
     boolean cellHasFocus) { 

    pnl.setLayout(new BorderLayout(0, 0)); 

    JCheckBox chckbxSomething = new JCheckBox("something"); 
    pnl.add(chckbxSomething, BorderLayout.NORTH); 

    JSeparator separator = new JSeparator(); 
    pnl.add(separator, BorderLayout.CENTER); 

    JPanel panel_1 = new JPanel(); 
    panel_1.setBorder(new EmptyBorder(0, 35, 0, 0)); 
    pnl.add(panel_1, BorderLayout.SOUTH); 
    panel_1.setLayout(new GridLayout(0, 1, 0, 0)); 

    int rndNum = rnd.nextInt(5) + 1; 

    for (int i = 0; i < rndNum; i ++) { 
    JLabel lblNewLabel2 = new JLabel("New label"); 
    panel_1.add(lblNewLabel2); 
    } 

    return pnl; 
} 
} 

回答

4

首先,請記住,CellRenderers被用作擺動 「橡皮圖章」。這樣做是爲了節省內存並幫助提高性能。這允許組件像JList一樣維護對渲染器的單個引用,但仍繪製列表中的所有項目。

這意味着,當調用getListCellRendererComponent時,渲染器將處於與上次調用相同的狀態。

從我可以從你的代碼來講,這將意味着,每個渲染器被調用時,添加了另一個複選框,將另一隔離另一個小組和其它更多的標籤...

所有其次,渲染器儘可能不要在getListCellRendererComponent中創建任何內容,這隻會增加內存使用量(部分代碼可能沒有選擇)。

第三,JList不支持編輯器,因爲我之前說過的原因,渲染器不是編輯器。

正。在將所有元素添加到面板之前,嘗試從面板的「正文」部分刪除內容。

// Don't use Container, use JPanel instead, mixing heavy and light weight components 
// is never a good idea :P 
public class GAListRendererAdv extends JPanel implements ListCellRenderer { 
    private static final long serialVersionUID = 1L; 
    private JPanel pnl = new JPanel(); 
    private Random rnd = new Random(); 

    private JCheckBox checkBox; 

    public GAListRendererAdv() { 

     setLayout(new BorderLayout(0, 0));    
     checkBox = new JCheckBox(); 

     add(checkBox, BorderLayout.NORTH); 
     add(new JSeparator(), BorderLayout.CENTER); 

     pnl = new JPanel(new GridLayout(0, 1, 0, 0)); 
     pnl.setBorder(new EmptyBorder(0, 35, 0, 0)); 

     add(pnl BorderLayout.SOUTH); // Don't forget to add the panel :P 

    } 

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 

     pnl.removeAll(); 
     int rndNum = rnd.nextInt(5) + 1; 

     for (int i = 0; i < rndNum; i ++) { 
      JLabel lblNewLabel2 = new JLabel("New label"); 
      pnl.add(lblNewLabel2); 
     } 

     return this; 
    } 
+1

Hi @MadProgrammer。你說:「第三,JList不支持編輯器,渲染器不是編輯器」。所以,這裏是我的問題,那麼你會怎麼做,然後製作一個可編輯的組件列表(或序列)? 具體來說,我通過CellRenderer填充JList中的自定義窗格,但所有funcionallity(如按鈕等)不起作用。 – giorgiline 2012-10-21 21:15:46

+0

簡單的解決方案是實際使用一個單獨的列'JTable'。你可以逃脫不通過覆蓋模型的'getColumnName'方法,並返回一個空字符串 – MadProgrammer 2012-10-21 22:30:17

+0

所以@MadProgrammer,這樣的表必須與特定的實現爲TableCellEditor的設置或我錯了顯示列名?自定義單元格渲染仍然不允許按鈕交互。 也許更好的解決方案是將組件添加到ScrollPane中的LayoutManager中?我不知道如何做到這一點,但我會亂它。 – giorgiline 2012-10-22 10:48:12