WilliamShatner
WilliamShatner

Reputation: 926

Display the information of a JTable row when selected

How do I display the information of a JTable row when selected?

I'll briefly explain what I am trying to do and then post the SSCCE that I created in case any of my explanation is confusing.

I'm wanting to be able to click any row in a table and display that information on a panel. I'm not sure what I need to make use of to get the job done.

I'm thinking I'll need to use:

I haven't used Listeners before, so I only know of those from reading articles/documentation while researching what I need to do to complete the job.

I'm also slightly confused as to how to display the info on my JPanel. The panel is created in the main class where as the table is created in its own class.

I appreciate any help and advice.

Example source :

import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class SwingTesting {

    private final JFrame frame;
    private final TablePane tablePane;
    private final JSplitPane splitPane;
    private final JPanel infoPanel;

    public SwingTesting() {
        tablePane = new TablePane();
        infoPanel = new JPanel();
        frame = new JFrame();

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tablePane, infoPanel);

        frame.add(splitPane);
        frame.pack();
        frame.setVisible(true);
    }


    class TablePane extends JPanel {

        private final JTable table;
        private final TableModel tableModel;
        private final ListSelectionModel listSelectionModel;

    public TablePane() {
        table = new JTable();
        tableModel = createTableModel();
        table.setModel(tableModel);
        table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        table.add(table.getTableHeader(), BorderLayout.PAGE_START);
        table.setFillsViewportHeight(true); 

        listSelectionModel = table.getSelectionModel();
        table.setSelectionModel(listSelectionModel);
        listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());
        table.setSelectionModel(listSelectionModel);

        this.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.gridheight = 1;
    gbc.gridwidth = 3;
    gbc.insets = new Insets(5, 5, 5, 5);
    gbc.ipadx = 2;
    gbc.ipady = 2;
    gbc.weightx = 1;
    gbc.weighty = 1;
        this.add(new JScrollPane(table), gbc);
    }

    private TableModel createTableModel() {
        DefaultTableModel model = new DefaultTableModel(
            new Object[] {"Car", "Color", "Year"}, 0 
        ){
            @Override 
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        addTableData(model);
        return model;
    }

    private void addTableData(DefaultTableModel model) {
        model.addRow(new Object[] {"Nissan", "Black", "2007"});
        model.addRow(new Object[] {"Toyota", "Blue", "2012"});
        model.addRow(new Object[] {"Chevrolet", "Red", "2009"});
        model.addRow(new Object[] {"Scion", "Silver", "2005"});
        model.addRow(new Object[] {"Cadilac", "Grey", "2001"});
    }


    class SharedListSelectionHandler implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            ListSelectionModel lsm = (ListSelectionModel) e.getSource();
            String contents = "";

            if(lsm.isSelectionEmpty()) {
                System.out.println("<none>");
            } else {
                int minIndex = lsm.getMinSelectionIndex();
                int maxIndex = lsm.getMaxSelectionIndex();
                for(int i = minIndex; i <= maxIndex; i++) {
                    if(lsm.isSelectedIndex(i)) {
                        for(int j = 0; j < table.getColumnCount(); j++) {
                            contents += table.getValueAt(i, j) + " ";
                        }
                    }
                }
                System.out.println(contents);
            }
        }

    }
}

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

This doesn't quite perform like I want it. It prints out double the information.

So instead of Chevrolet Red 2009 it prints out Chevrolet Red 2009 Chevrolet Red 2009. Ultimately I'm wanting to put the text in a JLabel and put it on the panel. Keeping in mind that the panel containing the JLabel is in a different class than the table.

Upvotes: 2

Views: 8936

Answers (3)

Andrew Thompson
Andrew Thompson

Reputation: 168825

table.getModel().addTableModelListener(tableModelListener);

See TableModel.addTableModelListener(TableModelListener) for details.


Based on the SSCCE.

GUI with details on selection

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

public class SwingTesting {

    private final JFrame frame;
    private final TablePane tablePane;
    private final JSplitPane splitPane;
    private final JPanel infoPanel;

    JTextField make = new JTextField(9);;
    JTextField color = new JTextField(7);;
    JTextField year = new JTextField(4);

