如何从jtable中删除一行

时间:2014-07-08 06:31:50

标签: java swing jtable jbutton tablecelleditor

我想更改要删除的按钮的操作。我有这段代码:

package buttonexample;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;


public class ButtonExample {

public JTable table;

    public static void main(String[] args) {
    final ButtonExample example = new ButtonExample();
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            example.createAndShowGUI();
        }
    });
}

private void createAndShowGUI() {
    JFrame frame = new JFrame("Button Example");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    table = new JTable(new JTableModel()); 
    JScrollPane scrollPane = new JScrollPane(table);
    table.setFillsViewportHeight(true); 

    TableCellRenderer buttonRenderer = new JTableButtonRenderer();
    //table.getColumn("Button1").setCellRenderer(buttonRenderer);
    table.getColumn("Button2").setCellRenderer(buttonRenderer);
    table.addMouseListener(new JTableButtonMouseListener(table));

    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.getContentPane().setPreferredSize(new Dimension(500, 200));
    frame.pack();
    frame.setVisible(true);
}

public static class JTableModel extends AbstractTableModel {
    private static final long serialVersionUID = 1L;
    private static final String[] COLUMN_NAMES = new String[] {"Id", "Stuff", "Asdfsdf", "Button2"};
    private static final Class<?>[] COLUMN_TYPES = new Class<?>[] {Integer.class, String.class, String.class,  JButton.class};

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

    @Override public int getRowCount() {
        return 4;
    }

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

    @Override public Class<?> getColumnClass(int columnIndex) {
        return COLUMN_TYPES[columnIndex];
    }

    @Override public Object getValueAt(final int rowIndex, final int columnIndex) {

        switch (columnIndex) {
            case 0: return rowIndex;
            case 1: return "Text for "+rowIndex;
            case 2: return "Column for "+rowIndex;
            case 3: final JButton button = new JButton(COLUMN_NAMES[columnIndex]);
                    button.addActionListener(new ActionListener() {
            @Override
                        public void actionPerformed(ActionEvent arg0) {
                                                            // When this is clicked the whole row will be deleted.
                            JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(button), 
                                    "Button clicked for row "+rowIndex);
                        }
                    });
                    return button;
            default: return "Error";
        }
    }   
}

private static class JTableButtonRenderer implements TableCellRenderer {        
    @Override public Component getTableCellRendererComponent(JTable table, Object     value, boolean isSelected, boolean hasFocus, int row, int column) {
        JButton button = (JButton)value;
        if (isSelected) {
            button.setForeground(table.getSelectionForeground());
            button.setBackground(table.getSelectionBackground());
        } else {
            button.setForeground(table.getForeground());
            button.setBackground(UIManager.getColor("Button.background"));
        }
        return button;  
    }
}

private static class JTableButtonMouseListener extends MouseAdapter {
    private final JTable table;

    public JTableButtonMouseListener(JTable table) {
        this.table = table;
    }

    public void mouseClicked(MouseEvent e) {
        int column = table.getColumnModel().getColumnIndexAtX(e.getX());
        int row    = e.getY()/table.getRowHeight(); 

        if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() &&                    
column >= 0) {
            Object value = table.getValueAt(row, column);
            if (value instanceof JButton) {
                ((JButton)value).doClick();
            }
        }
    }
}
}

但是(DefaultTableModel)someTable.getModel(); model.removeRow(row);我不能使它工作,因为表模型没有任何名称,我不知道该命名。我已经尝试初始化表模型,我得到错误说非静态变量模型不能引用静态上下文。有没有办法删除静态上下文中的行?

1 个答案:

答案 0 :(得分:3)

example by camickr可能是一个更可重用的解决方案,但为了教育......

  • 渲染单元格是视图的范畴
  • 模型应该永远不会包含组件,特别是如果你正考虑将它们渲染到屏幕上,这只是错误的方法......
  • 您需要设置一个TableCellEditor,它将作为您检索编辑操作通知(鼠标单击或按键)的方式

这是一个基本的例子,为了简单起见,我使用了DefaultTableModel因为它有一个很好的removeRow方法,但可以想象,你可以使用任何TableModel,只要您提供了删除行并由编辑器修改以支持它的方法......

enter image description here

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

public class ButtonExample {

    public JTable table;

    public static void main(String[] args) {
        final ButtonExample example = new ButtonExample();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                example.createAndShowGUI();
            }
        });
    }

    private void createAndShowGUI() {
        JFrame frame = new JFrame("Button Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        table = new JTable(new ExampleTableModel());
        JScrollPane scrollPane = new JScrollPane(table);
        table.setFillsViewportHeight(true);

        table.getColumn("action").setCellRenderer(new ButtonCellRenderer());
        table.getColumn("action").setCellEditor(new ButtonCellEditor());

        frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    public static class ExampleTableModel extends DefaultTableModel {

        public ExampleTableModel() {
            super(new Object[]{"id", "stuff", "blah", "action"}, 0);
            for (int index = 0; index < 10; index++) {
                addRow(new Object[]{index, "Text for " + index, "Na na", index});
            }
        }

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

    }

    public static class ButtonCellRenderer extends JButton implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (value != null) {
                setText("Delete row " + value.toString());
            } else {
                setText("Delete Me");
            }
            if (isSelected) {
                setForeground(table.getSelectionForeground());
                setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(UIManager.getColor("Button.background"));
            }
            return this;
        }
    }

    public static class ButtonCellEditor extends AbstractCellEditor implements TableCellEditor {

        private JButton editor;
        private Object value;
        private int row;
        private JTable table;

        public ButtonCellEditor() {
            editor = new JButton();
            editor.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (table != null) {
                        fireEditingStopped();
                        TableModel model = table.getModel();
                        if (model instanceof DefaultTableModel) {
                            ((DefaultTableModel) model).removeRow(row);
                        }
                    }
                }
            });
        }

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

        @Override
        public Object getCellEditorValue() {
            return value;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            this.table = table;
            this.row = row;
            this.value = value;
            if (value != null) {
                editor.setText("Delete row " + value.toString());
            } else {
                editor.setText("Delete Me");
            }
            if (isSelected) {
                editor.setForeground(table.getSelectionForeground());
                editor.setBackground(table.getSelectionBackground());
            } else {
                editor.setForeground(table.getForeground());
                editor.setBackground(UIManager.getColor("Button.background"));
            }
            return editor;
        }
    }

}

仔细查看How to Use Tables了解更多详情

这只是个人偏好,但我更喜欢使用工具栏或菜单项和键绑定来提供此支持。表中的按钮看起来如此...过时了 - 恕我直言