2013-02-26 126 views
3

我有一列JTable我设置了一个自定义TableCellRenderer返回自定义JPanel在其getTableCellRendererComponent方法。
JTable渲染JPanel

定制JPanel包含几个JTextFieldJButton,只有一个创建JPanel定制的实例,并在getTableCellRendererComponent方法我只设置了从数据模型对象JTextField值。

为了使JTextFiel编辑和JButton点击我不得不从JTable模型设置isCellEditable方法真正以及创建isCellEditable到真正实施TableCellEditor一类,并设置我的JTable的默认单元格编辑器它。

我想在点击我自定义的JPanel的某些按钮时获取表格选定的行,但它总是返回我-1。如果我将一个ListSelectionListener添加到JTable中,则它在连续单击时甚至不会调用valueChanged方法。如果我删除单元格编辑器,它工作正常。为什么ListSelectionListener无法工作,如果单元编辑器被添加到JTable,为什么需要提供单元编辑器?来自JTable模型的isCellEditable不够?

+0

不知道哪里是你的问题,在默认情况下ListSelectionListener返回渲染器的JComponent和XxxTableCellEditor太 – mKorbel 2013-02-26 13:11:55

+0

如果我添加ListSelectionListener到JTable它甚至不调用valueChanged方法,除非我没有将单元格编辑器设置为JTable。 – jerome 2013-02-26 13:15:44

+0

请在这里看到我的帖子一个答案,是否有同样的问题,什么是真正的问题,一切都取决于model_to_view,默认情况下不会将任何JComponents放到模型中,但是对于您的问题很好的示例 – mKorbel 2013-02-26 13:18:48

回答

3

SSCCE例如

import java.awt.*; 
import java.awt.event.*; 
import java.util.EventObject; 
import javax.swing.*; 
import javax.swing.table.*; 

public class PanelInTable { 

    private JFrame frame; 
    private JTable CompTable = null; 
    private PanelTableModel CompModel = null; 
    private JButton addButton = null; 

    public static void main(String args[]) { 
     try { 
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 
      //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     } catch (Exception fail) { 
     } 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new PanelInTable().makeUI(); 
      } 
     }); 
    } 

    public void makeUI() { 
     CompTable = CreateCompTable(); 
     JScrollPane CompTableScrollpane = new JScrollPane(CompTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
       JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
     JPanel bottomPanel = CreateBottomPanel(); 
     frame = new JFrame("Comp Table Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(CompTableScrollpane, BorderLayout.CENTER); 
     frame.add(bottomPanel, BorderLayout.SOUTH); 
     frame.setPreferredSize(new Dimension(800, 400)); 
     frame.setLocation(150, 150); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public JTable CreateCompTable() { 
     CompModel = new PanelTableModel(); 
     CompModel.addRow(); 
     JTable table = new JTable(CompModel); 
     table.setRowHeight(new CompCellPanel().getPreferredSize().height); 
     table.setTableHeader(null); 
     PanelCellEditorRenderer PanelCellEditorRenderer = new PanelCellEditorRenderer(); 
     table.setDefaultRenderer(Object.class, PanelCellEditorRenderer); 
     table.setDefaultEditor(Object.class, PanelCellEditorRenderer); 
     return table; 
    } 

    public JPanel CreateBottomPanel() { 
     addButton = new JButton("Add Comp"); 
     addButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent ae) { 
       Object source = ae.getSource(); 
       if (source == addButton) { 
        CompModel.addRow(); 
       } 
      } 
     }); 
     JPanel panel = new JPanel(new GridBagLayout()); 
     panel.add(addButton); 
     return panel; 
    } 
} 

class PanelCellEditorRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor { 

    private static final long serialVersionUID = 1L; 
    private CompCellPanel renderer = new CompCellPanel(); 
    private CompCellPanel editor = new CompCellPanel(); 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     renderer.setComp((Comp) value); 
     return renderer; 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 
     editor.setComp((Comp) value); 
     return editor; 
    } 

    @Override 
    public Object getCellEditorValue() { 
     return editor.getComp(); 
    } 

    @Override 
    public boolean isCellEditable(EventObject anEvent) { 
     return true; 
    } 

    @Override 
    public boolean shouldSelectCell(EventObject anEvent) { 
     return false; 
    } 
} 

class PanelTableModel extends DefaultTableModel { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public int getColumnCount() { 
     return 1; 
    } 

    public void addRow() { 
     super.addRow(new Object[]{new Comp(0, 0, "", "")}); 
    } 
} 

class Comp { 

    public int type; 
    public int relation; 
    public String lower; 
    public String upper; 

    public Comp(int type, int relation, String lower, String upper) { 
     this.type = type; 
     this.relation = relation; 
     this.lower = lower; 
     this.upper = upper; 
    } 
} 

class CompCellPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private JLabel labelWith = new JLabel("With "); 
    private JComboBox typeCombo = new JComboBox(new Object[]{"height", "length", "volume"}); 
    private JComboBox relationCombo = new JComboBox(new Object[]{"above", "below", "between"}); 
    private JTextField lowerField = new JTextField(); 
    private JLabel labelAnd = new JLabel(" and "); 
    private JTextField upperField = new JTextField(); 
    private JButton removeButton = new JButton("remove"); 

    CompCellPanel() { 
     setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 
     relationCombo.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       enableUpper(relationCombo.getSelectedIndex() == 2); 
      } 
     }); 
     enableUpper(false); 
     removeButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JTable table = (JTable) SwingUtilities.getAncestorOfClass(JTable.class, (Component) e.getSource()); 
       int row = table.getEditingRow(); 
       table.getCellEditor().stopCellEditing(); 
       ((DefaultTableModel) table.getModel()).removeRow(row); 
      } 
     }); 
     add(labelWith); 
     add(typeCombo); 
     add(relationCombo); 
     add(lowerField); 
     add(labelAnd); 
     add(upperField); 
     add(Box.createHorizontalStrut(100)); 
     add(removeButton); 
    } 

    private void enableUpper(boolean enable) { 
     labelAnd.setEnabled(enable); 
     upperField.setEnabled(enable); 
    } 

    public void setComp(Comp Comp) { 
     typeCombo.setSelectedIndex(Comp.type); 
     relationCombo.setSelectedIndex(Comp.relation); 
     lowerField.setText(Comp.lower); 
     upperField.setText(Comp.upper); 
     enableUpper(Comp.relation == 2); 
    } 

    public Comp getComp() { 
     return new Comp(typeCombo.getSelectedIndex(), relationCombo.getSelectedIndex(), lowerField.getText(), upperField.getText()); 
    } 
} 
0

为什么你需要在你的编辑你的选择?

是否足够了解您当前正在编辑的行和列?

,如果是,则只是将它们在那里你设置你的编辑值

@Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     renderer.setComp((Comp) value, row, column); 
     return renderer; 
    }