在JBable中使JButton可单击

这是我想要做的截图:

在此处输入图像描述

发生了什么事情,JButton显示正确,但点击它没有任何反应。 经过一些搜索,我发现table.getValueAt()返回的Object是一个String而不是一个JButton …

这是代码:

 tblResult = new JTable(data,cols) { public TableCellRenderer getCellRenderer( int row, int column ) { return new ClientsTableRenderer(); } }; 

我在运行时使用它来填充JTable 🙁 tblResult现在是Clients.rblResult

 SwingUtilities.invokeLater( new Runnable() { public void run() { DefaultTableModel aModel = new DefaultTableModel() { //setting the jtable read only @Override public boolean isCellEditable(int row, int column) { return false; } }; String[] cols = {"N°","Société", "TVA", "CP", "Ville", ""}; aModel.setColumnIdentifiers(cols); Object[] temp = new Object[6]; for(int i=0;i<result.length;i++) { temp[0] = result[i].custNumber; temp[1] = result[i].name; temp[2] = result[i].tva; temp[3] = result[i].cp; temp[4] = result[i].city; temp[5] = "Consulter"; aModel.addRow(temp); } Clients.tblResult.setModel(aModel); Clients.tblResult.addMouseListener(new JTableButtonMouseListener(Clients.tblResult)); }} ); 

这里是ClientsTableRenderer

 public class ClientsTableRenderer extends JPanel implements TableCellRenderer { @Override public Component getTableCellRendererComponent( final JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setBackground(Color.WHITE); if(column < 5) { JLabel label = new JLabel(value.toString()); JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER,0,9)); panel.setBackground(Color.WHITE); panel.add(label); this.add( panel); } else { JButton button = new JButton(value.toString()); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { System.out.println("Clicked !"); } }); JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER,0,3)); panel.setBackground(Color.WHITE); panel.add(button); this.add(panel); } return this; } } 

最后,JTableButtonMouseListener():

 public class JTableButtonMouseListener extends MouseAdapter { private final JTable table; public JTableButtonMouseListener(JTable table) { this.table = table; } @Override public void mouseClicked(MouseEvent e) { int column = table.getColumnModel().getColumnIndexAtX(e.getX()); int row = e.getY()/table.getRowHeight(); System.out.println("Col :"+column + "row:"+row); if (row = 0 && column 
= 0) { Object value = table.getValueAt(row, column); System.out.println("Value :"+value.getClass().getName()); if (value instanceof JButton) { ((JButton)value).doClick(); } } } }

我是Java新手,非常感谢帮助:)

提前致谢 !

Rob Camick的Table Button Column可满足您的需求。

问题是当表中绘制时, JButton不再存在。 这些组件仅用于在呈现表时创建“标记”。 没有实际的按钮。

有一种方法可以让你点击按钮, 仍然保持你的表不可编辑 ,但它远离正确的代码。 只是一个可能的解决方案的快速大纲(我现在没时间给出一个完整的代码示例)

  • 将鼠标监听器附加到表中
  • 单击鼠标时,确定单击鼠标的单元格
  • 向表格渲染器询问该单元格的组件
  • 使用鼠标单击的位置来确定在该特定位置的上一步骤中组件中是否存在按钮
  • 如果是这样,点击按钮api( doClick方法)

这甚至不是代码的脏部分。 由于你的渲染器(希望)每次都不会返回一个新的JButton ,你应该在附加到JButton ActionListener中跟踪实际发生的点击的组件。 一个可能的解决方案是保持对上次创建JButton的表模型值的引用(因此在getCellRendererComponent方法中跟踪行/列),但我不确定这是否是最佳方法。

如上所述,一个可能的解决方案,但远非优雅。

最简单的方法是让一个列可编辑并使用编辑器,如其他答案中所指出的那样

