2012-11-02 101 views
1

我想爲自定義組合框中的值設置工具提示值。基本上,我的組合框包含一個首字母縮略詞列表 - 當他們懸停在我想讓它顯示該人的全名時。我的組合框基本上是一個JTable的單元/列,它有自己的TableCellRenderer和DefaultCellEditor。該列表是一個JList(模型中的內部類) - iv嘗試直接設置'setToolTipText'方法,但似乎不起作用。在JTable中將JComboBox的Item的值設置爲CellEditor

下面是代碼:

* JTable的內碼:*

public void setupUserCombo(Container container){ 
     TableColumn col = getColumnModel().getColumn(3); 
     Set<ComboUser> values = new LinkedHashSet<ComboUser>(); 

     ComboUser comboUser = new ComboUser(new User("Test User")); 
     values.add(comboUser); 

     col.setCellEditor(new MyComboBoxEditor((ComboUser[])values.toArray(new ComboUser[0]))); 
     col.setCellRenderer(new MyComboBoxRenderer((ComboUser[])values.toArray(new ComboUser[0]))); 
     repaint(); 
} 

public class MyComboBoxRenderer extends JComboBox implements TableCellRenderer { 
    private static final long serialVersionUID = 1L; 

    public MyComboBoxRenderer(ComboUser[] items) { 
     super(items); 
     repaint(); 
    } 

    public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) { 
     if (value != null){ 
      System.out.println("Setting tooltip"); 
      ((ComboUser)value).setToolTipText("TESTING!!"); 
     } 
     setSelectedItem(value); 

     return this; 
    } 
} 

public class MyComboBoxEditor extends DefaultCellEditor { 
    private static final long serialVersionUID = 1L; 

    public MyComboBoxEditor(ComboUser[] items) { 
     super(new JComboBox(items)); 
    } 
} 

*在模型內亞綱:*

public class ComboUser extends JLabel{ 

    private User user; 

    public ComboUser(User user){ 
     if (user != null){ 
      this.user = user; 
     } else { 
      this.user = new User(""); 
     } 
    } 

    @Override 
    public String toString() { 
     return user.getInitials(); 
    } 
+0

一)從未添加過向JSomething數據領域(一comboUser當然不履行是,一到JLabel關係)B)從未實施過任何類只爲爲了查看原因而重寫toString(這就是渲染器的用途)c)如果可以通過配置可用的類來達到相同的目的,則不要繼承子類 – kleopatra

回答

3

如果您想在編輯組合框中使用工具提示,則必須在該組合框的自定義渲染器中進行此操作。下面是一個簡單的例子:

// some data 
User[] users = new User[] { 
     new User("Clara Zetkin", "CZ"), 
     new User("Rosa Luxemburg", "RL"), 
     new User("Susan Sontag", "SS"), 
}; 
// the renderer for use in the editor 
ListCellRenderer comboRenderer = new DefaultListCellRenderer() { 

    @Override 
    public Component getListCellRendererComponent(JList<?> list, 
      Object value, int index, boolean isSelected, 
      boolean cellHasFocus) { 
     if (value instanceof User) { 
      setToolTipText(((User) value).getName()); 
      value = ((User) value).getInitials(); 
     } else { 
      setToolTipText(null); 
     } 
     return super.getListCellRendererComponent(list, value, index, isSelected, 
       cellHasFocus); 
    } 

}; 
JComboBox editingCombo = new JComboBox(users); 
editingCombo.setRenderer(comboRenderer); 

JTable table = new JTable(3, 2); 
// set up the editor for the first column 
table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(editingCombo)); 
// the renderer to use in the table 
TableCellRenderer renderer = new DefaultTableCellRenderer() { 

    @Override 
    protected void setValue(Object value) { 
     if (value instanceof User) { 
      setToolTipText(((User) value).getInitials()); 
      value = ((User) value).getName(); 
     } else { 
      setToolTipText(null); 
     } 
     super.setValue(value); 
    } 

}; 
table.getColumnModel().getColumn(0).setCellRenderer(renderer); 
+0

+1的基本的東西,請爲什麼不'BasicComboBoxRenderer'('Editable' /''Non_Editable' JComboBox') – mKorbel

+0

@mKorbel - 不明白是什麼你的意思是;-)射擊野外:如果你沒有能夠實現你的目標,永遠不要使用平面課程。 – kleopatra

+0

aaach,真的,硬幣的一面有實現的一切,第二個真實的是,這可能是最簡單,最簡單和最簡單的:-) – mKorbel

2

see JTable tutorial,測試代碼的例子,例如

import java.awt.BorderLayout; 
import javax.swing.DefaultCellEditor; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableColumn; 
import java.awt.Component; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import javax.swing.JButton; 
import javax.swing.JComboBox; 
import javax.swing.JList; 
import javax.swing.plaf.basic.BasicComboBoxRenderer; 

public class TableRenderDemo extends JPanel { 

    private static final long serialVersionUID = 1L; 

