Java Swing中关于JTable的一些总结

上周继续用Swing做小项目,其中我在实现数据的查询过程中发现,以往的习惯是更新数据筛选条件都要去数据库中重新查询,但是我把数据库部署到云端发现这样查询数据压力较大,程序运行很慢,最好是少执行数据库的操作,多在本地实现数据的修改,于是我就仔细研究了研究JTable的一些功能,发现JTable的作为容器还是可以往里面添加一些控件来调用RowSorter对表中数据进行筛选和排序的。

一,通过点击列名实现数据排序

  

单击表头,可以针对这一列进行排序,代码很简单

	final TableRowSorter ts;
        ts = new TableRowSorter(jTable1.getModel());  //由于使用的NetBeans做的,Jtable已经new好了,故此省略
        jTable1.setRowSorter(ts);
只需给要筛选的table设置一个RowSorter即可


二,实现Excel中每列筛选的功能

  

这里我采用的方式是在往表里添加数据的同时往Jcombobox中也添加item,当然还要考虑重复的问题,这样保证筛选选项都是已出现的数据,我的理想状态是能把Jcombobox放到table的表头TableHeader里面去,但是翻了不少代码发现自己弄不明白,只好暂时放弃,若有高人指点不胜感谢!

	//接上面的代码,还是使用获取的TableRowSorter
        ts.setRowFilter(RowFilter.regexFilter(jCB1.getSelectedItem().toString(), 0));  //(要匹配的值,列的下标)


三,添加JCheckbox实现多选/全选数据

   
只要设置一下tablemodel ,这样表中的boolean会被自动显示成一个checkbox,我把它放到第一列

table.setModel(new DefaultTableModel(){      //重写DefaultTableModel的getColumnClass方法,若是在NetBeans中的话需要定制代码
	@Override
	public Class getColumnClass(int columnIndex)	{
		Object value = getValueAt(0, columnIndex);
		if(value!=null){
			return value.getClass();
                }
		else{
			return super.getClass();
                }
	}
});
接下来是给表头中画一个checkbox用以全选,注意是画出来的也就是说只具有显示效果,单击全选的效果还需要单击事件实现

class MyCheckBoxRenderer extends JCheckBox implements TableCellRenderer {

    public MyCheckBoxRenderer() {
        this.setBorderPainted(true);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        // TODO Auto-generated method stub		
        return this;
    }
}
final MyCheckBoxRenderer check = new MyCheckBoxRenderer();
        table.getColumnModel().getColumn(0).setHeaderRenderer(check);
        table.getTableHeader().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (table.getColumnModel().getColumnIndexAtX(e.getX()) == 0) {//如果点击的是第0列,即checkbox这一列
                    JCheckBox Checkbox = (JCheckBox) check;
                    boolean b = !check.isSelected();
                    check.setSelected(b);
                    table.getTableHeader().repaint();
                    for (int i = 0; i < table.getRowCount(); i++) {
                        table.getModel().setValueAt(b, i, 0);//把这一列都设成和表头一样
                    }
                }
            }
        });
这样效果就达到了,我还给table内容加了一个MouseClicked,单击某一行就改变这一行的选中状态,也就是改变第一列的boolean值即可,就不贴代码了。


四,设置table背景透明

这种效果在web上是很容易的,我想在Swing上实现想来想去还是得用table,但是如果没有内容填充的话table的的背景太丑了,通过多方查找先总结如下:

首先JTable是存在于JScrollPane这个容器上的,也需要把这个容器设为透明

	jScrollPane.getViewport().setOpaque(false);
        jScrollPane.setOpaque(false);
这时候再把table设置成透明

	jTable.setOpaque(false);
但是这个时候每一行的数据还不是透明的,没了边框后反而更丑了,需要设置透明的渲染器来渲染每一行

	DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setHorizontalAlignment(SwingConstants.CENTER);  //这里是设置了字体居中
        renderer.setOpaque(false);//渲染器设置为透明
        jTable.getColumnModel().getColumn(0).setCellRenderer(renderer);  //这里因为我只用了一列,所以只getColumn(0)来进行设置

五,根据需要设置某一行字体

接上面的图,我是想做成邮箱那个效果,未读消息加粗,点击查看后字体恢复原样,查找后明白,同样需要设置渲染器来达到这个效果。

重写DefaultTableCellRenderer的getTableCellRendererComponent方法

public class MessageFont extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        if (((Message)value).getMstate().equals("0")) {    //这里我是判断的放入表中的数据对象中的某一个值,可根据具体情况修改
            Font tempF = cell.getFont();
            String NameF = tempF.getName();
            //int StyleF = tempF.getStyle();
            int SizeF = tempF.getSize();
            cell.setFont(new Font(NameF, Font.BOLD, SizeF));  	//重新设定Font,具体查看API
            return cell;
        } else {
            return cell;
        }
    }
}
这样结合上面的同时设置为透明的需求的话代码应该是这样

        MessageFont renderer = new MessageFont();
        renderer.setHorizontalAlignment(SwingConstants.CENTER);
        renderer.setOpaque(false);//渲染器设置为透明
        jTable.setOpaque(false);//table设置透明  再此之前已将JScrollPane设置为透明
        jTable.getColumnModel().getColumn(0).setCellRenderer(renderer);


至此,我想要的效果就基本达到了,但是还有很多不懂的东西仍需研究,比如setCellRenderer和setCellEditor的结合使用等等,以后有了新的收获会继续添加。

参考资料:

http://blog.csdn.net/b_h_l/article/details/7771944

http://my.oschina.net/soitravel/blog/35425

http://www.blogjava.net/zeyuphoenix/archive/2010/04/08/317755.html

你可能感兴趣的:(Java)