2011-04-15 19 views
11

Me gustaría hacer una tabla editable y luego verificar los datos para asegurarme de que es válida. No estoy seguro de cómo cambiar el color de una sola celda. Me gustaría obtener una celda, por ejemplo (0,0) y colorear el primer plano en rojo. He leído las otras publicaciones en SO así como en Oracle sobre el ColorRenderer personalizado, pero simplemente no entiendo cómo usaría esto.Java JTable change cell color

Gracias.

Respuesta

17

Supongamos que la celda que desea representar con un color diferente representa un estado (tomaré Rechazado y Aprobado como ejemplos). Luego implementaría un método en mi modelo de tabla llamado getStatus (int row) que devuelve el estado de cualquier fila determinada.

Luego, cuando esté en su lugar, crearé un procesador de células responsable de representar la columna a la que pertenece la celda. El procesador de celda sería algo en las líneas del código siguiente.

public class StatusColumnCellRenderer extends DefaultTableCellRenderer { 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { 

    //Cells are by default rendered as a JLabel. 
    JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); 

    //Get the status for the current row. 
    CustomTableModel tableModel = (CustomTableModel) table.getModel(); 
    if (tableModel.getStatus(row) == CustomTableModel.APPROVED) { 
     l.setBackground(Color.GREEN); 
    } else { 
     l.setBackground(Color.RED); 
    } 

    //Return the JLabel which renders the cell. 
    return l; 

} 

Entonces, cuando el procesador está en su lugar, simplemente "aplicar" el procesador a la mesa con el siguiente fragmento de código:

Table.getColumnModel().getColumn(columnIndex).setCellRenderer(new StatusColumnCellRenderer()); 

Con respecto a la preparación de una célula editable, sólo tiene que poner en práctica el isCellEditable (int rowIndex, int columnIndex) método en su modelo de tabla. También necesita implementar el método setValueAt (valor del objeto, int rowIndex, int columnIndex) si desea mantener el valor que proporciona el usuario (¡que supongo que tiene!).

+0

alternativa: También puede evitar la realización del procedimiento getStatus() en su modelo de mesa si lo prefiere. Digamos, si getValueAt (int rowIndex, int columnIndex) de su modelo de tabla devuelve los estados como cadenas ("APROBADO", "RECHAZADO") entonces simplemente podría tener el renderizado para verificar el valor proporcionado [...] RendererComponent (tabla, valor) , boolean [...]) y cambia el color de la celda en función de eso. Entonces no necesitaría tomar el "desvío" al modelo de tabla para obtener el estado de la fila/columna actual. Esta podría ser la forma más fácil de hacerlo ... – sbrattla

+0

Una última pequeña nota: si busca la solución en la que implementa getStatus (int row), asegúrese de convertir el índice de filas utilizando table.convertRowIndexToModel (int row) La fila proporcionada a getTableCellRendererComponent() es el índice de vista, que puede ser diferente del índice del modelo si el orden de las filas se cambia debido a la clasificación. – sbrattla

1

La forma más sencilla es escribir un simple TableCellRenderer extendiendo el DefaultTableCellRenderer y sobrescribir el método getTableCellRendererComponent a setBackground(Color.RED). Por ejemplo:

final JTable table = new JTable(...); 
table.setCellRenderer(new DefaultTableCellRenderer() { 
    public Component getTableCellRenderer(JTable table, Object value, ...) { 
     super.getTableCellRenderer(...); 

     if (value should be highlighted) { 
      setBackground(Color.RED); 
     } 
     return this; 
    } 
}); 
+1

no - eso es incompleto: DefaultTableCellEditor es una implementación defectuosa que exhibe la infame "memoria de color": al tocar los colores una vez, tendrás que hacerlo siempre, es decir, agregar una rama else a – kleopatra

+0

@kleopatra. Tienes razón, debería haber un 'else' que restablece el color a negro. Además, no hay un método 'setCellRenderer' en' JTable', por lo que este es un ejemplo incompleto. Mis intenciones eran que mostraría al OP lo suficiente como para comenzar por el camino correcto y ellos mismos podrían aprender los pequeños detalles. –

2

me gustaría hacer una tabla editable y luego comprobar los datos para asegurarse de su validez.

Otro enfoque sería editar los datos antes de guardarlos en el modelo de tabla para evitar que se ingresen datos no válidos.

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 
import javax.swing.event.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 

