Reputation: 926
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:
table.getSelectedRow()
MouseListener()
ListSelectionListener()
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
Reputation: 168825
table.getModel().addTableModelListener(tableModelListener);
See TableModel.addTableModelListener(TableModelListener)
for details.
Based on the SSCCE.
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
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
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