JTable com botão
Pessoal vou compartilhar com vocês um código que cria uma tabela (JTable), e em uma das colunas adiciona um botão (JButton).
É um material difícil de se encontrar na internet, já vi vários exemplos de extrema complexidade, nada funcional.
A classe principal ExemploTableComButton e duas classes acessórias TableSorter e CellRenderer.
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.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import br.com.bjbraz.app.jpme.screen.componentes.CellRenderer; import br.com.bjbraz.app.jpme.screen.componentes.TableSorter; public class ExemploTableComButton extends JPanel{ /** * */ private static final long serialVersionUID = 1L; public ExemploTableComButton(){ TabelaClientes tabela = new TabelaClientes(); Object[][] data = new Object[1][7]; data[0][0] = String.valueOf(0); data[0][1] = String.valueOf(0); data[0][2] = ""; data[0][3] = ""; data[0][4] = ""; data[0][5] = ""; data[0][6] = ""; JTable table = null; TableSorter sorter = null; javax.swing.JScrollPane scrollTabela; sorter = new TableSorter(tabela); table = new JTable(tabela); table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); table.setPreferredScrollableViewportSize(new Dimension(500, 300)); table.setFillsViewportHeight(true); table.addMouseListener(new JTableButtonMouseListener(table)); TableCellRenderer buttonRenderer = new JTableButtonRenderer(); table.getColumn("Detalhe").setCellRenderer(buttonRenderer); scrollTabela = new javax.swing.JScrollPane(table); tabela.setData(data); tabela.fireTableDataChanged(); table.repaint(); table.revalidate(); scrollTabela.repaint(); scrollTabela.revalidate(); add(scrollTabela); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { inicializar(); } }); } private static void inicializar() { ExemploTableComButton painel = new ExemploTableComButton(); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(painel); frame.pack(); frame.setVisible(true); } public class TabelaClientes extends AbstractTableModel { /** * */ private static final long serialVersionUID = 1L; private String[] columnNames = { "#", "Data abertura", "Data fechamento", "Local", "Responsável", "Total de produtos", "Detalhe" }; public final Object[] longValues = { "String", "String", "Data fechamento", "Local", "Responsável", "Total de produtos", "Detalhe" }; private final Class[] COLUMN_TYPES = new Class[] { String.class, String.class, String.class, String.class, String.class, String.class, JButton.class }; private Object[][] data = obterDados(); public Object[][] getData() { return data; } public void setData(Object[][] data) { this.data = data; } /** * Gera os dados para serem mostrados no Grid * * @return */ private Object[][] obterDados() { data = new Object[1][7]; data[0][0] = ""; data[0][1] = ""; data[0][2] = ""; data[0][3] = ""; data[0][4] = ""; data[0][5] = ""; data[0][6] = ""; return data; } public int getColumnCount() { return columnNames.length; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return columnNames[col]; } public Object getValueAt(final int rowIndex, final int columnIndex) { switch (columnIndex) { case 0: return data[rowIndex][columnIndex]; case 1: return data[rowIndex][columnIndex]; case 2: return data[rowIndex][columnIndex]; case 3: return data[rowIndex][columnIndex]; case 4: return data[rowIndex][columnIndex]; case 5: return data[rowIndex][columnIndex]; case 6: final JButton button = new JButton("Label botao"); button.setBorder(null); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Aqui vai a sua ação"); } }); return button; } return data[rowIndex][columnIndex]; } public Class getColumnClass(int c) { return COLUMN_TYPES[c]; } public boolean isCellEditable(int row, int col) { return false; } public void setValueAt(Object value, int row, int col) { data[row][col] = value; fireTableCellUpdated(row, col); } } /* * This method picks good column sizes. If all column heads are wider than * the column's cells' contents, then you can just use * column.sizeWidthToFit(). */ public void initColumnSizes(JTable table) { table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); TabelaClientes model = (TabelaClientes) table.getModel(); TableColumn column = null; Component comp = null; int headerWidth = 0; int cellWidth = 0; Object[] longValues = model.longValues; TableCellRenderer headerRenderer = table.getTableHeader() .getDefaultRenderer(); for (int i = 0; i < longValues.length; i++) { column = table.getColumnModel().getColumn(i); column.setCellRenderer(new CellRenderer()); if (i == 0) { column.setPreferredWidth(5); continue; } comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0); headerWidth = comp.getPreferredSize().width; comp = table.getDefaultRenderer(model.getColumnClass(i)) .getTableCellRendererComponent(table, longValues[i], false, false, 0, i); cellWidth = comp.getPreferredSize().width; column.sizeWidthToFit(); column.setPreferredWidth(Math.max(headerWidth, cellWidth)); System.out.println(column.getHeaderValue() + " headerWidth " + headerWidth + " cellWidth " + cellWidth); } } private static class JTableButtonRenderer implements TableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JButton button = (JButton) value; 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(); } } } } } public class CellRenderer extends DefaultTableCellRenderer { int contador = 0; public CellRenderer() { super(); } private Color getCellColor(int doc){ // este � um teste qualquer que faão para decidir // a cor da fonte de cada linha. // substitua por qualquer outro teste, se achar necessário if((doc % 2) == 0) return Color.GREEN; else return Color.BLACK; } public Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){ contador = contador +1 ; JLabel label = (JLabel)super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); // somente para centralizar if (column != 0) label.setHorizontalAlignment(JLabel.LEFT); // se for par if((row % 2) == 0){ // cor de fundo label.setBackground(Color.WHITE); // // cor da fonte // if(column != 0) // label.setForeground(getCellColor(contador)); } // se for �mpar else{ // cor de fundo // label.setBackground(new Color(240, 240, 240)); label.setBackground(new Color(210, 228, 238)); // // cor da fonte // if(column != 0) label.setForeground(Color.BLACK); } label.setHorizontalAlignment(SwingConstants.LEFT); return label; } } public class TableSorter extends TableMap { int indexes[]; Vector sortingColumns = new Vector(); boolean ascending = true; int compares; public TableSorter() { indexes = new int[0]; } public TableSorter(TableModel model) { setModel(model); } public void setModel(TableModel model) { super.setModel(model); reallocateIndexes(); } public int compareRowsByColumn(int row1, int row2, int column) { Class type = model.getColumnClass(column); TableModel data = model; Object o1 = data.getValueAt(row1, column); Object o2 = data.getValueAt(row2, column); if (o1 == null && o2 == null) { return 0; } else if (o1 == null) { return -1; } else if (o2 == null) { return 1; } /* * We copy all returned values from the getValue call in case * an optimised model is reusing one object to return many * values. The Number subclasses in the JDK are immutable and * so will not be used in this way but other subclasses of * Number might want to do this to save space and avoid * unnecessary heap allocation. */ if (type.getSuperclass() == java.lang.Number.class) { Number n1 = (Number)data.getValueAt(row1, column); double d1 = n1.doubleValue(); Number n2 = (Number)data.getValueAt(row2, column); double d2 = n2.doubleValue(); if (d1 < d2) { return -1; } else if (d1 > d2) { return 1; } else { return 0; } } else if (type == java.util.Date.class) { Date d1 = (Date)data.getValueAt(row1, column); long n1 = d1.getTime(); Date d2 = (Date)data.getValueAt(row2, column); long n2 = d2.getTime(); if (n1 < n2) { return -1; } else if (n1 > n2) { return 1; } else { return 0; } } else if (type == String.class) { String s1 = (String)data.getValueAt(row1, column); String s2 = (String)data.getValueAt(row2, column); int result = s1.compareTo(s2); if (result < 0) { return -1; } else if (result > 0) { return 1; } else { return 0; } } else if (type == Boolean.class) { Boolean bool1 = (Boolean)data.getValueAt(row1, column); boolean b1 = bool1.booleanValue(); Boolean bool2 = (Boolean)data.getValueAt(row2, column); boolean b2 = bool2.booleanValue(); if (b1 == b2) { return 0; } else if (b1) { // Define false < true return 1; } else { return -1; } } else { Object v1 = data.getValueAt(row1, column); String s1 = v1.toString(); Object v2 = data.getValueAt(row2, column); String s2 = v2.toString(); int result = s1.compareTo(s2); if (result < 0) { return -1; } else if (result > 0) { return 1; } else { return 0; } } } public int compare(int row1, int row2) { compares++; for (int level = 0; level < sortingColumns.size(); level++) { Integer column = (Integer)sortingColumns.elementAt(level); int result = compareRowsByColumn(row1, row2, column.intValue()); if (result != 0) { return ascending ? result : -result; } } return 0; } public void reallocateIndexes() { int rowCount = model.getRowCount(); // Set up a new array of indexes with the right number of elements // for the new data model. indexes = new int[rowCount]; // Initialise with the identity mapping. for (int row = 0; row < rowCount; row++) { indexes[row] = row; } } public void tableChanged(TableModelEvent e) { //System.out.println("Sorter: tableChanged"); reallocateIndexes(); super.tableChanged(e); } public void checkModel() { if (indexes.length != model.getRowCount()) { System.err.println("Sorter not informed of a change in model."); } } public void sort(Object sender) { checkModel(); compares = 0; // n2sort(); // qsort(0, indexes.length-1); shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length); //System.out.println("Compares: "+compares); } public void n2sort() { for (int i = 0; i < getRowCount(); i++) { for (int j = i+1; j < getRowCount(); j++) { if (compare(indexes[i], indexes[j]) == -1) { swap(i, j); } } } } public void shuttlesort(int from[], int to[], int low, int high) { if (high - low < 2) { return; } int middle = (low + high)/2; shuttlesort(to, from, low, middle); shuttlesort(to, from, middle, high); int p = low; int q = middle; if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) { for (int i = low; i < high; i++) { to[i] = from[i]; } return; } // A normal merge. for (int i = low; i < high; i++) { if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) { to[i] = from[p++]; } else { to[i] = from[q++]; } } } public void swap(int i, int j) { int tmp = indexes[i]; indexes[i] = indexes[j]; indexes[j] = tmp; } // The mapping only affects the contents of the data rows. // Pass all requests to these rows through the mapping array: "indexes". public Object getValueAt(int aRow, int aColumn) { checkModel(); return model.getValueAt(indexes[aRow], aColumn); } public void setValueAt(Object aValue, int aRow, int aColumn) { checkModel(); model.setValueAt(aValue, indexes[aRow], aColumn); } public void sortByColumn(int column) { sortByColumn(column, true); } public void sortByColumn(int column, boolean ascending) { this.ascending = ascending; sortingColumns.removeAllElements(); sortingColumns.addElement(new Integer(column)); sort(this); super.tableChanged(new TableModelEvent(this)); } // There is no-where else to put this. // Add a mouse listener to the Table to trigger a table sort // when a column heading is clicked in the JTable. public void addMouseListenerToHeaderInTable(JTable table) { final TableSorter sorter = this; final JTable tableView = table; tableView.setColumnSelectionAllowed(false); MouseAdapter listMouseListener = new MouseAdapter() { public void mouseClicked(MouseEvent e) { TableColumnModel columnModel = tableView.getColumnModel(); int viewColumn = columnModel.getColumnIndexAtX(e.getX()); int column = tableView.convertColumnIndexToModel(viewColumn); if (e.getClickCount() == 1 && column != -1) { //System.out.println("Sorting ..."); int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK; boolean ascending = (shiftPressed == 0); sorter.sortByColumn(column, ascending); } } }; JTableHeader th = tableView.getTableHeader(); th.addMouseListener(listMouseListener); } }
Comentários
Postar um comentário