2009-06-05 54 views
75

Tengo un JTable en el que me puse el tamaño de la columna de la siguiente manera:Java JTable establecer el ancho de columna

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
table.getColumnModel().getColumn(0).setPreferredWidth(27); 
table.getColumnModel().getColumn(1).setPreferredWidth(120); 
table.getColumnModel().getColumn(2).setPreferredWidth(100); 
table.getColumnModel().getColumn(3).setPreferredWidth(90); 
table.getColumnModel().getColumn(4).setPreferredWidth(90); 
table.getColumnModel().getColumn(6).setPreferredWidth(120); 
table.getColumnModel().getColumn(7).setPreferredWidth(100); 
table.getColumnModel().getColumn(8).setPreferredWidth(95); 
table.getColumnModel().getColumn(9).setPreferredWidth(40); 
table.getColumnModel().getColumn(10).setPreferredWidth(400); 

Esto funciona bien, pero cuando se maximiza la mesa, me sale el espacio vacío a la derecha de la última columna. ¿Es posible cambiar el tamaño de la última columna al final de la ventana cuando se cambia el tamaño?

Encontré AUTO_RESIZE_LAST_COLUMN propiedad en documentos pero no funciona.

Editar: JTable está en un JScrollPane se establece su tamaño preferido.

Respuesta

38

¿Qué ocurre si llama al setMinWidth(400) en la última columna en su lugar de setPreferredWidth(400)?

En el JavaDoc para JTable, lea los documentos para doLayout() con mucho cuidado. Aquí están algunos bits de elección:

Cuando el método se denomina como resultado del cambio de tamaño de una ventana que encierra, el resizingColumn es nulo. Esto significa que el cambio de tamaño se ha producido "fuera" de JTable y el cambio, o "delta", se debe distribuir a todas las columnas, independientemente de este modo de cambio de tamaño automático de JTable.

Esto podría ser por qué AUTO_RESIZE_LAST_COLUMN no lo ayudó.

Nota: Cuando una JTable realiza ajustes en el ancho de las columnas, respeta por completo sus valores mínimos y máximos .

Esto indica que es posible que desee establecer Mín == Máx. Para todas menos las últimas columnas, establecer Min = Preferred en la última columna y no establecer Max o establecer un valor muy grande para Max.

+1

setMinWidth (400) todavía hace que la derecha de la tabla de Estar vacío –

+2

Intenta agregar setMaxWidth (10000) para ver si eso hace la diferencia. – Eddie

+0

lo cambió pero no tuvo efecto. –

21

Con JTable.AUTO_RESIZE_OFF, la tabla no cambiará el tamaño de ninguna de las columnas, por lo que tomará su configuración preferida. Si su objetivo es tener las columnas predeterminadas para su tamaño preferido, salvo que la última columna complete el resto del panel, tiene la opción de usar el JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode, pero podría ser más efectivo si se usa con TableColumn.setMaxWidth() en lugar de TableColumn.setPreferredWidth() para todas menos la última columna.

Una vez que esté satisfecho de que AUTO_RESIZE_LAST_COLUMN de hecho funciona, se puede experimentar con una combinación de TableColumn.setMaxWidth() y TableColumn.setMinWidth()

+1

Cuando se utiliza AUTO_RESIZE_LAST_COLUMN para cambiar el tamaño de la tabla para que se ajuste al panel de desplazamiento, mi objetivo es tener la mesa en cierto tamaño mínimo pero hacerla crecer si es más grande que mi tamaño mínimo. –

+0

Puede tener este comportamiento si utiliza TableColumn.setMinWidth() en lugar de TableColumn.setMaxWidth(). – akf

+0

para agregar a mi último comentario: use TableColumn.setMinWidth() para cada columna de su tabla, incluida la última columna. – akf

4

Leyendo el comentario de Kleopatra (su segunda vez que se sugiere tener un vistazo a javax.swing.JXTable, y ahora estoy lo siento, no tienen un aspecto primera vez :)) le sugiero que siga el enlace

tuve esta solución para el mismo problema: (pero le sugiero que siga el siguiente enlace) en redimensionar la tabla , escala los anchos de columna de la tabla al ancho total de la tabla actual. para hacer esto utilizo una matriz global de enteros para los anchos de columna (relativas)):

private int[] columnWidths=null; 

utilizo esta función para establecer los anchos de columna tabla:

