向JTable中添加JButton

7
需要一个简单的Swing代码来演示如何使用tablecellrenderer和tablecelleditor在JTable的一列中添加按钮。

请查看此主题,可能会有所帮助。 https://dev59.com/J2DVa4cB1Zd3GeqPeIj3 - Shantanu Banerjee
需要完整的示例代码... 我无法理解它。 - deva
你尝试过什么?有许多可用于此的资源。看看Rob Camick的这个http://tips4java.wordpress.com/2009/07/12/table-button-column/,解释得非常好。 - Amarnath
2个回答

26

这是一个非常好的示例,它在 JTable 的单元格中添加了一个 JButton:

enter image description here

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class JButtonTableExample {

    public JButtonTableExample() {
        JFrame frame = new JFrame("JButtonTable Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        DefaultTableModel dm = new DefaultTableModel();
        dm.setDataVector(new Object[][]{{"button 1", "foo"},
                    {"button 2", "bar"}}, new Object[]{"Button", "String"});

        JTable table = new JTable(dm);
        table.getColumn("Button").setCellRenderer(new ButtonRenderer());
        table.getColumn("Button").setCellEditor(new ButtonEditor(new JCheckBox()));


        JScrollPane scroll = new JScrollPane(table);

        table.setPreferredScrollableViewportSize(table.getPreferredSize());//thanks mKorbel +1 https://dev59.com/4mPVa4cB1Zd3GeqP8bpk

        table.getColumnModel().getColumn(0).setPreferredWidth(100);//so buttons will fit and not be shown butto..

        frame.add(scroll);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JButtonTableExample();
            }
        });

    }
}

class ButtonRenderer extends JButton implements TableCellRenderer {

    public ButtonRenderer() {
        setOpaque(true);
    }

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

class ButtonEditor extends DefaultCellEditor {

    protected JButton button;
    private String label;
    private boolean isPushed;

    public ButtonEditor(JCheckBox checkBox) {
        super(checkBox);
        button = new JButton();
        button.setOpaque(true);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                fireEditingStopped();
            }
        });
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        if (isSelected) {
            button.setForeground(table.getSelectionForeground());
            button.setBackground(table.getSelectionBackground());
        } else {
            button.setForeground(table.getForeground());
            button.setBackground(table.getBackground());
        }
        label = (value == null) ? "" : value.toString();
        button.setText(label);
        isPushed = true;
        return button;
    }

    @Override
    public Object getCellEditorValue() {
        if (isPushed) {
            JOptionPane.showMessageDialog(button, label + ": Ouch!");
        }
        isPushed = false;
        return label;
    }

    @Override
    public boolean stopCellEditing() {
        isPushed = false;
        return super.stopCellEditing();
    }
}

参考资料:


如何为该按钮添加addActionListener以删除相应的行。 - deva
请参见http://tips4java.wordpress.com/2009/07/12/table-button-column/。 - gerardw
我尝试了这段代码,它完美地显示了按钮,但我无法单击它,它既不可用也不禁用,所以您知道什么问题吗?它看起来像你发布的图片,但我不能点击它...提前感谢! - Vasilije Bursac
2
我解决了这个问题。记住单元格必须是可编辑的。因此,在您的单元格编辑器中,您需要有类似以下代码的内容:@Override public boolean isCellEditable(EventObject e){ return true; }希望这能帮助到某些人! - Vasilije Bursac

23

### 在 JTable 上添加按钮

JTable 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);

###示例 JTableModel,它管理列和行,设置组件

public static class JTableModel extends AbstractTableModel {
        private static final long serialVersionUID = 1L;
        private static final String[] COLUMN_NAMES = new String[] {"Id", "Stuff", "Button1", "Button2"};
        private static final Class<?>[] COLUMN_TYPES = new Class<?>[] {Integer.class, String.class, JButton.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) {
            /*Adding components*/
            switch (columnIndex) {
                case 0: return rowIndex;
                case 1: return "Text for "+rowIndex;
                case 2: // fall through
               /*Adding button and creating click listener*/
                case 3: final JButton button = new JButton(COLUMN_NAMES[columnIndex]);
                        button.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent arg0) {
                                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(button), 
                                        "Button clicked for row "+rowIndex);
                            }
                        });
                        return button;
                default: return "Error";
            }
        }   
    }

###示例按钮点击监听器,这个监听器可以管理当鼠标单击组件时的情况。

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()); // get the coloum of the button
            int row    = e.getY()/table.getRowHeight(); //get the row of the button

            /*Checking the row or column is valid or not*/
            if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() && column >= 0) {
                Object value = table.getValueAt(row, column);
                if (value instanceof JButton) {
                    /*perform a click event*/
                    ((JButton)value).doClick();
                }
            }
        }
    }

###示例JTable单元格渲染器,管理单元格组件

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;
            return button;  
        }
    }

1
按钮点击不起作用 - JoachimR
3
您错过了table.addMouseListener(new JTableButtonMouseListener(table));这行代码。它为表格添加了一个鼠标监听器,用于处理单元格中的按钮点击事件。 - Andrew Selivanov
智能解决方案,我喜欢它。 - Abdullah Asendar
更简单的解决方案在这里 - https://dev59.com/8pzha4cB1Zd3GeqPCD0i#40440287 - Ravindra Gullapalli
您正在将应该在视图中的东西(即JButton)放入模型(TableModel)中。JButton应该只是渲染器的一部分。-1。 - searchengine27

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接