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