java swing项目桌面软件仍是蛮香的,至少有了我本身的桌面软件|Java 开发实战

这是我参与更文挑战的第5天,活动详情查看: 更文挑战java

本文正在参加「Java主题月 - Java 开发实战」,详情查看 活动连接web

最近利用空闲时间本身琢磨了一下java swing 编程,其实在从事javaweb以前我一直向往的就是java swing 开发,不知道为何可能当时以为Windows上的exe程序非常神奇,关于windows上制做exe我以前也有介绍编程

exe打包教程一windows

exe打包教程二数组

java swing开发都是本身琢磨的,有的地方写的不规范,不过大多都是网上借鉴的,应该不算离谱的。markdown

今天看了看本身的java swing的程序,感受写的还不错,可是发现如今遇到一个瓶颈问题,就是jtable的使用,因为一开始概念不理解如今jtable得从新写,以前我吧数据放在jtable上了,可是真正开发的java swing数据都是放在TableModel上的。下面就Jtable的使用,好好整理了一番,途中参考的文章我都会放在下面列出,读者能够本身参考**mvc

JTable结构梳理

  • JTable=TableHeader+TableColumnless

  • 顾名思义咱们知道表格是由表头和表列组成的,这两个都是单独的控件。可是JTable中若是想让表头显示仅仅将JTable加入Jpanel或者Jframe中是不行的,我这里提供两种方式实现编辑器

  • 一、分别将TableHeader和TableColumn加入控件中单独的显示,这种状况不常见ide

  • 二、先将JTable加入jscrollpane(滚动条)中,而后在将滚动条加入到对应的控件中(Jpanel或者是Jframe).java swing 开发中加入滚动条是很常见的操做,因此这种方式的加入表格仍是很推荐的。

table = new JTable(data, columnNames);
table.setBackground(Color.gray);
table.setPreferredScrollableViewportSize(new Dimension(800, 100));
table.setFillsViewportHeight(false);
pane = new JScrollPane(table);
this.add(pane);
复制代码
  • 上面的代码就是简单的实现将表格以显示表头的方式加入到jframe中显示。其中咱们可以看到多了几个设置,setPreferredScrollableViewportSize无关紧要的,无所谓,可是setFillsViewportHeight是设置表格在纵向上的铺展状况,什么意思呢,若是这里设置为true则表格就会在纵向上铺满jframe,若是是false,表格则会按照本身的实际占地面积显示,不会多占的。

这里写图片描述

这里写图片描述

JTable数据显示

  • java swing中jtable是mvc形式的,因此jtable仅仅是数据的显示,而真正和数据绑定的倒是TableModel这个接口,咱们先看看这个接口的内部有哪些方法,这样咱们内心才有个底。

这里写图片描述

  • 众多周知jtable中经常使用的两种构造函数一个是数组另外一个是vector,这两种构造函数中都是采用了匿名内部类实现tablemodel,前者用的是AbstractTableModel,后者是DefaultTableModel。而DefaultTableModel有事继承了AbstractTableModel,因此咱们平时若是自定义model的话,都会去继承AbstractTableModel的。咱们在去源码里能够看见这里写图片描述,咱们会发现AbstractTableModel有事继承TableModel这个接口的。因此咱们的全部方法都是源于他。

  • 咱们观察AbstractTableModel源码中注释发现,咱们只须要继承AbstractTableModel类后只须要实现三个必须的方法,其余的方法根据须要实现

public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
复制代码

这里写图片描述

  • 这三个方法的做用就是经过model高数jtable我须要一个几行几列的表格,至于每一个单元格显示的内容就是经过getValueAt这个方法实现的,到这里咱们就实现了,jtable的model自定义显示。
//表格的列,须要用户本身设定好
	private int column;
	//待加载的数据  数据每行的列数和上面要统一好
	private List<Object> list;
	
	public MyTableModel(List<Object> list,int column){
		this.column=column;
		this.list=list;
	}
	@Override
	public int getRowCount() {
		// TODO Auto-generated method stub
		return list.size();
	}

	@Override
	public int getColumnCount() {
		// TODO Auto-generated method stub
		return this.column;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		// TODO Auto-generated method stub
		return list.get(rowIndex).toString()+"_"+rowIndex+"_"+columnIndex;
	}
复制代码
  • 上面的代码就是个人model类,里面有个穿list的构造函数,而后咱们看看咱们的三个方法就起到了做用了。而后在getValueAt获取指定行数的list的指定内容就能够填充到表格上了。

jtable数据的CURD

  • 在上面咱们继承了AbstractTableModel,这里面有对数据的CURD操做

这里写图片描述

