Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用自定义JTable单元编辑器和单元渲染器_Java_Swing_Jtable_Tablecellrenderer_Tablecelleditor - Fatal编程技术网

Java 如何使用自定义JTable单元编辑器和单元渲染器

Java 如何使用自定义JTable单元编辑器和单元渲染器,java,swing,jtable,tablecellrenderer,tablecelleditor,Java,Swing,Jtable,Tablecellrenderer,Tablecelleditor,我已经创建了一个JTable,它带有一个自定义表渲染器和自定义单元编辑器,可以在图像中给出结果 我使用扩展了JPanel的单独类创建了第一个表单元格中显示的面板。并将表值添加为 tbl.setCellEditor(new customCell()); tbl.getColumnModel().getColumn(0).setCellRenderer(new customCell()); DefaultTableModel dtm = (Defa

我已经创建了一个JTable,它带有一个自定义表渲染器和自定义单元编辑器,可以在图像中给出结果

我使用扩展了JPanel的单独类创建了第一个表单元格中显示的面板。并将表值添加为

        tbl.setCellEditor(new customCell());
        tbl.getColumnModel().getColumn(0).setCellRenderer(new customCell());

        DefaultTableModel dtm = (DefaultTableModel) tbl.getModel();

        Vector v = new Vector();
        v.add(new Panel());
        v.add("Test");
        dtm.addRow(v);

        v.clear();
        v.add(new Panel());
        v.add("Test 2");
        dtm.addRow(v);
这是我的table自定义类,用于创建此表

class customCell extends DefaultTableModel implements TableCellRenderer, TableCellEditor {

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Panel p = new Panel();            
            table.setRowHeight(row, p.getHeight());
            return p;
        }

        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {

            return new Panel();
        }

        public Object getCellEditorValue() {
            return "";
        }

        public boolean isCellEditable(EventObject anEvent) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return true;
        }

        public boolean stopCellEditing() {
            return true;
        }

        public void cancelCellEditing() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void addCellEditorListener(CellEditorListener l) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void removeCellEditorListener(CellEditorListener l) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

我的问题是,面板的显示与我预期的一样,我无法在文本字段中键入或更改复选框或单击按钮。请告诉我如何解决这个问题。

我强烈建议重用默认表呈现器和编辑器中提供的功能,因为您的代码有很多问题

  • 请拆分编辑器、渲染器和表模型。把他们都安排在同一个班上真是奇怪
  • 对于渲染器,不要每次都创建
    组件的新实例。相反,重用相同的组件,只需在
    getTableCellRenderComponent
    方法中修改该
    组件
  • 编辑器
    组件也一样
  • 扩展默认编辑器,而不是使用
    UnsupportedOperationException
    s或只返回空
    String
    s来实现方法
  • 为了支持我的第四点,请引用以下内容:

    如果要指定除文本字段、复选框或组合框以外的编辑器,该怎么办?由于DefaultCellEditor不支持其他类型的组件,您必须做更多的工作。您需要创建一个实现TableCellEditor接口的类。AbstractCellEditor类是一个很好的超类。它实现了TableCellEditor的超级界面CellEditor,省去了实现单元格编辑器所需的事件触发代码的麻烦

    您的单元编辑器类至少需要定义两个方法-getCellEditorValue和getTableCellEditorComponent。CellEditor所需的getCellEditorValue方法返回单元格的当前值。TableCellEditor所需的getTableCellEditorComponent方法应配置并返回要用作编辑器的组件

    如文中所述,您必须实现事件触发代码:

    省去了实现单元编辑器所需的事件触发代码的麻烦


    你显然忽视了这一点。因此,我建议从
    AbstractCellEditor
    开始,而不是从头开始实现界面

    必须为已经可见的
    JPanel
    添加适当的
    LayoutManager
    可编辑/不可编辑的属性

    让我们享受

    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 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");
    
       public 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());
        }
    }
    

    停止编辑属于编辑器,而不是面板。另外,从外部actionListener搞乱模型是。。。有争议;-)谢谢你的精彩捕捉,顺便说一句,这段代码被你的诚实修改了3次以上,我试着移动并使用Rob制作的JTable中的动作(我认为没有更好、更自由、更简单的了),没有发生类似的更改和事件,你为什么要扩展AbstractCellEditor@Radu西蒙涅斯库因为。。。。。。。冰熊??:-),我认为这是最简单、紧凑的代码,例如在SSCCE forn中,粘贴到public forumplease中,请使用小写变量名,这是非常令人困惑的。