Fixed column of a Jtable in a Jscrollpane

Asked

Viewed 1,204 times

4

How do I leave a fixed Jtable column (no scroll) inside a Jscrollpane?

I want to leave the first column of a fixed table, the scroll bar will only scroll from the second column onwards, the first should always be visible.

I even managed to do but I have to divide the table in two...

  • I don’t know if this is really possible. It seems to me that your solution of splitting the table in two is the best.

  • @Victor Apparently you can’t escape from raising two JTable, but it seems possible to use a single TableModel and make each table (header and "rest") use only one part of that template.

2 answers

3

What you’re looking for is a Row header (line header - compare with column header, used when you want a line fixed at the top). There is a similar question in Stackoverflow in English, but the answers do not contain much information, only two links.

I took a quick look at both of them, and they separate the JTable in two... However, the first link allows using a single TableModel for both tables - which is what really matters, right?

See the link to the complete solution. Example of use (simplified):

TableModel data = new DefaultTableModel(0,10); // Substitua com seu TableModel particular

// Criando o modelo de coluna para a tabela "normal" (coluna 1 em diante)
TableColumnModel columns = new DefaultTableColumnModel();
for (int count = data.getColumnCount(), i = 1; i < count; i++)
{
    TableColumn c = new TableColumn(i);
    c.setHeaderValue(data.getColumnName(i));
    columns.addColumn(c);
}

// Criando o modelo de coluna para o cabeçalho (coluna 0; se quiser pode fixar mais colunas)
TableColumnModel headerColumns = new DefaultTableColumnModel();
TableColumn h = new TableColumn(0);
h.setHeaderValue(data.getColumnName(0));
headerColumns.add(h);

// Criando as tabelas
JTable table = new JTable(data, columns);
JTable rowHeader = new JTable(data, headerColumns);

// RowHeaderRendered é uma classe externa, que pode ser baixada no link acima
rowHeader.setDefaultRenderer(Object.class, new RowHeaderRenderer());

JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setRowHeaderView(rowHeader);
  • 1

    That’s kind of what I did, I actually specialized a Jscrollpane, I’ll post my solution to whoever wants to see it. Maybe when you have more time I’ll try another way

0

My solution until then:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class JFixedColScrollPane extends JScrollPane {

  private JTable fixedTable;
  private JTable mainTable;

  public JFixedColScrollPane( JTable fxTable, JTable mnTable ) throws Exception {
    super( mnTable );
    this.fixedTable = fxTable;
    this.mainTable = mnTable;

    fixedTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
    mainTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );

    setRowHeaderView( fixedTable );

    ListSelectionListener listSelectionListener = new ListSelectionListener() {
      public void valueChanged( ListSelectionEvent e ) {
        JTable tabelaSelecionada = (e.getSource() == fixedTable.getSelectionModel()) ? fixedTable : mainTable;
        JTable tabelaASelecionar = (tabelaSelecionada == fixedTable) ? mainTable : fixedTable;
        tabelaASelecionar.getSelectionModel().removeListSelectionListener( this );
        tabelaASelecionar.clearSelection();
        int linha = tabelaSelecionada.getSelectedRow();
        if ( linha >= 0 ) {
          tabelaASelecionar.getSelectionModel().addSelectionInterval( linha, linha );
          if ( tabelaSelecionada == fixedTable ) {
            Rectangle rectangle = tabelaASelecionar.getCellRect( linha, 0, false );
            rectangle.width = tabelaASelecionar.getWidth();
            tabelaASelecionar.scrollRectToVisible( rectangle );
          }
        }
        tabelaASelecionar.getSelectionModel().addListSelectionListener( this );
      }
    };

    this.fixedTable.getSelectionModel().addListSelectionListener( listSelectionListener );
    this.mainTable.getSelectionModel().addListSelectionListener( listSelectionListener );

    final JTableHeader fixedTableHeader = this.fixedTable.getTableHeader();
    setCorner( ScrollPaneConstants.UPPER_LEFT_CORNER, fixedTableHeader );

    fixedTable.addComponentListener( new ComponentAdapter() {
      @Override
      public void componentResized( ComponentEvent e ) {
        fixedTable.setPreferredScrollableViewportSize( new Dimension( fixedTable.getColumnModel().getTotalColumnWidth(), 50 ) );
      }
    } );
  }

  public JTable getFixedTable() throws Exception {
    return fixedTable;
  }

  public JTable getMainTable() throws Exception {
    return mainTable;
  }
}

to use:

new JFixedColScrollPane( tabelaFixa, tabelaMovel );

Browser other questions tagged

You are not signed in. Login or sign up in order to post.