JTable con JButton (Swing)

Resuelto
mikis69 Mensajes publicados 174 Estado Miembro -  
mikis69 Mensajes publicados 174 Estado Miembro -
Hola a todos,

En el marco de un proyecto personal, estoy utilizando JTable pero tengo un problema importante con la selección de una fila.

Una imagen vale más que mil palabras, así que aquí está la imagen de mi JTable.



Como pueden ver en la imagen, cuando se selecciona una fila, solo las columnas "String" tienen el fondo azul/gris y las columnas "JButton" no lo tienen. Sin embargo, realmente me gustaría que todas las columnas tuvieran el fondo azul/gris cuando se selecciona una fila.

He probado muchas cosas, pero nada lo que he hecho hasta ahora ha resuelto el problema.

 addMouseListener(new TableMouseListener(this)); setDefaultRenderer(Object.class, new TableCellRenderer()); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setRowHeight(25); 


 public class TableCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setBorder(BorderFactory.createEmptyBorder(0, 3, 2, 0)); setFont(getFont().deriveFont(14f)); if(value instanceof Button) { return (Button) value; } return this; } } 


Si alguien también tiene consejos para hacer la JTable más atractiva estéticamente, estaré encantado de escucharlos ^^

Gracias por su ayuda,

Mikis

3 respuestas

KX Mensajes publicados 19031 Estado Moderador 3 020
 
Hola,

El problema es que tu botón ocupa todo el tamaño de la celda, por lo que no deja traslucir el fondo de la fila que cambia de color.

Podrías utilizar el parámetro isSelected para identificar cuándo la fila está seleccionada y cambiar el color de fondo del botón en consecuencia.

Ejemplo:

import java.awt.*; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; public class Test { public static void main(String[] args) { Object[][] rowData = { { "a1", "b1", new JButton("c1") }, { "a2", "b2", new JButton("c2") } }; String[] numColumns = { "a", "b", "c" }; JTable table = new JTable(rowData, numColumns); table.setSelectionBackground(Color.YELLOW); table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof JButton) { JButton button = (JButton) value; button.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); return button; } else { return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); } } }); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(table); frame.pack(); frame.setVisible(true); } }
La confianza no excluye el control.
1
mikis69 Mensajes publicados 174 Estado Miembro
 
Bueno, después de lo que me dijiste:

"Así que el problema puede venir de la forma en que codificaste esta clase"

Fui a ver la clase en cuestión y aquí está el código que había:

 public Button(String icon, ActionListener action) { super(new ImageIcon("icons" + File.separator + icon)); addActionListener(action); setBorderPainted(false); setBorder(null); setBackground(null); setMargin(new Insets(0, 0, 0, 0)); setContentAreaFilled(false); } 


El problema era entonces el setContentAreaFilled(false) que había puesto para no tener un cambio de color al hacer clic en un botón. Desafortunadamente, el resultado en las JTable no era muy bueno ya que los botones no tenían fondo.

Así que reemplacé el código anterior por este

 public Button(String icon, ActionListener action) { super(new ImageIcon("icons" + File.separator + icon)); addActionListener(action); setBorderPainted(false); setBorder(null); setBackground(null); setMargin(new Insets(0, 0, 0, 0)); addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { ((JButton) e.getSource()).setContentAreaFilled(false); } }); } 


Y sin saber por qué, ahora funciona muy bien.
En las tablas el resultado es excelente y cuando hago clic en un botón, no hay cambio de color.



¡Gracias de todos modos!
1
mikis69 Mensajes publicados 174 Estado Miembro
 
"El problema es que tu botón ocupa todo el tamaño de la celda, por lo que ya no deja traslucir el fondo de la línea que cambia de color."

Sin embargo, cuando hago un

table.setBackground(Color.ORANGE);


Obtengo esto



E incluso intenté algo para que se vea más bonito. Alternar el color una línea sí y la siguiente no, pero el resultado en los botones sigue siendo "sin color" (el color por defecto de la JTable)



Creo que hay algo que no he entendido en los Renderer o los Editor que permitiría que aparezca mi botón y el fondo de la celda.
0
KX Mensajes publicados 19031 Estado Moderador 3 020
 
Aquí está la tabla que tú coloreas de naranja, yo hablo de colorear solo el botón, como en mi ejemplo.

if (value instanceof JButton) { JButton button = (JButton) value; button.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); return button; }
0
mikis69 Mensajes publicados 174 Estado Miembro > KX Mensajes publicados 19031 Estado Moderador
 
Nada sucede cuando escribo su código..

Si tomas la tercera imagen, ¿de dónde crees que proviene el problema? porque los botones no están "coloriendo" una línea sí y otra no..
0
KX Mensajes publicados 19031 Estado Moderador 3 020 > mikis69 Mensajes publicados 174 Estado Miembro
 
Si has puesto mi código tal cual, es normal que no pase nada, porque en mi ejemplo tomé JButton (Swing), mientras que tú has puesto Button (AWT), así que el instanceof no puede funcionar si no hablamos de la misma clase.

En la medida en que usas Swing, deberías reemplazar tus Button por JButton.
0
mikis69 Mensajes publicados 174 Estado Miembro
 
De hecho, la clase Button que he creado hereda de JButton...
0
KX Mensajes publicados 19031 Estado Moderador 3 020 > mikis69 Mensajes publicados 174 Estado Miembro
 
Ah... ¿no es la clase Button de java.awt?
Es una mala idea haberla nombrado como una clase estándar de Java.

Así que el problema puede venir de la manera en que has codificado esta clase... aunque eso no forma parte de los fragmentos de código que nos has dado.

Nota: puedes probar el código que puse hace un rato (es un main para ejecutar), verás que funciona muy bien y que el botón está bien resaltado.
 
0