    public TableRenderDemo() { 
     super(new BorderLayout(5, 5)); 
     final JTable table = new JTable(new MyTableModel()); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     table.setFillsViewportHeight(true); 
     table.setRowHeight(20); 
     JScrollPane scrollPane = new JScrollPane(table); 
     initColumnSizes(table); 
     setUpSportColumn(table, table.getColumnModel().getColumn(2)); 
     add(scrollPane, BorderLayout.CENTER); 
     JButton resetButton = new JButton("Reset to default"); 
     resetButton.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       for (int i = 0; i < table.getRowCount(); i++) { 
        table.getModel().setValueAt("None of the above", i, 2); 
       } 
      } 
     }); 
     add(resetButton, BorderLayout.SOUTH); 
    } 

    private void initColumnSizes(JTable table) { 
     MyTableModel model = (MyTableModel) table.getModel(); 
     TableColumn column = null; 
     Component comp = null; 
     int headerWidth = 0; 
     int cellWidth = 0; 
     Object[] longValues = model.longValues; 
     TableCellRenderer headerRenderer = table.getTableHeader().getDefaultRenderer(); 
     for (int i = 0; i < 5; i++) { 
      column = table.getColumnModel().getColumn(i); 
      comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0); 
      headerWidth = comp.getPreferredSize().width; 
      comp = table.getDefaultRenderer(model.getColumnClass(i)).getTableCellRendererComponent(table, longValues[i], false, false, 0, i); 
      cellWidth = comp.getPreferredSize().width; 
      column.setPreferredWidth(Math.max(headerWidth, cellWidth)); 
     } 
    } 

    private void setUpSportColumn(JTable table, TableColumn sportColumn) { 
     ArrayList<String> listSomeString = new ArrayList<String>(); 
     listSomeString.add("Snowboarding"); 
     listSomeString.add("Rowing"); 
     listSomeString.add("Knitting"); 
     listSomeString.add("Speed reading"); 
     listSomeString.add("Pool"); 
     listSomeString.add("None of the above"); 
     JComboBox comboBox = new JComboBox(); 
     comboBox.addItem(new Item(1, "-")); 
     comboBox.addItem(new Item(2, "Snowboarding")); 
     comboBox.addItem(new Item(3, "Rowing")); 
     comboBox.addItem(new Item(4, "Knitting")); 
     comboBox.addItem(new Item(5, "Speed reading")); 
     comboBox.addItem(new Item(6, "Pool")); 
     comboBox.addItem(new Item(7, "None of the above")); 
     comboBox.setMaximumRowCount(3); 
     comboBox.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) { 
       JComboBox comboBox = (JComboBox) e.getSource(); 
       Item item = (Item) comboBox.getSelectedItem(); 
       System.out.println(item.getId() + " : " + item.getDescription()); 
      } 
     }); 
     //comboBox.setRenderer(new ItemRenderer()); 
     sportColumn.setCellEditor(new DefaultCellEditor(comboBox)); 
     DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); 
     renderer.setToolTipText("Click for combo box"); 
     sportColumn.setCellRenderer(renderer); 
    } 

    class ItemRenderer extends BasicComboBoxRenderer { 

     @Override 
     public Component getListCellRendererComponent(JList list, Object value, 
       int index, boolean isSelected, boolean cellHasFocus) { 
      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
      if (value != null) { 
       Item item = (Item) value; 
       setText(item.getDescription().toUpperCase()); 
      } 
      if (index == -1) { 
       Item item = (Item) value; 
       setText("" + item.getId()); 
      } 
      return this; 
     } 
    } 

    class Item { 

     private int id; 
     private String description; 

     public Item(int id, String description) { 
      this.id = id; 
      this.description = description; 
     } 

     public int getId() { 
      return id; 
     } 

     public String getDescription() { 
      return description; 
     } 

     @Override 
     public String toString() { 
      return description; 
     } 
    } 

    class MyTableModel extends AbstractTableModel { 

     private static final long serialVersionUID = 1L; 
     private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"}; 
     private Object[][] data = {{"Kathy", "Smith", "Snowboarding", new Integer(5), false}, 
      {"John", "Doe", "Rowing", new Integer(3), true}, {"Sue", "Black", "Knitting", new Integer(2), false}, 
      {"Jane", "White", "Speed reading", new Integer(20), true}, {"Joe", "Brown", "Pool", new Integer(10), false}}; 
     public final Object[] longValues = {"Jane", "Kathy", "None of the above", new Integer(20), Boolean.TRUE}; 

     @Override 
     public int getColumnCount() { 
      return columnNames.length; 
     } 

     @Override 
     public int getRowCount() { 
      return data.length; 
     } 

     @Override 
     public String getColumnName(int col) { 
      return columnNames[col]; 
     } 

     @Override 
     public Object getValueAt(int row, int col) { 
      return data[row][col]; 
     } 

     @Override 
     public Class<?> getColumnClass(int c) { 
      return getValueAt(0, c).getClass(); 
     } 

     @Override 
     public boolean isCellEditable(int row, int col) { 
      if (col < 2) { 
       return false; 
      } else { 
       return true; 
      } 
     } 

     @Override 
     public void setValueAt(Object value, int row, int col) { 
      data[row][col] = value; 
      fireTableCellUpdated(row, col); 
      System.out.println("New value of data: " + getValueAt(row, col)); 
     } 
    } 

    private static void createAndShowGUI() { 
     JFrame frame = new JFrame("TableRenderDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     TableRenderDemo newContentPane = new TableRenderDemo(); 
     frame.setContentPane(newContentPane); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
+0

我不確定這是我在尋找什麼 - 這只是設置整個工具提示組合框。我想爲它設置爲每個單元格內的組合框 – maloney

+0

是否意味着JComboBox項目的工具提示(作爲CellEditor在JTable中)或顯示工具提示從渲染器 – mKorbel

+0

我一直試圖從渲染器設置它,但那不工作。基本上,當他們點擊下拉列表它在列表中的一些值 - 當他們將鼠標懸停在應該顯示與該值相關聯的提示。那可能嗎? – maloney