论坛首页 Java企业应用论坛

当JXTreeTable遇到TristateCheckBox(三)

浏览 3607 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-01-27   最后修改:2009-05-06

这篇小文是本系列( 第一部分 第二部分 )的最终章。主要说下与checkboxtreetable组件相关的几个hack技巧。


运行本demo

 

  1. 在本系列的第一部分下载 jxtreetable_with_checkbox.zip 到本地并解压。
  2. NetBeans主菜单依次选择“文件”——“打开项目”。
  3. 在弹出的“打开项目”对话框中选择刚才解压之后的jxtreetable_with_checkbox目录,点击“打开项目”按钮。
  4. 在附件中下载TestFrame3.zip解压为TestFrame3.java放到cn.vearn.checktreetable包下。
  5. 在附件中下载CheckTreeTableManager2.zip解压为CheckTreeTableManager2.java放到org.jdesktop.swingx.ux包下。
  6. “项目”视图选中TestFrame3,按Shift + F6运行文件。
  7. 点击“显示highlighter”复选按钮,可以切换是否Highlighter。
  8. 点击“禁止列交换”复选按钮,可以切换是否允许通过鼠标拖拽进行列交换。

 

#1 设置Highlighter

 

swingx中的Highlighter内容很丰富,不过在这里只是简单地对奇偶行用不同背景色。实现这个很简单:

 

checkbox1 = new JCheckBox("显示highlighter");
checkbox1.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        treetable.setHighlighters(checkbox1.isSelected() ? HighlighterFactory.createSimpleStriping() : null);
    }
});

 

效果是这个样子的:


 

#2 禁止列交换

 

JTable有这样一个特性:通过鼠标拖拽表头中某一列可以对列进行交换。checkboxtreetable也继承了这个特性。不过这导致了一个问题,如果将包含JTree的第一列交换后(见下图),我们无法通过点击树节点之前的checkbox来改变选中状态了。这是由于CheckTreeTableManager通过监听mouseClicked事件来判断鼠标点击坐标,来选中树节点之前的checkbox,交换列之后改变了坐标位置,导致不能改变树节点之前的checkbox。


解决方法也很简单,禁止列交换就可以了:

 

checkbox2 = new JCheckBox("禁止列交换");
checkbox2.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        treetable.getTableHeader().setReorderingAllowed(checkbox2.isSelected() ? false : true);
    }
});

 

要是希望含JTree的第一列固定,其他列可以交换可以吗?可以的,不过有点麻烦:

 

treetable = new JXTreeTable(new TestTreeTableModel(createDummyData())) {
            protected JTableHeader createDefaultTableHeader() {
                return new JTableHeader(columnModel) {
                    @Override
                    public void setDraggedColumn(TableColumn aColumn) {
                        if (aColumn == getColumnModel().getColumn(0)) {
                            return;
                        }
                        super.setDraggedColumn(aColumn);
                    }
                };
            }

            protected TableColumnModel createDefaultColumnModel() {
                return new DefaultTableColumnModel() {
                    public void moveColumn(int columnIndex, int newIndex) {
                        if (columnIndex == 0 || newIndex == 0) {
                            return;
                        }
                        super.moveColumn(columnIndex, newIndex);
                    }
                };
            }
        }; //  JXTreeTable构造方法

 

#3 更换CheckTreeTableManager

 

在#2中我们已经发现一个问题,也就是CheckTreeTableManager实际上是以一种hack手段(判断点击坐标位置)来改变checkbox的状态。那么我们换一种方式来实现,通过选中一行(或多行)来选中树节点前的checkbox,用TreeSelectionListener来监听用户事件:

 

public void valueChanged(TreeSelectionEvent e) {
      TreePath path = e.getPath();
      ...
}

 

获得TreePath的引用之后,就和之前的实现一样了。不过这种方式也带来了几个问题:

 

  1. 选中chechbox的行为比较怪异,其他UI库中的checkboxtreetable都是通过点击树节点前的checkbox来改变其状态。
  2. 只要在某一行点击,就会改变checkbox状态,容易误操作。
  3. 先选中一个树节点的checkbox,如果想取消选中,需要按住Ctrl在取消选中该行(Windows环境下),很麻烦。

CheckTreeTableManager和CheckTreeTableManager2究竟如何选择,看您了。

 

后记

 

虽然swing在国内比较冷清,但我还是尽力写好这个系列。是santhosh 的文章帮助我在项目中用上了checkboxtreetable,那么我也希望对社区做一些贡献。能帮上一个人少走些弯路,目的就达到了。本系列至此全部结束,谢谢大家!

 

  • 大小: 18.7 KB
  • 大小: 20.9 KB
   发表时间:2009-08-12  
Greate!期待您有更加精彩的教程出来!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics