É possível congelar a 1a coluna de um JTable (swing) ? [Semi-resolvido]

Apesar de já ter achado esse assunto aqui (ano passado), o pessoal não continuou o tópico então resolvi criar um novo.

Gostaria de saber se existe uma maneira de congelar apenas a primeira coluna de um JTable (de 6 colunas por exemplo), não permitindo que o usuário arraste ela para outra ordem/posição e permitindo o scroll de rolagem das outras colunas .

Sei que têm como congelar a table inteira, mas apenas 1 coluna não sei…
<< jtable.getTableHeader().setReorderingAllowed(false); >>

Já conversei com um colega sobre isso e ele me disse que eu teria que “customizar” o JTable. Seria isso mesmo?

Exemplo paliativo:

[quote]package com.gui;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumnModel;

public class FixedColumnScrollPane extends JScrollPane
{
public FixedColumnScrollPane(JTable main, int fixedColumns)
{
super( main );

    //  Use the table to create a new table sharing
    //  the DataModel and ListSelectionModel

    JTable fixed = new JTable( main.getModel() );
    fixed.setFocusable( false );
    fixed.setSelectionModel( main.getSelectionModel() );
    fixed.getTableHeader().setReorderingAllowed( false );

// fixed.getTableHeader().setResizingAllowed( false );
fixed.putClientProperty(“terminateEditOnFocusLost”, Boolean.TRUE);
main.putClientProperty(“terminateEditOnFocusLost”, Boolean.TRUE);

    //  Remove the fixed columns from the main table

    for (int i = 0; i < fixedColumns; i++)
    {
        TableColumnModel columnModel = main.getColumnModel();
        columnModel.removeColumn( columnModel.getColumn( 0 ) );
    }

    //  Remove the non-fixed columns from the fixed table

    while (fixed.getColumnCount() > fixedColumns)
    {
        TableColumnModel columnModel = fixed.getColumnModel();
        columnModel.removeColumn( columnModel.getColumn( fixedColumns ) );
    }

    //  Add the fixed table to the scroll pane

    fixed.setPreferredScrollableViewportSize(fixed.getPreferredSize());
    setRowHeaderView( fixed );
    setCorner(JScrollPane.UPPER_LEFT_CORNER, fixed.getTableHeader());
}

public static void main(String[] args)
{
    //  Build your table normally

    JTable table = new JTable(10, 8);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    JScrollPane scrollPane= new FixedColumnScrollPane(table, 1 );

//
JFrame frame = new JFrame(“Table Fixed Column Demo”);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( scrollPane );
frame.setSize(400, 300);
frame.setVisible(true);
}
}[/quote]

Fonte: http://forum.java.sun.com/thread.jspa?threadID=601267&messageID=3222198

Exatamente cara.Se você quer que um componente funcione de um modo customizado para seu aplicativo você provávelmente vai ter que customizá-lo.
Dê uma olhada no código fonte dos Models utilizados pela JTable pra você ver o que eles fazem e o que você provávelmente irá ter que fazer.
DefaultTableMode, JTableHeader, DefaultTableColumnModel…

Olá Juliano…

Já briguei muito com esse problema, pois eu não queria utilizar duas jtable (como no exemplo que você mostrou acima), porém foi o único jeito que consegui (e olha q pesquisei muito ;-))

Realmente ainda não possui um método do tipo: jTable.setCongelar(numCol) hehe…

abraços!

espero que com isso vc resolva:
http://weblogs.java.net/blog/elevy/archive/2009/01/freezable_jtabl.html

Galera,

Estou precisando desse efeito de ‘congelar painéis’ no JTable, mas queria saber se a única solução é criando 2 JTables mesmo, ou se depois de 2 anos temos algum componente mais completo?

É até engraçado, quando me pediram isso pensei comigo em usar 2 JTables, mas achei que seria uma solução meio antiga e que deveria ter algo mais “encapsulado”…

Vlw

A Melhor solução que vi até o momento foi essa:

http://tips4java.wordpress.com/2008/11/05/fixed-column-table/

Impacto no seu código:

Onde o scrollPaneBottom é o objeto que contem sua tabela. E o código da classe mágica é esse:

[code]import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/*

  • Prevent the specified number of columns from scrolling horizontally in

  • the scroll pane. The table must already exist in the scroll pane.

  • The functionality is accomplished by creating a second JTable (fixed)

  • that will share the TableModel and SelectionModel of the main table.

  • This table will be used as the row header of the scroll pane.

  • The fixed table created can be accessed by using the getFixedTable()

  • method. will be returned from this method. It will allow you to:

  • You can change the model of the main table and the change will be

  • reflected in the fixed model. However, you cannot change the structure

  • of the model.
    */
    public class FixedColumnTable implements ChangeListener, PropertyChangeListener {
    private JTable main;
    private JTable fixed;
    private JScrollPane scrollPane;

    /*

    • Specify the number of columns to be fixed and the scroll pane

    • containing the table.
      */
      public FixedColumnTable(int fixedColumns, JScrollPane scrollPane) {
      this.scrollPane = scrollPane;

      main = ((JTable) scrollPane.getViewport().getView());
      main.setAutoCreateColumnsFromModel(false);
      main.addPropertyChangeListener(this);

      // Use the existing table to create a new table sharing
      // the DataModel and ListSelectionModel

      int totalColumns = main.getColumnCount();

      fixed = new JTable();
      fixed.setAutoCreateColumnsFromModel(false);
      fixed.setModel(main.getModel());
      fixed.setSelectionModel(main.getSelectionModel());
      fixed.setFocusable(false);

      // Remove the fixed columns from the main table
      // and add them to the fixed table

      for (int i = 0; i < fixedColumns; i++) {
      TableColumnModel columnModel = main.getColumnModel();
      TableColumn column = columnModel.getColumn(0);
      columnModel.removeColumn(column);
      fixed.getColumnModel().addColumn(column);
      }

      // Add the fixed table to the scroll pane

      fixed.setPreferredScrollableViewportSize(fixed.getPreferredSize());
      scrollPane.setRowHeaderView(fixed);
      scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixed.getTableHeader());

      // Synchronize scrolling of the row header with the main table

      scrollPane.getRowHeader().addChangeListener(this);
      }

    /*

    • Return the table being used in the row header
      */
      public JTable getFixedTable() {
      return fixed;
      }
      //
      // Implement the ChangeListener
      //

    @Override
    public void stateChanged(ChangeEvent e) {
    // Sync the scroll pane scrollbar with the row header

    JViewport viewport = (JViewport) e.getSource();
    scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
    

    }
    //
    // Implement the PropertyChangeListener
    //

    @Override
    public void propertyChange(PropertyChangeEvent e) {
    // Keep the fixed table in sync with the main table
    if (“selectionModel”.equals(e.getPropertyName())) {
    fixed.setSelectionModel(main.getSelectionModel());
    }

    if ("model".equals(e.getPropertyName())) {
        fixed.setModel(main.getModel());
    }
    

    }
    }[/code]

Sds