在Java窗体表格中插入复选框
最近接触了一点Java的GUI编程,也就是由Java AWT更新而来的Java Swing。
总体上而言,Java Swing编程有两大特点:麻烦、效果差。
麻烦是说由于设计器的使用不方便(如果您希望使用窗体设计器通过快速拖拽控件建立您的Java Swing GUI程序,请您使用MyEclipse 8.5以上版本,并且需要最高使用权限),所有代码都得手写,如果没有好的编码规范和注释习惯。自己都会被代码淹没。
效果差是指运行时的界面。具体的您可以自己尝试发现。
那么我们通过一段代码来创建属于我们的窗体:
1 import javax.swing.JFrame; 2 3 /** 4 * 我的第一个Java窗体 5 * 6 * @author Johness 7 * 8 */ 9 public class MyJFrame extends JFrame{ 10 11 12 13 }
然后通过main方法来测试:
运行后,窗体在屏幕左上角显现并且是最小化的形式。
呵呵,那么关于设置窗体的显示我就不再赘述了,值得注意的是窗体的布局必须设置。
小贴士:使用setLayout设置布局,参数传递null;
我们讨论一下怎样在窗体的表格中显示复选框。
即实现如下效果:
我随便拖了些控件(数据是老师给的……)。
好了,我们来一步步实现。
小贴士二:使用add方法向控件添加内容控件。
①首先我们需要面板(JPanel)或其他容器控件承载表格(JTable),值得一提的是:由于窗体本身就是容器型控件,您可以考虑将表格单个地放置在窗体上。
②然后我们需要将表格对象创建出来并放入该容器控件,大家可以参考手册(如JDK_API_1_6_zh_CN.CHM)创建表格控件。值得一提的是在这七个构造方法中,设计器(如果您使用了MyEclipse)使用的是JTable(TableModel dm)
这个版本。而一般情况使用
JTable(Vector rowData, Vector columnNames)
这个版本的居多(不包括我)。如果是我,可能会选择使用设计器的版本。
可能有细心的朋友会发现说:设计器的版本很不方便,因为需要传递的是接口,我们必须写一个类实现该接口并构造实例作为参数传递,麻烦,不如直接使用JTable(Object[][] rowData, Object[] columnNames)这个版本。
那么在这里我向不知道“匿名内部类”(老师是这样称呼的,没考证)的朋友普及一下Java的匿名内部类。
在Java方法中,如果参数需要传递接口,可以在调用方法时传递一个(匿名)对象,该对象是一个不具名的类的实例,该对象所属类实现了方法参数的接口。
比如上面的例子JTable(TableModel dm)
,这是JTable的构造方法,需要的是一个TableModel接口类型的参数(这里只是举例,实际运用比较复杂),我们可以使用如下写法:JTable table = new JTable(new TableModel());
毫无疑问,这种写法是错误的,但是如果这样写就不是了:
1 import javax.swing.*; 2 import javax.swing.event.*; 3 import javax.swing.table.*; 4 5 6 public class MyFirstJFrame extends JFrame { 7 public MyFirstJFrame() { 8 setLayout(null); 9 10 JTable table = new JTable(new TableModel(){ 11 12 @Override 13 public int getRowCount() { 14 // TODO Auto-generated method stub 15 return 0; 16 } 17 18 @Override 19 public int getColumnCount() { 20 // TODO Auto-generated method stub 21 return 0; 22 } 23 24 @Override 25 public String getColumnName(int columnIndex) { 26 // TODO Auto-generated method stub 27 return null; 28 } 29 30 @Override 31 public Class<?> getColumnClass(int columnIndex) { 32 // TODO Auto-generated method stub 33 return null; 34 } 35 36 @Override 37 public boolean isCellEditable(int rowIndex, int columnIndex) { 38 // TODO Auto-generated method stub 39 return false; 40 } 41 42 @Override 43 public Object getValueAt(int rowIndex, int columnIndex) { 44 // TODO Auto-generated method stub 45 return null; 46 } 47 48 @Override 49 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 50 // TODO Auto-generated method stub 51 52 } 53 54 @Override 55 public void addTableModelListener(TableModelListener l) { 56 // TODO Auto-generated method stub 57 58 } 59 60 @Override 61 public void removeTableModelListener(TableModelListener l) { 62 // TODO Auto-generated method stub 63 64 }}); 65 } 66 }
我可能需要解释一下这些代码:首先是JTable table = new JTable(new TableModel(){});可以看出来,大括号中间的部分是一些需要重写的方法。
那么大家应该怎样理解这一句代码呢?我们分解一下(new TableModel(){})。我们应该怎么看待?大家回想一下我以上说过的匿名内部类的定义。我们可以这样看,new ……()是构造方法,调用来构造一个匿名对象,其后的{}不是Java的特殊语法,但是Java中可以将方法定义在里面(这里的方法生命周期与匿名对象相同),当然,此处是用于实现接口的方法。
清晰一点了吧?我们再来拆分:TableModel我们可以在其前面补充一个不存在的类类名,比如MyTableModel。好了,我们完整再现一下:new MyTableModel:TableModel(){}也就是说大家可以想象成(new TableModel(){})是在声明一个匿名对象,它属于一个不具名的类(如MyTableModel),该类实现了TableModel接口。而由于语法限制,不能全部写出来所以省略了[MyTableModel:]。当然,这只是我们的推理,大家理解记忆哈。
注:这里的匿名对象只没有引用指向(即没有变量名)的对象。
实际上我们使用匿名内部类的地方很多,比如添加事件监听。但是“上面创建JTable的方法是只作为示例,绝大多数是不会如此用的”,大家谨记。
我会在随笔结尾贴出全部代码,其中创建JTable的代码是使用了设计器的构造方式。
③设置表格渲染。在详细说明之前我先解释一下JTable的显示原理:
首先是数据来源,您使用JTable的构造方法,大部分重载中参数即包含了数据,比如JTable(Vector rowData, Vector columnNames)
中Vector保存的数据(Vector相当于数组)。
其次是表格样式,表格将数据和如何显示数据(比如列数量、列名称、是否可编辑)保存在其数据模版中,该模版实现自接口TableModel。
最后,表格(每一个单元格)可以设置渲染效果。
我把完整的代码贴出来:
上面的代码有一些缺陷,大家需要做一些修改。实际上我也不希望贴上完全无误的perfect的代码,对需要学习的朋友不是好事儿。
总结:充分理解Java的方法返回值作为判断依据。
1、匿名内部类(匿名对象后{}的妙用)。
2、窗体的布局:默认布局为(最后添加?)的控件占据其窗体的全部空间。
3、编辑器、渲染。
最近断断续续地看WPF了,因为在看C语言了……
我创建了QQ群:35142661。作为能够与我一起学习或者指导我学习的朋友们近来讨论。
2012-05-02 18:42:59