    public SwingTesting() {
        tablePane = new TablePane();
        infoPanel = new JPanel(new FlowLayout(5));

        infoPanel.add(new JLabel("Make"));
        infoPanel.add(make);
        infoPanel.add(new JLabel("Color"));
        infoPanel.add(color);
        infoPanel.add(new JLabel("Year"));
        infoPanel.add(year);

        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tablePane, infoPanel);

        frame.add(splitPane);
        frame.pack();
        frame.setVisible(true);
    }

    class TablePane extends JPanel {

        private final JTable table;
        private final TableModel tableModel;
        private final ListSelectionModel listSelectionModel;

    private void setFields(int index) {
        make.setText(table.getValueAt(index, 0).toString());
        color.setText(table.getValueAt(index, 1).toString());
        year.setText(table.getValueAt(index, 2).toString());
    }

    private void clearFields() {
        make.setText("");
        color.setText("");
        year.setText("");
    }

    public TablePane() {
        table = new JTable();
        tableModel = createTableModel();
        table.setModel(tableModel);
        table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        table.add(table.getTableHeader(), BorderLayout.PAGE_START);
        table.setFillsViewportHeight(true);

        listSelectionModel = table.getSelectionModel();
        table.setSelectionModel(listSelectionModel);
        listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());
        table.setSelectionModel(listSelectionModel);

        this.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.gridheight = 1;
    gbc.gridwidth = 3;
    gbc.insets = new Insets(5, 5, 5, 5);
    gbc.ipadx = 2;
    gbc.ipady = 2;
    gbc.weightx = 1;
    gbc.weighty = 1;
        this.add(new JScrollPane(table), gbc);
    }

    private TableModel createTableModel() {
        DefaultTableModel model = new DefaultTableModel(
            new Object[] {"Car", "Color", "Year"}, 0
        ){
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        addTableData(model);
        return model;
    }

    private void addTableData(DefaultTableModel model) {
        model.addRow(new Object[] {"Nissan", "Black", "2007"});
        model.addRow(new Object[] {"Toyota", "Blue", "2012"});
        model.addRow(new Object[] {"Chevrolet", "Red", "2009"});
        model.addRow(new Object[] {"Scion", "Silver", "2005"});
        model.addRow(new Object[] {"Cadilac", "Grey", "2001"});
    }


    class SharedListSelectionHandler implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            ListSelectionModel lsm = (ListSelectionModel) e.getSource();
            String contents = "";

            if(lsm.isSelectionEmpty()) {
                System.out.println("<none>");
            } else {
                int minIndex = lsm.getMinSelectionIndex();
                int maxIndex = lsm.getMaxSelectionIndex();
                if (minIndex==maxIndex) {
                    setFields(minIndex);
                } else {
                    clearFields();
                    for(int i = minIndex; i <= maxIndex; i++) {
                        if(lsm.isSelectedIndex(i)) {
                            for(int j = 0; j < table.getColumnCount(); j++) {
                                contents += table.getValueAt(i, j) + " ";
                            }
                        }
                    }
                    System.out.println(contents);
                }
            }
        }

    }
}

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

Upvotes: 3

mKorbel
mKorbel

Reputation: 109813

I'd be use

  • table.getSelectedRow() could be safe until/without implemented RowSorter or RowFilter, otherwise you have to convertViewToModel

  • MouseListener for JToolTip

  • ListSelectionListener() is direct way how to do it, but

a) setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

b) to test if row > -1, otherwise there any row(s) isn't selected

c) then there no reason thinking or reduce I would prefer to have double/multi click disabled.

  • frame.getContentPane().add(splitPane); not required using of ContentPane from Java5

  • new SwingTesting(); please to read Initial Thread

EDIT:

how to use ListSelectionListener here, here, or top of examples is here

Upvotes: 2

Asif
Asif

Reputation: 5038

Well I think using a custom MouseListener is not as feasible as using a special ButtonColumn that can render JButton on a seperate column with each row, you just have to define a common ActionListener for the JButton.

More information can be found here: Table Button Column

Upvotes: 1

Related Questions