尝试这个:

 import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; 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.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; public class TableWithButtonDemo { private JFrame frame = new JFrame("Table Demo"); private String[] columnNames = { "String", "Integer", "Float", "" }; private Object[][] data = { { "Dummy", new Integer(12), new Float(12.15), "Consulter" } }; private TableModel model = new DefaultTableModel(data, columnNames) { private static final long serialVersionUID = 1L; public boolean isCellEditable(int row, int column) { return column == 3; } }; private JTable table = new JTable(model); public TableWithButtonDemo() { table.getColumnModel().getColumn(3).setCellRenderer(new ClientsTableButtonRenderer()); table.getColumnModel().getColumn(3).setCellEditor(new ClientsTableRenderer(new JCheckBox())); table.setPreferredScrollableViewportSize(table.getPreferredSize()); table.setShowHorizontalLines(true); table.setShowVerticalLines(false); JScrollPane scroll = new JScrollPane(table); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(scroll); frame.pack(); frame.setLocation(150, 150); frame.setVisible(true); } public static void main(String[] args) throws Exception { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); EventQueue.invokeLater(new Runnable() { public void run() { new TableWithButtonDemo(); } }); } class ClientsTableButtonRenderer extends JButton implements TableCellRenderer { public ClientsTableButtonRenderer() { setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setForeground(Color.black); setBackground(UIManager.getColor("Button.background")); setText((value == null) ? "" : value.toString()); return this; } } public class ClientsTableRenderer extends DefaultCellEditor { private JButton button; private String label; private boolean clicked; private int row, col; private JTable table; public ClientsTableRenderer(JCheckBox checkBox) { super(checkBox); button = new JButton(); button.setOpaque(true); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fireEditingStopped(); } }); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { this.table = table; this.row = row; this.col = column; button.setForeground(Color.black); button.setBackground(UIManager.getColor("Button.background")); label = (value == null) ? "" : value.toString(); button.setText(label); clicked = true; return button; } public Object getCellEditorValue() { if (clicked) { JOptionPane.showMessageDialog(button, "Column with Value: "+table.getValueAt(row, 1) + " - Clicked!"); } clicked = false; return new String(label); } public boolean stopCellEditing() { clicked = false; return super.stopCellEditing(); } protected void fireEditingStopped() { super.fireEditingStopped(); } } } 

本文提供了一种更简单的方法来解决您的问题,而无需添加MouseListeners并计算点击实际上是否在按钮上:

http://web.archive.org/web/20100623105810/http://ivolo.mit.edu/post/A-Simple-Pattern-for-Embedding-Components-into-a-Swing-JTable.aspx

重载表模型,并设置isCellEditable(int,int)为带按钮的单元格返回false。

它可以很好地添加到表中的MouseListener。

这是我的解决方案

ButtonEditor.java

 public abstract class ButtonEditor extends DefaultCellEditor implements ActionListener { private static final long serialVersionUID = 1L; /** The cell's row. */ protected int row; /** The cell's column. */ protected int column; /** The cell's column. */ protected JTable table; /** The button we are editing. */ protected JButton button; /** The panel used when editing. */ protected JPanel panel = new JPanel(new GridBagLayout()); /** Constructor */ public ButtonEditor() {super(new JCheckBox());} /** * This method is called when the user try to modify a cell. * In this case it will be called whenever the user click on the cell. * @param table * @param value * @param isSelected * @param row * @param column * @return JPanel The JPanel returned contains a JButton with an ActionListener. */ @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { this.row = row; this.column = column; this.table = table; button = (JButton) value; //prevent to add the action listener everytime the user click on the cell. if(button.getActionListeners().length == 0) button.addActionListener(this); panel.add(button); panel.setBackground(table.getGridColor()); return panel; } /** * Return a renderer for JButtons. The result is a button centered in the table's cell. * @return */ public static TableCellRenderer getRenderer() { return new TableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JPanel panel = new JPanel(new GridBagLayout()); panel.add((JButton) value); panel.setBackground(table.getGridColor()); return panel; } }; } 

}

以下是如何使用它:

Demo.java

  table.setDefaultRenderer(JButton.class, ButtonEditor.getRenderer()); table.setDefaultEditor(JButton.class, new ButtonEditor() { @Override public void actionPerformed(ActionEvent e) { //handle clicks here. for example: if(column == 5) { System.out.Println(row); button.setFocusPainted(false); } } });