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

6 respostas
J

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?

6 Respostas

J

Exemplo paliativo:

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);

}

}</blockquote>

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

L

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…

J

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!

R

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

P

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

D

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

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

Impacto no seu código:

FixedColumnTable fct = new FixedColumnTable(1, scrollPaneBottom);

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

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());
        }
    }
}

Sds

Criado 25 de março de 2008
Ultima resposta 15 de set. de 2012
Respostas 6
Participantes 6