if("增长".equals(command)){
			List<Object> data = getData();
			data.add("test5");
			data.add("test6");
			datamModel.setList(data);
//			datamModel.fireTableStructureChanged();
			datamModel.fireTableRowsInserted(5,6);
		}else if("删除".equals(command)){
			List<Object> data = getData();
			data.remove(2);
			datamModel.setList(data);
			datamModel.fireTableRowsDeleted(1, 1);
		}else if("更新".equals(command)){
			List<Object> data = getData();
			data.set(0, "test0_1");
			datamModel.setList(data);
			datamModel.fireTableRowsUpdated(0, 5);
		}
复制代码
  • 里面都会带有参数好比datamModel.fireTableRowsUpdated(0, 5);的意思是通州JTable显示模块去刷新从1-6行的全部数据,因此说好比你更新了第一行的数据,而你用的两个参数是1,4.那么恭喜你,你的更新JTable没法实现,由于他只更新从第二行开始到第五行的数据。其余的方法参数和他同样。经过上面就能够轻松实现JTable的CURD操做。

JTable控件显示法

  • 相信有的朋友遇到过,表格中须要显示CheckBox、button等控件的,可是咱们发现咱们定义的控件在表格上显示成了控件对应的类的字符串了,这又是为何呢。下面请随我一块儿看看源码吧:
/**
     *  Returns <code>Object.class</code> regardless of <code>columnIndex</code>.
     *
     *  @param columnIndex  the column being queried
     *  @return the Object.class
     */
    public Class<?> getColumnClass(int columnIndex) {
        return Object.class;
    }
复制代码
  • 源码中AbstractTableModel的getColumnClass的方法是JTable决定显示类型的主要依据,源码中返回的默认是object.class,这就意味着咱们在jtable是true或false或其余类,在这里都会返回object.class,那么jtable就会采用默认的渲染方式去渲染表格,默认的就是全部都是字符串形式展现,这个设置在JTable中的源码中
protected void createDefaultRenderers() {
        defaultRenderersByColumnClass = new UIDefaults(8, 0.75f);

        // Objects
        setLazyRenderer(Object.class, "javax.swing.table.DefaultTableCellRenderer$UIResource");

        // Numbers
        setLazyRenderer(Number.class, "javax.swing.JTable$NumberRenderer");

        // Doubles and Floats
        setLazyRenderer(Float.class, "javax.swing.JTable$DoubleRenderer");
        setLazyRenderer(Double.class, "javax.swing.JTable$DoubleRenderer");

        // Dates
        setLazyRenderer(Date.class, "javax.swing.JTable$DateRenderer");

        // Icons and ImageIcons
        setLazyRenderer(Icon.class, "javax.swing.JTable$IconRenderer");
        setLazyRenderer(ImageIcon.class, "javax.swing.JTable$IconRenderer");

        // Booleans
        setLazyRenderer(Boolean.class, "javax.swing.JTable$BooleanRenderer");
    }
复制代码
  • 源码中就有渲染器专门处理bool类型的,那么咱们只须要在getColumnClass进行处理就好了,在咱们的bool的单元格返回bool类JTable就会采用bool类型的渲染器了。
return getValueAt(0, c).getClass();
复制代码
  • 这样咱们就能够显示一些其余的控件了,还有一些好比每行都须要一行按钮来实现修改改行的功能,这些按钮正常咱们不须要再数据中添加(避免数据过于庞大),若是不在数据中添加那么咱们的getClass方法就起不到做用,这个用到了下面的知识来解决

JTable渲染和编辑

  • 这种呢其实就是上面的getClass底层的实现方式,JTable中源码咱们上面能够看出JTable经过返回的不一样的类来调用不一样的渲染器,如今咱们不经过返回类的方式来渲染,而是本身定义一个渲染器,而后经过JTable提供的方法设定用该渲染器渲染该单元格!
setCellEditor和setCellRenderer
复制代码
  • 你们能够观察源码,在JTable的编辑器中AbstractCellEditor是基础的抽象类,他继承了CellEditor,怎么样熟悉吗,这个不就是和AbstractTableModel 是同样的吗。可是这个类不能反回控件须要和TableCellEditor结合使用,或者咱们只是用另一个基础类DefaultCellEditor,

  • DefaultCellEditor和AbstractTableModel 有设么区别呢,他们都是同样实现了CellEditor接口,可是前者构造中只能传入控件,也就是说每日次实力只能经过不一样构造函数构建不一样的控件,可是后者是抽象类,继承的类能够自定义构造函数,这就方便咱们够赞多个不一样的控件了,因此这两个你们看状况使用。最后都是经过getTableCellEditorComponent这个函数将控件返回出去。

  • 设置完了编辑器,咱们最终要是只渲染器,就是JTable最终如何显示的问题。和上面的那个同样。继承TableCellRenderer类,经过getTableCellRendererComponent方法返回渲染成设么控件,渲染的控件咱们能够进行二次封装。

  • 调用以下 两个参数就是经过上面两个类构造的类

column.setCellEditor(editor);

      
column.setCellRenderer(renderer);
复制代码
相关文章
相关标签/搜索