主要涉及到JTable,DefaultTableModel,RowFileter等类;
使用场景:对图书的搜索和删改,其中图书数据用JTable放入;其中,搜索后会显示出更据关键词出来的信息;然后如果关键词为“”,即空字符串;在点击搜索就等于显示全部;
bug:不输入任何数据点击搜索时数据不会改变,或者直接没了;总之不能显示所有数据;
文章目录
- 一、图书信息页
- 二、搜索图书的实现
- 1.修改前代码
- 查询的逻辑
一、图书信息页
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
public class BookInfFrame extends MinorFrame{
private JTable table;
private DefaultTableModel tdm;
private int foucusCount = 0;
private JTextField jtf1;
private List<Book> data;
String[] columnNames = {"编号", "图书名称", "图书作者", "价格"};
public BookInfFrame(String title, int width, int height) {
super(title, width, height);
}
static int count = 0 ;
public BookInfFrame() {
super("图书信息",900 , 700);
initFrame();
}
private void initFrame() {
count++;
System.out.println("bookInfo initFrame 执行"+count);
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
initTable();
JLabel jl1 = new JLabel("图书名称或作者:");
jtf1 = new JTextField("输入图书名称或者作者");
// jtf1.setFont(new Font("楷体",Font.ITALIC,16));
jtf1.setToolTipText("输入搜索的图书名称或作者名称");
JPanel jp2 = new JPanel();
jp2.add(jtf1);
JButton jb = new JButton("查询");
JPanel jp1 = new JPanel();
jp1.add(jl1);
jp1.add(jp2);
jp1.add(jb);
jp.add(jp1,BorderLayout.NORTH);
JScrollPane j = new JScrollPane(table);
jp.add(j,BorderLayout.CENTER);
JButton jbDel = new JButton("删除");
JButton jbMod = new JButton("修改");
Box opBox = Box.createHorizontalBox();
opBox.add(Box.createHorizontalGlue());
opBox.add(jbDel);
opBox.add(jbMod);
opBox.add(Box.createHorizontalGlue());
jp.add(opBox,BorderLayout.SOUTH);
setContentPane(jp);
jbDel.addActionListener(e->delelte());
jbMod.addActionListener(e->modifty());
jb.addActionListener(e->search());
//todo当输入框清除之后需要显示所有数据
jtf1.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
}
@Override
public void focusGained(FocusEvent e) {
foucusCount++;
//第一次点击input框,清楚input text
if(foucusCount == 1)
jtf1.setText("");
}
});
}
//todo 修改,bug,修改后数据并不会更行
//√
private void modifty() {
int select = table.getSelectedRow();
if(select == -1) {
JPaneUtil.showErr(this, "你还没有选择修改的图书");
}
//弹出修改框,需要把整个model传入到修改信息中;
JFrame frame = new BookModifyFrame(this.data.get(select));
JFrame THIS = this;
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
//disposze是否触发?,会触发
THIS.setEnabled(true);
// requestFocus();
//
BookDao dao = new BookDao();
//异步执行,所以只能放在监听函数里面
//获取修改后的数据
Book newBook = dao.queryById(data.get(select).getId());
data.set(select, newBook);//与等号有什么区别
setTableRow(newBook, tdm, select);
}
});
// THIS.setEnabled(true);
}
private void setTableRow(Book book,DefaultTableModel dtm,int row) {
System.out.println("new book"+book);
dtm.setValueAt(book.getId(), row, 0);
dtm.setValueAt(book.getBookName(), row, 1);
dtm.setValueAt(book.getAuthor(), row, 2);
dtm.setValueAt(book.getPrice(), row, 3);
//改变数据
//通知数据改变
dtm.fireTableRowsUpdated(row, row);
}
//删除所选中的书
private void delelte() {
int select = table.getSelectedRow();
if(select == -1) {
JPaneUtil.showErr(this, "你还没有选择删除的图书");
}
//询问狂
if(JOptionPane.OK_OPTION == JPaneUtil.showConfirm(this, "你确定删除这条信息嘛?"))
{
String id = this.data.get(select).getId();
//database delete
BookDao dao = new BookDao();
dao.delete(id);
tdm.removeRow(select);
table.updateUI();
//or
// tdm.fireTableDataChanged();
JPaneUtil.showOk(this, "删除成功!");
}
}
//√
private void search() {
//
String text = jtf1.getText();
if(text.equals("")) {
System.out.println("triiger search all");
tdm.setRowCount(0);//清除表格数据
//貌似这里会出错
//h=好像要重新设置一个tableModel 还是出错
//从table中获取莫模型再试一下 bug
BookDao dao = new BookDao();
if(this.data == null)
this.data = dao.queryByAll();
DefaultTableModel tm = (DefaultTableModel) table.getModel();
tm.setDataVector(listTo2Array(this.data), this.columnNames);
// table.setModel(tm);
//todo blog ,太他妈坑了,之前的没啥问题,应该是之前设置了rowSorter,然后进行设置数据的时候他也默认把rowRowSorter给方静去了;
table.setRowSorter(null);
table.updateUI();
return;
}
TableRowSorter<TableModel> t = new TableRowSorter<TableModel>(tdm);
System.out.println("rowfilter 触发 text="+text);
String regex = "^"+text+"$";
RowFilter<Object, Object> nameFilter = RowFilter.regexFilter(regex,1,2);
t.setRowFilter(nameFilter);
table.setRowSorter(t);
table.updateUI();
}
//初始化表格
private void initTable() {
//创建表格
Object[][] rowType = getAllBooks();
tdm = new DefaultTableModel(rowType, columnNames);
table = new JTable(tdm) {
@Override
public boolean isCellEditable(int row, int column) {
return false; //不可编辑,但可以选择
}
};
//
DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();//单元格渲染器
dtcr.setHorizontalAlignment(JLabel.CENTER);//居中显示
table.setDefaultRenderer(Object.class, dtcr);//设置渲染器t
table.getColumnModel().getColumn(0).setPreferredWidth(100);
table.getColumnModel().getColumn(1).setPreferredWidth(200);
table.getColumnModel().getColumn(2).setPreferredWidth(80);
table.getColumnModel().getColumn(3).setPreferredWidth(50);
table.getTableHeader().setReorderingAllowed(false); //不可改变列的位置
//设置表格只能单选;
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
private Object[][] getAllBooks() {
// TODO Auto-generated method stub
BookDao bd = new BookDao();
List<Book> books = bd.queryByAll();
this.data = books;
String[][] obj = new String[books.size()][4];
for(int i = 0 ; i < books.size(); i++) {
Book b = books.get(i);
obj[i] =b.toString().split(" +");
System.out.println(b);
}
return obj;
}
private Object[][] listTo2Array(List<Book> books) {
// TODO Auto-generated method stub
// BookDao bd = new BookDao();
// List<Book> books = bd.queryByAll();
// this.data = books;
//
//
String[][] obj = new String[books.size()][4];
for(int i = 0 ; i < books.size(); i++) {
Book b = books.get(i);
obj[i] =b.toString().split(" +");
System.out.println("list 2 arry +"+obj[i][1].toString());
}
return obj;
}
public static void main(String[] args) {
JFrame jf = new BookInfFrame();
jf.setVisible(true);
}
}
界面显示:
二、搜索图书的实现
1.修改前代码
//√
private void search() {
//
String text = jtf1.getText();
if(text.equals("")) {
System.out.println("triiger search all");
tdm.setRowCount(0);//清除表格数据
//貌似这里会出错
//h=好像要重新设置一个tableModel 还是出错
//从table中获取莫模型再试一下 bug
BookDao dao = new BookDao();
if(this.data == null)
this.data = dao.queryByAll();
DefaultTableModel tm = (DefaultTableModel) table.getModel();
tm.setDataVector(listTo2Array(this.data), this.columnNames);
// table.setModel(tm);
//table.setRowSorter(null);
table.updateUI();
return;
}
TableRowSorter<TableModel> t = new TableRowSorter<TableModel>(tdm);
System.out.println("rowfilter 触发 text="+text);
String regex = "^"+text+"$";
RowFilter<Object, Object> nameFilter = RowFilter.regexFilter(regex,1,2);
t.setRowFilter(nameFilter);
table.setRowSorter(t);
table.updateUI();
}
代码主要逻辑:如果输入框为空,点击搜索则显示全部信息,如果有文字就按照文字搜索;按照关键字搜索并不是走的后端查询,而是运用了JTable中Sorter和Filter;
查询的逻辑
先构造tableRowSorter,更据t构造Rowfilter,RowFilter采用的是regexFilter(Stirng args,…colum);第一个参数是设置正则表达式,即你所要搜寻的东西,第二个参数是你在哪几列查询;例如以上代码,即查询text,然后在第一列和第二列查询;更据上述的运行图,即为作者和图书名;
但是当清除input框后,数据出错:
改了很久,发现可能是在之前为table设置了一个sorter,然后之后的数据操作都是基于这个sorter的,所以是不是应该尝试把这个sorter给清空。但查看后没发现此方法,就死马当活🐎yi,加入了以下这行代码:
table.setRowSorter(null);
后面发现没有问题,目前查看源码还没发现什么原因;