我有一个JTable显示书籍列表,可以过滤和排序
BookSwing.java
package com.bookretailer.ui;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import com.bookretailer.modules.Book;
import com.bookretailer.modules.utils.BookDB;
public class BookSwing extends JFrame {
private final static String TITLE = "Book Retailer - Books";
private JPanel jpInfo = new JPanel();
private JTable table;
private JTextField txtFilter;
private TableRowSorter<BookTableModel> sorter;
private BookTableModel bookTableModel;
private List<Book> booksList;
private Book selectedBook;
private ListSelectionModel listSelectionModel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BookSwing frame = new BookSwing();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public BookSwing() {
setSize(600, 650);
initData();
jpInfo.setBounds(100, 100, 600, 650);
jpInfo.setLayout(null);
JPanel tbPanel = new JPanel();
tbPanel.setBorder(new TitledBorder(null, "", TitledBorder.LEADING, TitledBorder.TOP, null, null));
tbPanel.setBounds(10, 331, 570, 272);
jpInfo.add(tbPanel);
tbPanel.setLayout(null);
bookTableModel = new BookTableModel(booksList);
table = new JTable();
table.setModel(bookTableModel);
sorter = new TableRowSorter<BookTableModel>(bookTableModel);
table.setAutoCreateRowSorter(true);
table.setRowSorter(sorter);
final JTableHeader header = table.getTableHeader();
header.setDefaultRenderer(new HeaderRenderer(table));
List<RowSorter.SortKey> sortKeyList = new ArrayList<RowSorter.SortKey>();
sortKeyList.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeyList);
sorter.sort();
sorter.setSortsOnUpdates(true);
txtFilter = new JTextField();
// Whenever filterText changes, invoke newFilter.
txtFilter.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
filterBook();
}
public void insertUpdate(DocumentEvent e) {
filterBook();
}
public void removeUpdate(DocumentEvent e) {
filterBook();
}
});
JScrollPane scrollPane = new JScrollPane(table);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
initDetail(table.getSelectedRow());
}
});
scrollPane.setBounds(6, 37, 558, 225);
tbPanel.add(scrollPane);
listSelectionModel = table.getSelectionModel();
table.setSelectionModel(listSelectionModel);
listSelectionModel.addListSelectionListener(new ListSelectionHandler());
table.setSelectionModel(listSelectionModel);
JLabel lblBookFilter = new JLabel("Book Filter");
lblBookFilter.setBounds(10, 10, 78, 25);
tbPanel.add(lblBookFilter);
txtFilter.setBounds(75, 10, 489, 25);
tbPanel.add(txtFilter);
txtFilter.setColumns(10);
getContentPane().add(jpInfo);
}
private void initData() {
booksList = BookDB.getBookList();
}
protected void initDetail(int selectedRow) {
selectedBook = booksList.get(selectedRow);
}
private void refreshTableData() {
table.revalidate();
table.repaint();
table.getSelectionModel().clearSelection();
bookTableModel.fireTableDataChanged();
}
private void filterBook() {
RowFilter<TableModel, Object> rf = null;
// If current expression doesn't parse, don't update.
try {
rf = RowFilter.regexFilter("(?i)" + txtFilter.getText());
} catch (java.util.regex.PatternSyntaxException e) {
return;
}
sorter.setRowFilter(rf);
}
class BookTableModel extends AbstractTableModel {
List<Book> booksList;
String[] headerList = { "Book Code", "Title", "Price" };
Class[] classes = { Integer.class, String.class, Double.class };
public BookTableModel(List<Book> list) {
booksList = list;
}
@Override
public int getColumnCount() {
return headerList.length;
}
@Override
public int getRowCount() {
return booksList.size();
}
@Override
public Class<?> getColumnClass(int arg0) {
// TODO Auto-generated method stub
return classes[arg0];
}
// this method is called to set the value of each cell
@Override
public Object getValueAt(int row, int column) {
Book entity = null;
entity = booksList.get(row);
switch (column) {
case 0:
return entity.getBookId();
case 1:
return entity.getTitle();
case 2:
return entity.getPrice();
default:
return "";
}
}
// This method will be used to display the name of columns
public String getColumnName(int col) {
return headerList[col];
}
@Override
public void setValueAt(Object value, int row, int col) {
Book entity = null;
entity = booksList.get(row);
switch (col) {
case 0:
entity.setBookId((Integer) value);
break;
case 1:
entity.setTitle((String) value);
break;
case 2:
entity.setPrice((Double) value);
break;
default:
break;
}
fireTableCellUpdated(row, col);
}
}
private static class HeaderRenderer implements TableCellRenderer {
TableCellRenderer renderer;
public HeaderRenderer(JTable table) {
renderer = table.getTableHeader().getDefaultRenderer();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int col) {
return renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
}
}
class ListSelectionHandler implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
ListSelectionModel model = table.getSelectionModel();
int lead = model.getLeadSelectionIndex();
setFields(lead);
}
}
}
private void setFields(int index) {
System.out.println(booksList.get(index).getTitle());
}
}
我想在用户点击表格行时设置selectedBook 当用户没有过滤或排序数据时它工作正常,但当用户排序数据时,selectedBook被分配错误的书
如何使其正常工作以便将正确的书籍分配给selectedBook
答案 0 :(得分:15)
使用此代码:
selectedBook = booksList.get(table.convertRowIndexToModel(selectedRow));
答案 1 :(得分:4)
您需要将视图中的行索引转换为模型中的索引。如果您允许排序,这些是不同的事情。这包括in this question。在你的情况下,你应该这样做:
selectedBook = booksList.get(table.convertRowIndexToModel(selectedRow));
答案 2 :(得分:0)
int索引= table.getSelectRow(); 图书= booksList.get(index);