3

我有一个显示书籍列表的 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

4

3 回答 3

17

使用此代码:

selectedBook = booksList.get(table.convertRowIndexToModel(selectedRow));
于 2012-06-06T20:13:22.747 回答
4

您需要将视图中的行索引转换为模型中的索引。如果您允许排序,这些是不同的东西。这个问题涵盖了这一点。在你的情况下,你应该这样做:

selectedBook = booksList.get(table.convertRowIndexToModel(selectedRow));
于 2012-06-06T20:13:00.203 回答
1

int index = table.getSelectRow(); Book book = booksList.get(index);

于 2020-01-29T13:50:21.070 回答