问题
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.
回答1:
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();
}
});
}
}
回答2:
I'd be use
table.getSelectedRow()could be safe until/without implementedRowSorterorRowFilter, otherwise you have toconvertViewToModelMouseListenerforJToolTipListSelectionListener()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 ofContentPanefrom Java5new
SwingTesting();please to read Initial Thread
EDIT:
how to use ListSelectionListener here, here, or top of examples is here
回答3:
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
来源:https://stackoverflow.com/questions/10606521/display-the-information-of-a-jtable-row-when-selected