public void setColumnWidths(int[] widths){ 
    int nrCols=table.getModel().getColumnCount(); 
    if(nrCols==0||widths==null){ 
     return; 
    } 
    this.columnWidths=widths.clone(); 

    //current width of the table: 
    int totalWidth=table.getWidth(); 

    int totalWidthRequested=0; 
    int nrRequestedWidths=columnWidths.length; 
    int defaultWidth=(int)Math.floor((double)totalWidth/(double)nrCols); 

    for(int col=0;col<nrCols;col++){ 
     int width = 0; 
     if(columnWidths.length>col){ 
      width=columnWidths[col]; 
     } 
     totalWidthRequested+=width; 
    } 
    //Note: for the not defined columns: use the defaultWidth 
    if(nrRequestedWidths<nrCols){ 
     log.fine("Setting column widths: nr of columns do not match column widths requested"); 
     totalWidthRequested+=((nrCols-nrRequestedWidths)*defaultWidth); 
    } 
    //calculate the scale for the column width 
    double factor=(double)totalWidth/(double)totalWidthRequested; 

    for(int col=0;col<nrCols;col++){ 
     int width = defaultWidth; 
     if(columnWidths.length>col){ 
      //scale the requested width to the current table width 
      width=(int)Math.floor(factor*(double)columnWidths[col]); 
     } 
     table.getColumnModel().getColumn(col).setPreferredWidth(width); 
     table.getColumnModel().getColumn(col).setWidth(width); 
    } 

} 

Al configurar los datos I llamar:

setColumnWidths(this.columnWidths); 

y en el cambio que llamo el ComponentListener establecido en el padre de la tabla (en mi caso el JScrollPane que es el contenedor de mi mesa):

public void componentResized(ComponentEvent componentEvent) { 
    this.setColumnWidths(this.columnWidths); 
} 

nota que la tabla JTable también es global:

private JTable table; 

Y yo que establece el oyente:

scrollPane=new JScrollPane(table); 
    scrollPane.addComponentListener(this); 
+1

por lo que puedo ver, este es un truco (muy frágil): no se actualiza cuando el usuario cambia el ancho de una columna. De nuevo, sugiero que busque en el código fuente de JXTable: tiene una propiedad adicional horizontalScroll que activa el ancho disponible si la suma de las columnas prefs es menor que el ancho actual y muestra una barra de desplazamiento horizontal. De lo contrario – kleopatra

+0

Sé que no lo hace reacciona al usuario cambiando los anchos de tabla manualmente, de esa manera es un truco ... pero de nuevo: es mejor que lo sugerido anteriormente. Pero me hiciste sentir curiosidad por JXTable ... ¡echaré un vistazo allí! (y es agradable entrar a ti de nuevo en un tema de la mesa :)) –

+0

de nada :-) – kleopatra

1
fireTableStructureChanged(); 

no cumplirán el comportamiento de cambio de tamaño! Si este método se llama en algún lugar de su código DESPUÉS de establecer las propiedades de cambio de tamaño de la columna, todas sus configuraciones se restablecerán. Este efecto secundario puede ocurrir indirectamente. F.e. como consecuencia de que el modelo de datos vinculado se modifique de la manera en que se llama a este método, después de establecer las propiedades.

6

JTable.AUTO_RESIZE_LAST_COLUMN se define como "Durante todas las operaciones de cambio de tamaño, aplicar ajustes a la última columna sólo" lo que significa que tiene que establecer la autoresizemode al final de su código, de lo contrario setPreferredWidth() ganaron no afecta nada!

Así, en su caso esta sería la forma correcta:

table.getColumnModel().getColumn(0).setPreferredWidth(27); 
table.getColumnModel().getColumn(1).setPreferredWidth(120); 
table.getColumnModel().getColumn(2).setPreferredWidth(100); 
table.getColumnModel().getColumn(3).setPreferredWidth(90); 
table.getColumnModel().getColumn(4).setPreferredWidth(90); 
table.getColumnModel().getColumn(6).setPreferredWidth(120); 
table.getColumnModel().getColumn(7).setPreferredWidth(100); 
table.getColumnModel().getColumn(8).setPreferredWidth(95); 
table.getColumnModel().getColumn(9).setPreferredWidth(40); 
table.getColumnModel().getColumn(10).setPreferredWidth(400); 
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); 
+0

Gracias por una explicación clara y un ejemplo. – sg552

0

Usar este código. Funcionó para mí Consideré por 3 columnas. Cambia el valor del ciclo para tu código.

TableColumn column = null; 
     for (int i = 0; i < 3; i++) { 
      column = table.getColumnModel().getColumn(i); 
      if (i == 0) 
       column.setMaxWidth(10); 
      if (i == 2) 
       column.setMaxWidth(50); 
     } 
5

Utilice este método

public static void setColumnWidths(JTable table, int... widths) { 
    TableColumnModel columnModel = table.getColumnModel(); 
    for (int i = 0; i < widths.length; i++) { 
     if (i < columnModel.getColumnCount()) { 
      columnModel.getColumn(i).setMaxWidth(widths[i]); 
     } 
     else break; 
    } 

o extender la clase JTable:

public class Table extends JTable { 
    public void setColumnWidths(int... widths) { 
     for (int i = 0; i < widths.length; i++) { 
      if (i < columnModel.getColumnCount()) { 
       columnModel.getColumn(i).setMaxWidth(widths[i]); 
      } 
      else break; 
     } 
    } 
} 

Y luego

table.setColumnWidths(30, 150, 100, 100); 
Cuestiones relacionadas