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

Postagens mais visitadas deste blog

Introdução ao Empreendedorismo

Economia - Princípio da Utilidade Marginal Decrescente

Integrando seu site com o facebook