2011-08-24 12 views
5

Estoy tratando de sentirse cómodo con JTables, TableModels, JTableHeaders, procesadores, etc. Estoy tratando de hacer una sencilla tabla ficticia (para fines prácticos) que tiene este aspecto:Cambio de oscilación colores de las celdas JTable

- 1 2 3 
A A1 A2 A3 
B B1 B2 B3 
C C1 C2 C3 

También quiero que la celda B2 - y solo esa celda - tenga un fondo azul (Color.BLUE) - todas las otras celdas pueden tener el color predeterminado de Swing que se les asigna automáticamente.

Mi código está a continuación y se basa en innumerables ejemplos que he encontrado en este sitio web y en Internet en general. Pero no obtengo los resultados que quiero. En cambio, estoy obteniendo una tabla que se ve así:

A A1 A2 A3 
B B1 B2 B3 
C C1 C2 C3 

Observe que la primera fila (el encabezado) no está allí en absoluto. Además, con el código que lista a continuación, esto ejecuta y establece el color de todas las las celdas que colorean, no solo la celda B2 que quiero.

El código:

public class MyTable 
{ 
    public static void main(String[] args) 
    { 
     String[][] data = getTableData(); 
     String[] cols = getTableCols(); 

     JFrame frame = magicallyCreateJFrame();  // I promise this works! 
     MyRenderer myRenderer = new MyRenderer(); // See below 

     DefaultTableModel defModel = new DefaultTableModel(data, cols); 
     JTable myTable = new JTable(defModel); 

     myTable.setDefaultRenderer(Object.class, myRenderer); 

     frame.add(myTable); 
     frame.pack(); 
     frame.setVisible(true);    
    } 
} 

public static String[] getTableCols() 
{ 
    String cols = 
    { 
     "-", 
     "1", 
     "2", 
     "3", 
    }; 
} 

public static String[][] getTableData() 
{ 
    String[][] data = 
    { 
     { 
      "A", 
      "A1", 
      "A2", 
      "A3", 
     }, 
     { 
      "B", 
      "B1", 
      "B2", 
      "B3", 
     }, 
     { 
      "C", 
      "C1", 
      "C2", 
      "C3", 
     }, 
    }; 

    return data; 
} 

Y la rápida-n-sucia clase MyRenderer:

public class MyRenderer extends DefaultTableCellRenderer 
{ 
    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); 

    if(row == 2 && column == 2) 
     c.setBackground(new java.awt.Color(0, 0, 255)); 

    return c; 
} 

} 

Además del hecho de que este es horribles código y se rompe un montón de "mejor Prácticas tipo patrones y técnicas (recuerda que esto es solo algo con lo que estoy jugando), ¿Hay algo que esté haciendo aquí que sea obvio?? ¿Por qué no obtengo un encabezado de tabla (primera fila "- 1 2 3")? ¿Por qué mi procesador de células predeterminado no funciona en la celda B2 específica que estoy especificando?

JTables parecen ser bestias extrañas, bellas y poderosas. Poco a poco me estoy volviendo loco, pero me estoy ahogando con la implementación. ¡Gracias a cualquiera que pueda ayudar!

+0

Aún esperando un SSCCE ... – camickr

+0

Consulte también este [ejemplo] relacionado (http://stackoverflow.com/a/12352838/230513). – trashgod

Respuesta

14

usted necesita para asegurarse de que restablezca el procesador a su color de fondo por defecto (y manejar la selección de filas):

if (! table.isRowSelected(row)) 
{ 
    if(row == 2 && column == 2) 
     c.setBackground(new java.awt.Color(0, 0, 255)); 
    else 
     c.setBackground(table.getBackground()); 
} 

En el futuro a partir de una adecuada SSCCE con su pregunta.

3

¿Dónde especifica el renderizador para colorear B2 y solo B2? Quizás desee colocar un bloque if en su método getTableCellRendererComponent para que el color de fondo se establezca en azul solo si el objeto de valor de JTable toString() es "B2" o si los valores de fila y columna corresponden a la celda B2.

Y para ver el encabezado de su tabla, primero debe agregar la tabla a un JScrollPane y luego agregar el JScrollPane al padre.

Lo más importante: lea los tutoriales de Swing en JTables, ya que todo se explica aquí.

+0

Gracias Hovercraft: consulte el condicional agregado en la clase Renderer. Todavía no está funcionando, ¿qué me estoy perdiendo? – IAmYourFaja

4

Mitad-respuesta:

Usted necesita poner su JTable dentro de un JScrollPane tener el encabezado de la pantalla. O, como alternativa, puede agregar manualmente al diseño el componente devuelto por myTable.getTableHeader(). Sin embargo, recomiendo usar un JScrollPane.

EDIT:

Como se sugiere a continuación, para convertir el fondo azul para una sola celda específica, todo lo que necesita hacer es añadir una prueba como ésta:

if(column == 2 && row == 1) { 
    c.setBackground(Color.BLUE); 
} else { 
    c.setBackground(Color.WHITE); 
} 
+0

Y: ¿qué ocurre si en 'myTable.setDefaultRenderer (Object.class, myRenderer);' reemplaza 'Object.class' con' String.class'? – ChrisJ

+0

¿Cómo va a ayudar esto su problema? –

+0

Todos los datos en mi tabla serán cadenas. ¿Debo cambiar esa invocación para usar String.class en su lugar, y si es así, eso romperá algo? ¿Qué necesitaría cambiar para arreglar ese descanso? – IAmYourFaja

0

Tal vez, myTable.setDefaultRenderer(String.class, myRenderer); funcionaría correctamente.

0

Creo que la forma correcta de hacer el coloreado de la mesa es a través de ColorHighlighter. He dado un example here.

Cuestiones relacionadas