2014-12-14 4 views
0

내가 원하는 것은 JComboBox가있는 Jtable의 여섯 번째 열을 올바르게 구현하는 것입니다. 필드를 클릭하면 갑자기 콤보 박스가 나타나지만 클릭하지 않으면 JComponent 참조가 String으로 나타납니다. 나는 자신의 tableModel과 tableCellrenderer를 정의했다. 클릭하기 전에JTable에서 JComboBox를 올바르게 구현하는 방법은 무엇입니까?

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

스윙 튜토리얼에서는 콤보 상자를 편집기로 구현하는 방법을 보여줍니다. 튜토리얼에서 "스포츠"열은 콤보 상자를 사용합니다. 코드와 튜토리얼의 차이점은 무엇입니까? 왜 실제로 JComboBox를 TableModel에 추가하는지 알 수 없습니다. 튜토리얼은 그렇게하지 않습니다. 그렇다면 왜 당신입니까? – camickr

답변

2

당신은 객체 유형을 필터링하고는 Object.toString를 호출하기 전에 문자열 값을 잡을 필요가(); Object.toString() 메서드는 String이 아닌 한 Object에 대한 세부 정보를 반환하므로

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

값을 사용할 수 있습니다.

setText(value); 

은 또한 당신이 getTableCellRendererComponent 내부

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

라는 것으로 나타났습니다(). Do not do, getTableCellRendererComponent() 자체를 반복해서 호출하고 스택 오버플로를 생성합니다.

또한 model.It에 @ getRowCount() "return data [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; 
     } 
관련 문제