public class TableEdit extends JFrame 
{ 
    TableEdit() 
    { 
     JTable table = new JTable(5,5); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 

     JScrollPane scrollpane = new JScrollPane(table); 
     getContentPane().add(scrollpane); 

     // Use a custom editor 

     TableCellEditor fce = new FiveCharacterEditor(); 
     table.setDefaultEditor(Object.class, fce); 
    } 

    class FiveCharacterEditor extends DefaultCellEditor 
    { 
     FiveCharacterEditor() 
     { 
      super(new JTextField()); 
     } 

     public boolean stopCellEditing() 
     { 
      try 
      { 
       String editingValue = (String)getCellEditorValue(); 

       if(editingValue.length() != 5) 
       { 
        JTextField textField = (JTextField)getComponent(); 
        textField.setBorder(new LineBorder(Color.red)); 
        textField.selectAll(); 
        textField.requestFocusInWindow(); 

        JOptionPane.showMessageDialog(
         null, 
         "Please enter string with 5 letters.", 
         "Alert!",JOptionPane.ERROR_MESSAGE); 
        return false; 
       } 
      } 
      catch(ClassCastException exception) 
      { 
       return false; 
      } 

      return super.stopCellEditing(); 
     } 

     public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) 
     { 
      Component c = super.getTableCellEditorComponent(
       table, value, isSelected, row, column); 
      ((JComponent)c).setBorder(new LineBorder(Color.black)); 

      return c; 
     } 

    } 

    public static void main(String [] args) 
    { 
     JFrame frame = new TableEdit(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

Esto es probablemente lo que estoy buscando, daré una oportunidad y te lo haré saber. Tengo un botón para guardar para verificar que todos los datos sean válidos antes de guardar. Quiero poder guardar los datos que son válidos y omitir los datos que no lo son. ¡Gracias! – Matt

1

Esta es la forma más sencilla de colorear una Columna o celda en particular en una jTable.

Primera basta con crear una clase simple de CustomRenderer

class CustomRenderer extends DefaultTableCellRenderer <br /> 
{ 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
    { 
     Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
     setForeground(Color.blue); > 
     return c; 
    } 
} 

Este código obtiene la columna de celdas para mostrar

TableColumn col = tblExamHistoryAll.getColumnModel().getColumn(5); 
DefaultTableModel model3 = (DefaultTableModel)tblExamHistoryAll.getModel(); 
col.setCellRenderer(new CustomRenderer()); 

Esto es para borrar todas las filas anteriores desde su mesa. Si no quiere que acaba de eliminar estas líneas

model3.getDataVector().removeAllElements(); 
model3.fireTableDataChanged(); 
+0

-1 para fireXX desde el exterior (preguntándose si fue usted quien con la misma [misma respuesta incorrecta] (http://stackoverflow.com/a/13536681/203657) - mismo nombre, nueva cuenta?) – kleopatra

1

Creo que la forma correcta de hacer colorante en una mesa es a través de un ColorHighlighter. Los visualizadores de tabla tienen problemas para representar diferentes colores en la misma columna.

Aquí hay un ejemplo de cómo usar los resaltadores.En este caso, es para resaltar una celda que no es editable.

public class IsCellEditablePredicate implements HighlightPredicate { 

private JXTable table; 

public IsCellEditablePredicate (final JXTable table) { 
    this.table = table; 
} 

@Override 
public boolean isHighlighted(Component component, ComponentAdapter componentAdapter) { 

    return !table.isCellEditable(componentAdapter.row, 
      componentAdapter.column); 
} 

}

y luego en su código para setuping la tabla se agrega el rotulador y sus parámetros de color:

ColorHighlighter grayHighlighter = new ColorHighlighter(new IsCellEditablePredicate(table)); 

    grayHighlighter.setBackground(Color.LIGHT_GRAY); 
    grayHighlighter.setForeground(table.getForeground()); 
    grayHighlighter.setSelectedBackground(table.getSelectionBackground().darker()); 
    grayHighlighter.setSelectedForeground(table.getSelectionForeground().darker()); 

    table.setHighlighters(grayHighlighter); 
+0

¿Qué es exactamente? quieres decir con tu oración en negrita? ¿Podrías dar un ejemplo, por favor? – jaivalis