关于JavaSwing中JTable数据刷新以及数据排序问题

主要涉及到JTable,DefaultTableModel,RowFileter等类;
使用场景:对图书的搜索和删改,其中图书数据用JTable放入;其中,搜索后会显示出更据关键词出来的信息;然后如果关键词为“”,即空字符串;在点击搜索就等于显示全部;
bug:不输入任何数据点击搜索时数据不会改变,或者直接没了;总之不能显示所有数据;

一、图书信息页

示例: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);
后面发现没有问题,目前查看源码还没发现什么原因;

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值