2014-12-14 5 views
0

Я хочу только правильно реализовать шестой столбец моей Jtable с помощью JComboBox. Когда я нажимаю на поле, появляется всплывающее окно, но без щелчка у меня есть ссылка JComponent как String. Я определил собственный tableModel и tableCellrenderer.Как правильно реализовать JComboBox в JTable?

вот мой код:

package examples; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.util.EventObject; 

import javax.swing.DefaultCellEditor; 
import javax.swing.JCheckBox; 
import javax.swing.JComboBox; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.ListSelectionModel; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.CellEditorListener; 
import javax.swing.event.TableModelListener; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.TableCellEditor; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableModel; 

public class MyTableExample2 { 
    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 

       try { 
        UIManager.setLookAndFeel(UIManager 
          .getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException 
         | IllegalAccessException 
         | UnsupportedLookAndFeelException e) { 
        e.printStackTrace(); 
       } 

       @SuppressWarnings("unused") 
       JFrame frame = new MyFrame(); 
      } 
     }); 

    } 
} 

class MyFrame extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JComboBox<String> comboBox = new JComboBox<String>(new String[] { 
      "Me", "You", "They" }); 
    private String[] columnNames = { "First Name", "Last Name", "Sport", 
      "# of Years", "Vegetarian", "ComboBox" }; 
    private Object[][] data = { 
      { "Kathy", "Smith", "Snowboarding", new Integer(5), 
        new Boolean(true), comboBox }, 
      { "John", "Doe", "Rowing", new Integer(3), new Boolean(true), 
        comboBox }, 
      { "Sue", "Black", "Knitting", new Integer(2), new Boolean(false), 
        comboBox }, 
      { "Jane", "White", "Speed reading", new Integer(20), 
        new Boolean(true), comboBox }, 
      { "Joe", "Brown", "Pool", new Integer(10), new Boolean(false), 
        comboBox } }; 

    private JTable jTable = new JTable(new MyTableModel()); 
    private JScrollPane scrollPane = new JScrollPane(jTable); 
    private Font font = getContentPane().getFont().deriveFont(Font.BOLD, 15); 

    private class MyTableCellRenderer extends JLabel implements 
      TableCellRenderer { 

     private static final long serialVersionUID = 1L; 

     public MyTableCellRenderer() { 
      setOpaque(true); 
      setLayout(new BorderLayout()); 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, 
       Object value, boolean isSelected, boolean hasFocus, int row, 
       int column) { 
      Font font = getFont().deriveFont(Font.BOLD, 15); 
      table.setRowHeight((int) getPreferredSize().getHeight() + 5); 

      if ((row % 2) == 0) { 
       setBackground(new Color(224, 255, 255)); 
      } else { 
       setBackground(new Color(135, 206, 250)); 
      } 

      if (isSelected) { 
       setBackground(new Color(0, 0, 255)); 
      } 

      setForeground(Color.BLACK); 
      setText(value.toString()); 
      setFont(font); 

      return this; 
     } 

    } 

    private TableCellRenderer tableCellRend = new MyTableCellRenderer(); 

    public MyFrame() { 
     super("JTable"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     jTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 

     jTable.setColumnSelectionAllowed(false); 
     jTable.setRowSelectionAllowed(true); 
     jTable.setFillsViewportHeight(true); 
     jTable.setFont(font); 
     jTable.setRowHeight(20); 
     jTable.setGridColor(new Color(100, 149, 237)); 
     jTable.getColumnModel().getColumn(5) 
       .setCellEditor(new DefaultCellEditor(comboBox)); 
     jTable.setDefaultRenderer(Object.class, tableCellRend); 
     jTable.setAutoCreateRowSorter(true); 

     getContentPane().add(scrollPane); 

     pack(); 
     centerWindow(); 
     setVisible(true); 

    } 

    private class MyTableModel implements TableModel { 

     @Override 
     public void addTableModelListener(TableModelListener l) { 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 

      switch (columnIndex) { 
      case 0: 
       return String.class; 
      case 1: 
       return String.class; 
      case 2: 
       return String.class; 
      case 3: 
       return Object.class; 
      case 4: 
       return Object.class; 
      case 5: 
       return String.class; 
      default: 
       return null; 
      } 

     } 

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

     @Override 
     public String getColumnName(int columnIndex) { 
      switch (columnIndex) { 
      case 0: 
       return columnNames[0]; 
      case 1: 
       return columnNames[1]; 
      case 2: 
       return columnNames[2]; 
      case 3: 
       return columnNames[3]; 
      case 4: 
       return columnNames[4]; 
      case 5: 
       return columnNames[5]; 
      default: 
       return null; 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return data[0].length - 1; 
     } 

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

     @Override 
     public boolean isCellEditable(int rowIndex, int columnIndex) { 
      switch (columnIndex) { 
      case 5: 
       return true; 
      default: 
       return false; 
      } 

     } 

     @Override 
     public void removeTableModelListener(TableModelListener l) { 
     } 

     @Override 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
      data[rowIndex][columnIndex] = aValue; 
     } 

    } 

    public void centerWindow() { 
     Dimension dimension = getToolkit().getScreenSize(); 
     setLocation(((int) dimension.getWidth())/2 - (getWidth()/2), 
       ((int) dimension.getHeight())/2 - (getHeight()/2)); 
    } 

} 

Это результат, прежде чем нажать:

enter image description here

+0

Учебник Swing показывает вам, как реализовать комбинированное поле в качестве редактора. В учебнике столбец «Спорт» использует поле со списком. Как ваш код отличается от учебника? Я понятия не имею, почему вы фактически добавляете JComboBox в TableModel. Учебник этого не делает, так почему вы? – camickr

ответ

2

Вы должны выбирать тип объекта и поймать строковое значение перед вызовом Object.toString(); Поскольку метод Object.toString() возвращает данные об объекте, если это не String.

value = value instanceof JComboBox ? ((JComboBox) value).getSelectedItem().toString() : value.toString(); 

, то вы можете использовать это значение.

setText(value); 

Кроме того, я заметил, что вы назвали

table.setRowHeight((int) getPreferredSize().getHeight() + 5); 

внутри getTableCellRendererComponent(). Не делайте этого, он снова и снова будет помнить getTableCellRendererComponent(), и он сделает переполнение стека.

Также я внесла некоторые изменения в model.It были некоторые ошибки, как @ getRowCount() "вернуть данные [0] .length - 1;" (число столбцов возвращается вместо количества строк), которое должно быть «return data.length»;

@Override 
     public Class<?> getColumnClass(int columnIndex) { 
      Object value = this.getValueAt(0, columnIndex); 
      return (value == null ? Object.class : value.getClass()); 
     } 

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

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

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