JList con JPaneles dentro

Estoy tratando de solucionar un problema con una ampliación java que estoy desarrollando y tal vez puedas ayudarme.
Tengo un JList (dentro de un JScrollPane, pero esto no creo que importe) donde meto JPaneles. Estos JPaneles tienen BorderLayouts con diferentes elementos. En particular, en el centro tienen un BoxLayout con diferentes JLabels y JButtons.
El problema es que necesito poder accionar estos botones y no puedo porque si hago click sobre ellos el evento no llega hasta el boton; simplemente se selecciona el item del JList. ¿Sabes si puede ser porque el evento no llega hasta el JButton?
¿Tendría qué hacer un mouselistener para el JList y que le pase el evento a los JButtons o algo así?
Estoy bastante desconcertado con el tema, ¿puedes ayudarme?
Gracias por tu tiempo.
Saludos
P.D: Soy experto en javascript en este site, por si lo necesitas alguna vez.

1 Respuesta

Respuesta
1
No te aconsejo que uses JList para hacer ese tipo de "listas con elementos variables" que supongo que es la razón por la que quieres usar un JList. Ademas de que los JList están diseñados para no ser editables, es decir que las celdas nunca tendrán foco, sus celdas solo sirven para mostrar datos. Para hacer lo que piensas hacer te recomiendo que uses un JTable con una sola columna, los JTable's si permiten editar los datos de una celda, para hacer eso debes conocer la clase abstracta TableCellRenderer que funciona casi igual que el CellRenderer que usaste para meter los Paneles dentro del JLIst, y también debes conocer la clase AbstractCellEditor la cual te permite darle el foco a los botones de tu panel, debes hacer que tu panel sea el Editor de la tabla, mejor dicho, aquí te mando un ejemplo de un JPanel como editor de un JTable:
import javax.swing.table.TableCellEditor;
import java.awt.Component;
import javax.swing.JTable;
import java.util.EventObject;
import javax.swing.*;
import java.awt.BorderLayout;
public class EditorTabla extends AbstractCellEditor implements TableCellEditor {
JPanel panel = new JPanel();
CampoDeTexto campo;
JButton boton;
public EditorTabla( CampoDeTexto campo, JButton boton ){
panel.setLayout(new BorderLayout(1,0));
this.campo = campo;
this.boton = boton;
panel.add(campo,BorderLayout.CENTER);
panel.add(boton,BorderLayout.EAST);
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
boton.setActionCommand(""+column);
campo.setText(value != null? value.toString(): "");
return panel;
}
public void setValor( Object valor ){
campo.setText(valor != null? valor.toString() : "");
campo.setValor(valor);
stopCellEditing();
}
public Object getValor(){
return campo.getValor();
}
public Object getCellEditorValue() {
return campo.getText();
}
public boolean isCellEditable(EventObject anEvent) {
return true;
}
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
public boolean stopCellEditing() {
/*JTable tabla = (JTable) panel.getParent();
int col = tabla.getEditingColumn();
try {
if (VentanaAgregarClase.esValorValido((Object)campo.getText(), col) == null) {
return false;
}
}
catch (Exception ex) {
return false;
}*/
fireEditingStopped();
return true;
}
public void cancelCellEditing() {
fireEditingCanceled();
}
}
Hola,
Muchas gracias por tu respuesta, es una de las opciones que barajaba como alternativa.
En realidad el usar un JList no es algo sin motivo. Veras, uso un JList porque con el método ensureIndexIsVisible(int index) puedo hacer que se vea el item numero "index" sin mayor esfuerzo. Los JPanel que van dentro de las celdas (bien sea un JList, bien sea un JTable) son de diferente tamaño (en altura) dependiendo de su contenido (algunas tienen más, otras menos).
¿Podría hacerse algo parecido con un JTable? Es decir, ¿existe alguna manera de hacer que se asegure hacer el scroll necesario para que se vea el indice "index" con un JTable?
Ah! Otra opción que barajaba era directamente pasar del JTable y poner un BoxLayout vertical con todos los paneles directamente... así me ahorro el JTable incluso, ¿cómo lo ves?
Otra vez gracias, tu respuesta ha sido genial, si necesitas alguna vez algo de javascript no dudes en preguntarme, aunque tal vez también seas experto en ello.
Saludos
Ok, me parece bien la alternativa del BoxLayout, pero deber hacer ciertas trucos si el numero de paneles crece y tus paneles se comienzan a incojer mucho. Siguiendo con lo del JTable para hacer que una fila determinada sea visible debes trabajar directamente con el ScrollPane, ya que los creadores de la clase JTable no se preocuparon por ese detalle "hacer una fila por visible", por lo tanto preparé un ejemplo para mostrar te como sería la cosa:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class pruebaTabla extends JFrame implements ActionListener {
JTable tabla;
JTextField campo = new JTextField(10);
JScrollPane barras;
public static void main( String args [] ){
new pruebaTabla();
}
public pruebaTabla(){
Integer [][] numeros = new Integer [50][1];
for( int i=0; i<50; i++ ){
numeros = new Integer [] {new Integer(i+1)};
}
tabla = new JTable(numeros,new String []{"Numeros"});
campo.addActionListener(this);
barras = new JScrollPane(tabla);
this.getContentPane().add(barras);
this.getContentPane().add(campo,BorderLayout.NORTH);
this.setSize(200,300);
this.setVisible(true);
}
public void actionPerformed( ActionEvent e ){
int f = Integer.parseInt(campo.getText());
if ( f > 0 && f <= 50 ){
tabla.setRowSelectionInterval(f-1,f-1);
hacerFilaVisible(f-1);
}
else {
JOptionPane.showMessageDialog(this,"El numero debe ser mayor que 0 y menor que 51");
}
}
private void hacerFilaVisible(int fila){
int sumaAlturas = 0;
for( int i=0; i<fila; i++ ){
sumaAlturas+=tabla.getRowHeight(i);
}
Point p = new Point(0,sumaAlturas);
barras.getViewport().setViewPosition(p);
}
}
Espero que te sirva :), bye.
Muchas gracias por tus ejemplos y respuestas. He visto también la clase JTree, que tiene celdas editables (y deberían poder tomar el foco) y tiene lo de "scroll hasta que se vea el seleccionado" (en este caso, el expandido).
Voy a ver que les parecen las alternativas a los que deciden...
Muchísimas gracias, has sido una gran ayuda.
Si alguna vez necesitas algo de javascript, o JSP, o lo que sea, ya sabes.
Saludos

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas