让Swing表格支持远程后台数据翻页

开发 后端
不过,这个可以翻页的表格,只能翻页本地数据。也就是说,它只能翻已经放入TDataBox中的数据。例如我们一次性在TDataBox中加入了10000条数据。

TWaver Java不但提供了TTable、TElementTable这些表格组件,而且还提供了表格翻页器TPageNavigator。让表格和翻页器结合工作,可以立刻做出一个非常标准的可翻页的表格界面,如下图。

 

要让这两个组件一起工作,直接这样new一个实例,并放在界面上就可以了:

  1. TElementTable table = new TElementTable();  
  2. int[] pageSizes = { 1005001000 };  
  3. TPageNavigator nav=new TPageNavigator(table.getTablePaging(), pageSizes) 

其中nav就是一个普通的JPanel,可以放在界面的任何位置。而table可以和nav在界面上完全脱离显示,如何布局都可以。

不过,这个可以翻页的表格,只能翻页本地数据。也就是说,它只能翻已经放入TDataBox中的数据。例如我们一次性在TDataBox中加入了10000条数据,可以通过这个翻页器进行“每页100条、共有100页”这样的翻页操作。但是大多时候,我们需要的并不是“本地翻页”,而是“远程翻页”。所谓的远程翻页,也就是在每次翻页时候,TDataBox的数据需要被清空,并从远程服务器动态重新获取“下一页”的数据进行TDataBox加载并且显示。

如何做到这一点呢?只要用了TWaver Java这一“神器”,做到这一点就不难了。本文就通过一个例子,来说明如何定制一个翻页器,来拦截翻页动作,并从服务器获取翻页数据,进行动态显示。

TElementTable的翻页,实际上是靠一个TablePaging的接口来完成的。TWaver Java靠一个默认的TablePaging实现来完成了本地翻页。而我们要做的,就是创建一个远程翻页的TablePaging,来代替这个默认实现即可。

TablePaging接口定义了下面这些函数。大多数的函数,都是在问你一些简单的远端数据方面的问题:一共有多少记录?一页有多少条记录?一共有多少页?当前是第几页?

并且在***页、***一页、上一页、下一页等操作发生时,回调这个接口。所以,我们只要有了后台数据,就不难回答这些问题。 

  1. public interface TablePaging {  
  2.      public int getCurrentPageIndex();  
  3.      public void setCurrentPageIndex(int currentPageIndex);  
  4.      public int getPageRowSize();  
  5.      public void setPageRowSize(int pageRowSize);  
  6.      public int getPageTotalCount();  
  7.      public int getTotalRowCount();  
  8.      public void firstPage();  
  9.      public void previousPage();  
  10.      public void nextPage();  
  11.      public void lastPage();  
  12.      public void update();  
  13.      public void addPageListener(PageListener pageListener);  
  14.      public void removePageListener(PageListener pageListener);  
  15.  }  

以上函数基本上都可以顾名思义地理解,就不多作介绍了。我们现在假设后台有一个数据库,里面有一个客户地址的table。通过一个SQL查询服务,我们可以获得这些翻页数据。根据这个假设,我们可以做下面的实现。

  1. public class AddressTablePaging implements TablePaging {  
  2.      private SearchPane parent = null;  
  3.      private List pageListeners = new ArrayList();  
  4.      private TElementTable table = null;  
  5.      private int pageIndex = 1;  
  6.      private int pageSize = 100;  
  7.    
  8.      public AddressTablePaging(TElementTable table, SearchPane parent) {  
  9.          this.table = table;  
  10.          this.parent = parent;  
  11.      }  
  12.    
  13.      private void loadPage() {  
  14.          table.getDataBox().clear();  
  15.          try {  
  16.              int start = (pageIndex - 1) * pageSize;  
  17.              Collection<AddressVO> data = Server.searchAddress(..);  
  18.              for (AddressVO vo : data) {  
  19.                  Node node = new Node();  
  20.                  node.setBusinessObject(vo);  
  21.                  table.getDataBox().addElement(node);  
  22.              }  
  23.          } catch (Exception ex) {  
  24.              ex.printStackTrace();  
  25.              JOptionPane.showMessageDialog(table, ex.getMessage());  
  26.          }  
  27.          firePageChanged();  
  28.      }  
  29.    
  30.      @Override 
  31.      public void firstPage() {  
  32.          pageIndex = 1;  
  33.          loadPage();  
  34.      }  
  35.    
  36.      @Override 
  37.      public int getCurrentPageIndex() {  
  38.          return this.pageIndex;  
  39.      }  
  40.    
  41.      @Override 
  42.      public int getPageRowSize() {  
  43.          return this.pageSize;  
  44.      }  
  45.    
  46.      @Override 
  47.      public int getPageTotalCount() {  
  48.          try {  
  49.              int totalCount = getTotalRowCount();  
  50.              int pageCount = totalCount / getPageRowSize();  
  51.              if (totalCount % getPageRowSize() > 0) {  
  52.                  pageCount++;  
  53.              }  
  54.              return pageCount;  
  55.          } catch (Exception ex) {  
  56.              ex.printStackTrace();  
  57.          }  
  58.          return 0;  
  59.      }  
  60.    
  61.      @Override 
  62.      public int getTotalRowCount() {  
  63.          try {  
  64.              return Server.getAddressTotalCount(.);  
  65.          } catch (Exception ex) {  
  66.              ex.printStackTrace();  
  67.          }  
  68.          return 0;  
  69.      }  
  70.    
  71.      @Override 
  72.      public void lastPage() {  
  73.          this.pageIndex = getPageTotalCount();  
  74.          this.loadPage();  
  75.      }  
  76.    
  77.      @Override 
  78.      public void nextPage() {  
  79.          this.pageIndex++;  
  80.          this.loadPage();  
  81.      }  
  82.    
  83.      @Override 
  84.      public void previousPage() {  
  85.          if (this.pageIndex > 1) {  
  86.              pageIndex--;  
  87.          }  
  88.          this.loadPage();  
  89.      }  
  90.    
  91.      @Override 
  92.      public void setCurrentPageIndex(int pageIndex) {  
  93.          this.pageIndex = pageIndex;  
  94.      }  
  95.    
  96.      @Override 
  97.      public void setPageRowSize(int pageSize) {  
  98.          this.pageSize = pageSize;  
  99.      }  
  100.    
  101.      @Override 
  102.      public void addPageListener(PageListener pageListener) {  
  103.          this.pageListeners.add(pageListener);  
  104.      }  
  105.    
  106.      @Override 
  107.      public void removePageListener(PageListener pageListener) {  
  108.          this.pageListeners.remove(pageListener);  
  109.      }  
  110.    
  111.      public void firePageChanged() {  
  112.          for (int i = 0; i < this.pageListeners.size(); i++) {  
  113.              PageListener pageListener = (PageListener) this.pageListeners.get(i);  
  114.              pageListener.pageChanged();  
  115.          }  
  116.      }  
  117.    
  118.      @Override 
  119.      public void update() {  
  120.      }  
  121.  } 

在上面代码中,所有的翻页函数,都会集中调用loadPage()这个函数,从后台真正获取数据。而函数getTotalRowCount则负责
从后台获得“一共有多少条记录”。其他函数,基本进行转发即可。

另外一个需要注意的就是removePageListener/addPageListener等函数。主要用于对监听器进行管理,包括注册、删除、触发通知等等。

这些也是必须要实现的,不过很简单,用一个ArrayList维护就行了,触发时间时候,直接遍历、回调即可。

具体通过SQL从后台调用数据的实现,这里就不介绍了。相信每一个实际项目都有不同的数据库、接口、调用方法方面的差别。这里只是点到为止。

有了这个翻页器,我们就可以直接用在表格中了。下面继承一个表格,并用这个翻页器。

  1. public class AddressTable extends TElementTable {     
  2.      public AddressTablePaging getTablePaging() {  
  3.          return tablePaging;  
  4.      }  
  5.        
  6.  }  

这样,默认翻页器被替换,新的后台翻页器被置入表格中。***,再通过本文最开始提供的两行代码把表格放入界面中,程序就基本完成了。

  1. int[] pageSizes = { 1005001000 };  
  2. this.add(new TPageNavigator(table.getTablePaging(), pageSizes), BorderLayout.CENTER); 

其中pageSizes数组是定义了界面上每页条数的下拉列表选项,我们可以根据实际应用自己设置,如下图:

 

这样,一个完整的后台翻页程序就完成了。给表格设置好列、在后台添加一些数据,跑起来会是这样(翻页观看)

#p#

 

如果再增加一些查询字段等,就更帅了:

对了,***,再顺便给大家介绍一下表格中的可点击连接是如何做的:

 

要做这种可点击链接,首先要做3件事:1是显示link,2是显示手形状的光标,3是响应鼠标点击动作。对于1,可以来个“釜底抽薪”:在表格上从根儿上拦截prepareRenderer然后对文字动态修改为html的a标签的连接方式进行处理:

  1. @Override 
  2. public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {  
  3.     Element element = this.getElementByRowIndex(row);  
  4.     AddressVO vo = (AddressVO) element.getBusinessObject();  
  5.     Component com = super.prepareRenderer(renderer, row, column);  
  6.     if (!vo.isValid()) {  
  7.         com.setForeground(Color.red);  
  8.     } else {  
  9.         com.setForeground(Color.black);  
  10.     }  
  11.  
  12.     if (column == 2 || column == 3) {  
  13.         String text = ((JLabel) com).getText();  
  14.         text = "<html><a href=\"#\">" + text + "</a></html>";  
  15.         ((JLabel) com).setText(text);  
  16.     }  
  17.     return com;  

对于手形光标,可以通过监听鼠标移动,是否位于链接文字上方来动态修改光标:

  1. this.addMouseMotionListener(new MouseMotionAdapter() {  
  2.      @Override 
  3.      public void mouseMoved(MouseEvent e) {  
  4.          int row = rowAtPoint(e.getPoint());  
  5.          int column = columnAtPoint(e.getPoint());  
  6.          setCursor(Cursor.getDefaultCursor());  
  7.          if (row >= 0 && column >= 0) {  
  8.              if (column == 2 || column == 3) {  
  9.                  setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));  
  10.              }  
  11.          }  
  12.      }  
  13.  }); 

***,对于点击动作,可以通过给table添加鼠标监听器完成:

  1. this.addMouseListener(new MouseAdapter() {  
  2.      @Override 
  3.      public void mouseClicked(MouseEvent e) {  
  4.          int row = rowAtPoint(e.getPoint());  
  5.          int column = columnAtPoint(e.getPoint());  
  6.          setCursor(Cursor.getDefaultCursor());  
  7.          if (row >= 0 && column >= 0) {  
  8.              if (column == 2 || column == 3) {  
  9.                  Object value = getValueAt(row, column);  
  10.                  //do your action here.  
  11.              }  
  12.          }  
  13.      }  
  14.  }); 

至此,一个完整的可后台翻页、可鼠标点击超链接的综合型table就完成了。在实际使用中,还可以增加更复杂的翻页和显示效果。例如在TWaver的兄弟产品2BizBox免费ERP软件中,就有大量这样的应用,感兴趣的朋友可以到2BizBox.cn去下载安装一个玩一玩。

 

原文链接:http://www.blogjava.net/TWaver/archive/2012/08/03/384716.html

【编辑推荐】

  1. Swing杂记:引入Android的NinePatch技术
  2. JVM的内存溢出异常
  3. Java中的异常对程序效率有无影响
  4. ASP.NET中使用App_Code文件夹的异常
  5. Tomcat中部署后JspFactory报异常的解决方案
责任编辑:张伟 来源: blogjava
相关推荐

2009-12-02 10:33:34

LINQ to SQL

2012-01-17 14:09:54

JavaSwing

2011-03-31 17:02:19

MySQL数据库远程连接

2010-08-18 09:03:46

jQueryJSONTrimpath

2009-07-16 13:26:32

Swing增加

2015-09-08 14:52:22

微信应用数据

2010-08-26 14:16:18

DB2.NET开发

2017-05-18 10:43:36

热点图大数据CPU

2022-03-07 14:38:10

数据中心人工智能

2017-02-05 17:27:43

2009-07-10 11:31:45

Swing支持透明和不规则窗口

2009-07-03 14:23:49

JSP数据分页

2010-03-23 11:55:32

云计算

2012-03-01 11:54:00

2024-09-21 10:38:19

2009-07-10 11:25:48

Swing应用数据验证

2009-02-09 10:02:00

远程终端服务

2011-05-16 10:41:43

MYSQL

2023-11-30 15:10:20

物联网数据物联网平台

2017-03-17 16:10:24

linux进程后台
点赞
收藏

51CTO技术栈公众号