0

I cannot find a solution to add row header to my table. With horizontal header everything is okay, but how to set the vertical header (row header) to the left? Here is the code I currently have:

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

public class Table{

    public static void main(String[] args) {

        int n = 5;
        int m = 5;

        String[][] arrayList = new String[n][m];
        String[] horizontalHeader = new String[n];
        String[] verticalHeader = new String[n];

        for (int i = 0; i < n; i++) {
            horizontalHeader[i] = "column" + i;
            verticalHeader[i] = "row" + i;
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arrayList[i][j] = "value";
            }
        }

        JFrame frame = new JFrame("Table");
        JTable table = new JTable(arrayList, horizontalHeader);
        JScrollPane scrollPane = new JScrollPane(table);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

camickr
  • 321,443
  • 19
  • 166
  • 288
  • 1
    Hi, interesting, perhaps this might be of interest https://stackoverflow.com/questions/26248084/how-to-display-row-header-on-jtable-instead-of-column-header – IronMan Nov 17 '20 at 00:09

1 Answers1

1

You create a component and add the component to the JScrollPane using the setRowHeaderView(...) method.

So you might use a JList as the component containing the values for each row.

You would also need a custom renderer so the row header is rendered like the column header.

Here is a basic example that just uses a number for each row:

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

public class TableRowHeader extends JList implements TableModelListener
{
    private JTable table;

    @SuppressWarnings("unchecked")
    public TableRowHeader(JTable table)
    {
        this.table = table;

        setAutoscrolls( false );
        setCellRenderer(new RowHeaderRenderer());

        setFixedCellHeight(table.getRowHeight());
        setFixedCellWidth(50);
        setFocusable( false );
        setModel( new TableListModel() );
        setOpaque( false );
        setSelectionModel( table.getSelectionModel() );
        table.getModel().addTableModelListener( this );
    }

    public void tableChanged(TableModelEvent e)
    {
        if (e.getType() == TableModelEvent.INSERT
        ||  e.getType() == TableModelEvent.DELETE)
        {
            repaint();
        }
    }

    /*
     *  Use the table to implement the ListModel
     */
    class TableListModel extends AbstractListModel
    {
        public int getSize()
        {
            return table.getRowCount();
        }

        public Object getElementAt(int index)
        {
            return String.valueOf(index + 1);
        }
    }

    /*
     *  Use the table row header properties to render each cell
     */
    class RowHeaderRenderer extends DefaultListCellRenderer
    {
        RowHeaderRenderer()
        {
            setHorizontalAlignment(CENTER);
            setOpaque(true);
            setBorder(UIManager.getBorder("TableHeader.cellBorder"));
            setFont(table.getTableHeader().getFont());
            setBackground(table.getTableHeader().getBackground());
            setForeground(table.getTableHeader().getForeground());
        }

        public Component getListCellRendererComponent(
            JList list, Object value, int index,
            boolean isSelected, boolean cellHasFocus)
        {

            if (isSelected)
            {
                setBackground( table.getSelectionBackground() );
            }
            else
            {
                setBackground( table.getTableHeader().getBackground() );
            }

            setText( (value == null) ? "" : value.toString() );

            return this;
        }
    }
    private static void createAndShowUI()
    {
        JTable table = new JTable( 1000, 10 );
        JScrollPane scrollPane = new JScrollPane( table );
        scrollPane.setRowHeaderView( new TableRowHeader( table) );

        JFrame frame = new JFrame("Row Header Test");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

If you want different values in the row header then you would use your own ListModel containing the values you want displayed, instead of the TableListModel.

If you can dynamically add/remove rows of data from the TableModel, then you would need logic to also add/remove rows from the ListModel.

camickr
  • 321,443
  • 19
  • 166
  • 288