2010-07-22 10 views
6

Tengo una extensión JTable que se ha utilizado desde Java 1.3/1.4 en el proyecto que proporciona cosas como reordenamiento y clasificación de columnas haciendo clic en la columna. Estamos actualizando a Java 1.6, y la nueva JTable impide que el código de clasificación antiguo funcione. Sería una repetición algo extensa adaptar todo a la nueva API de JTable. Hasta entonces, ¿hay alguna forma de desactivar por completo esas adiciones en JTable?¿Cómo se puede deshabilitar todo el código de clasificación en JTable en 1.6

Editar: Después de la investigación adicional, el problema se centra en el hecho de que los eventos del mouse en el encabezado son absorbidos por Swing en 1.6 y no pasan a la implementación de la tabla, aunque establece su propio encabezado. Tanto para la justificada compatibilidad con versiones anteriores de Java.

Entonces, ¿hay alguna manera de detener el JTable 1.6? No he podido. Incluso anulando la interfaz de usuario en la mesa y el encabezado de la tabla no ayuda.

+0

He probado esto en el ejemplo de Sol y table.setRowSorter (nulo) está trabajando. ¿Podría ingresar el ejemplo del código para que todos puedan probarlo? – amra

Respuesta

4

¿Has probado JTable.setRowSorter(null)?

editar: y setAutoCreateRowSorter? (1. crear tabla, 2. fila clasificador a nulo, 3. autocreate clasificador a falso, 4. establecer modelo).

+0

Sí, desafortunadamente no ayudó :( – Yishai

+0

Edito mi respuesta, para hacer un segundo intento :-) – Istao

+0

Desafortunadamente eso tampoco ayudó. Incluso tuve que hackear ese componente porque siempre llamaba al súper que pasa un modelo, por lo que llama a un modelo establecido más tarde. Todavía no hay dados :( – Yishai

1
JTable.setAutoCreateRowSorter(false); 

A menos que el TableRowSorter se establece en alguna parte, no creo que usted tiene que llamar setRowSorter(null)

3

yo uso esto en mi subclase JTable y las capturas de eventos de ratón muy bien:

class QueueTable extends JTable { 
    public QueueTable() { 
     ... 
     getTableHeader().addMouseListener(new SortColumnListener(1)); 
    } 
} 
El

SortColumnListener se implementa de esta manera:

class SortColumnListener extends MouseAdapter { 
    SortColumnListener(int column) { ... } 

    public void mouseClicked(MouseEvent e) { 
     TableColumnModel colModel = QueueTable.this.getColumnModel(); 
     int columnModelIndex = colModel.getColumnIndexAtX(e.getX()); 

     if(columnModelIndex == column) { 
      // Do stuff 
     } 
    } 
} 

Esto atrapa los eventos del mouse en el SortColumnListener y puedo hacer lo que quiera con esos eventos. No tengo ningún conjunto RowSorter aplicación en el JTable y esto funciona perfectamente en Java 5 y Java 6.

Por completo el código fuente de esta clase, consulte: QueueTable.java

+0

Sí, he observado eso también, puedes agregar tu propio oyente. Pero en Java 1.5, creo que el punto era que un evento de mouse en el encabezado o en la mesa se propagaba igualmente sin un oyente especial en el encabezado. Al menos eso creo. – Yishai

+0

Es muy posible que lo hayan sido, pero consideraría un detalle de implementación y no una promesa de la API. Agregar un MouseListener al TableHeader siempre ha sido "la" forma de hacerlo. –

+0

Desafortunadamente, incluso agregando explícitamente un oyente y bombeando el mouse incluso a través de ese componente (y lo depuré, cree que es un evento de mouse normal) * todavía * no obtiene la tabla para ordenarlo. Suspiro. – Yishai

2

Tengo entendido que usted tiene dos problemas:

  1. Debido al nuevo código de clasificación en JTable, su ordenación no funciona.
  2. Incluso si deshabilita la ordenación por setRowSorter(null) o anulando el setRowSorter(TableRowsorter) para que no haga nada, no funciona porque los eventos en el encabezado no se pasan a su JTable.

En ese caso, creo que la opción para usted es simplemente tener su código de clasificación aplicado como TableRowSorter. No sé qué tan complejo es su código de clasificación y si puede asignar la API de TableRowSorter, pero esta parece ser una alternativa más que puede probar.

0

Probé todas las posibilidades mencionadas aquí en Sun table sort example y todas están funcionando.

Lamentablemente todavía hay many bugs in table sorting. No se puede hacer mucho hasta que publiques tu código aquí. Una posibilidad es probar SwingX solution.

+0

Gracias, lamentablemente, el componente que se rompió es de propiedad, y aunque compramos el código fuente, no puedo publicarlo aquí. – Yishai

0

He resuelto el problema en su edición:

package jtableheadermouseevent; 

import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableModel; 

/** 
* 
* @author martijn 
*/ 
public class Main { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     JFrame fr = new JFrame("JTable Header Mouse Listener"); 
     fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final JTable table = new JTable(); 
     JScrollPane pane = new JScrollPane(table); 

     String[][] data = {{"Foo", "Bar"}, {"Baz", "Coffee"}}; 
     String[] columns = {"Header 0", "Header 1"}; 

     DefaultTableModel model = new DefaultTableModel(data, columns); 
     table.setModel(model); 
     fr.add(pane); 
     table.getTableHeader().addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       super.mouseClicked(e); 
       System.out.println("Header clicked : (X: " + e.getX() + ", Y: " + e.getY() + ") With button " + e.getButton()); 
       int header = table.getTableHeader().columnAtPoint(e.getPoint()); 
       System.out.println("This means header " + header + " is clicked!"); 
      } 

     }); 
     fr.pack(); 
     fr.setSize(800, 300); 
     fr.setVisible(true); 
    } 

} 

Esto funciona perfecto en Linux, así que supongo que también en OSX y Windows. También lo probé después de cambiar el tamaño de las columnas: todavía sé qué columnas se presionaron. Pero después de reordenar las columnas, la columna que fue primero "columna 0" se convirtió en "columna 1".
Pero siempre se puede no permitir al usuario mover las columnas con esto:

table.getTableHeader().setReorderingAllowed(false); 

espero que esto ayude

+0

sí, eso me permite agregar un oyente adicional. Desafortunadamente, no solucionó el comportamiento. – Yishai

1

Una manera de desactivar la ordenación al hacer clic en la cabecera, es eliminar todos los oyentes de la cabecera de la tabla:

 for(MouseListener listener : table.getTableHeader().getMouseListeners()){ 
     table.getTableHeader().removeMouseListener(listener); 
    } 

Luego, en caso de que quiera alguna otra acción específica (como cambiar el tamaño de la columna) que sólo podría añadir un detector específico para esa acción en particular.

0

Prueba esto:

public abstract class BaseTable extends JTable { 
    public BaseTable() { 
     init(); 
     .. 
    } 

    protected boolean sortableDisable() { 
     return false; 
    } 

    private void init() { 
     TableRowSorter<BaseTableModel> sorter = 
      new TableRowSorter<BaseTableModel>(tableModel); 
     if (sortableDisable()) { 
      setAutoCreateRowSorter(false); 
      for (int c = 0; c < tableModel.getColumnCount(); c++) { 
       sorter.setSortable(c, false); 
      } 
     } 
     setRowSorter(sorter); 
     .. 
    } 
} 

public class TableX extends BaseTable() { 

    @Override 
    protected boolean sortableDisabled() { 
     return true; 
    } 
    .. 
} 
Cuestiones relacionadas