javaswing添加jcheckbox复选框
最近接触了⼀点Java的GUI编程,也就是由Java AWT更新⽽来的Java Swing。
  总体上⽽⾔,Java Swing编程有两⼤特点:⿇烦、效果差。
  ⿇烦是说由于设计器的使⽤不⽅便(如果您希望使⽤窗体设计器通过快速拖拽控件建⽴您的Java Swing GUI程序,请您使⽤MyEclipse 8.5以上版本,并且需要最⾼使⽤权限),所有代码都得⼿写,如果没有好的编码规范和注释习惯。⾃⼰都会被代码淹没。
  效果差是指运⾏时的界⾯。具体的您可以⾃⼰尝试发现。
  那么我们通过⼀段代码来创建属于我们的窗体:
1import javax.swing.JFrame;
2
3/**
4 * 我的第⼀个Java窗体
5 *
6 * @author Johness
7 *
8*/
9public class MyJFrame extends JFrame{
10
11
12
13 }
  然后通过main⽅法来测试:
  运⾏后,窗体在屏幕左上⾓显现并且是最⼩化的形式。
  呵呵,那么关于设置窗体的显⽰我就不再赘述了,值得注意的是窗体的布局必须设置。
  ⼩贴⼠:使⽤setLayout设置布局,参数传递null;
  我们讨论⼀下怎样在窗体的表格中显⽰复选框。
  即实现如下效果:
  我随便拖了些控件(数据是⽼师给的……)。
  好了,我们来⼀步步实现。
  ⼩贴⼠⼆:使⽤add⽅法向控件添加内容控件。
  ①⾸先我们需要⾯板(JPanel)或其他容器控件承载表格(JTable),值得⼀提的是:由于窗体本⾝
就是容器型控件,您可以考虑将表格单个地放置在窗体上。
  ②然后我们需要将表格对象创建出来并放⼊该容器控件,⼤家可以参考⼿册(如JDK_API_1_6_zh_CN.CHM)创建表格控件。值得⼀提的是在这七个构造⽅法中,设计器(如果您使⽤了MyEclipse)使⽤的是( dm)这个版本。⽽⼀般情况使⽤( rowData,  columnNames)这个版本的居多(不包括我)。如果是我,可能会选择使⽤设计器的版本。
  可能有细⼼的朋友会发现说:设计器的版本很不⽅便,因为需要传递的是接⼝,我们必须写⼀个类实现该接⼝并构造实例作为参数传递,⿇烦,不如直接使⽤([][] rowData, [] columnNames)这个版本。
  那么在这⾥我向不知道“匿名内部类”(⽼师是这样称呼的,没考证)的朋友普及⼀下Java的匿名内部类。
  在Java⽅法中,如果参数需要传递接⼝,可以在调⽤⽅法时传递⼀个(匿名)对象,该对象是⼀个不具名的类的实例,该对象所属类实现了⽅法参数的接⼝。
  ⽐如上⾯的例⼦( dm),这是JTable的构造⽅法,需要的是⼀个TableModel接⼝类型的参数(这⾥只是举例,实际运⽤⽐较复杂),我们可以使⽤如下写法:JTable table = new JTable(new TableModel());
  毫⽆疑问,这种写法是错误的,但是如果这样写就不是了:
1import javax.swing.*;
2import javax.swing.event.*;
3import javax.swing.table.*;
4
5
6public class MyFirstJFrame extends JFrame {
7public MyFirstJFrame() {
8        setLayout(null);
9
10        JTable table = new JTable(new TableModel(){
11
12            @Override
13public int getRowCount() {
14// TODO Auto-generated method stub
15return 0;
16            }
17
18            @Override
19public int getColumnCount() {
20// TODO Auto-generated method stub
21return 0;
22            }
23
24            @Override
25public String getColumnName(int columnIndex) {
26// TODO Auto-generated method stub
27return null;
28            }
29
30            @Override
31public Class<?> getColumnClass(int columnIndex) {
32// TODO Auto-generated method stub
33return null;
34            }
35
36            @Override
37public boolean isCellEditable(int rowIndex, int columnIndex) {
38// TODO Auto-generated method stub
39return false;
40            }
41
42            @Override
43public Object getValueAt(int rowIndex, int columnIndex) {
44// TODO Auto-generated method stub
45return null;
46            }
47
48            @Override
49public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
50// TODO Auto-generated method stub
51
52            }
53
54            @Override
55public void addTableModelListener(TableModelListener l) {
56// TODO Auto-generated method stub
57
58            }
59
60            @Override
61public 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的构造⽅法,⼤部分重载中参数即包含了数据,⽐如( rowData, columnNames)中Vector保存的数据(Vector 相当于数组)。
  其次是表格样式,表格将数据和如何显⽰数据(⽐如列数量、列名称、是否可编辑)保存在其数据模版中,该模版实现⾃接⼝TableModel。
  最后,表格(每⼀个单元格)可以设置渲染效果。
  我把完整的代码贴出来:
1import java.awt.Component;
2import java.awt.event.ActionEvent;
3import java.awt.event.ActionListener;
4
5import javax.swing.*;
6import javax.swing.table.*;
7
8
9public class MyFirstJFrame extends JFrame {
10
11// 作为测试的main⽅法
12public static void main(String[] args) {
13new MyFirstJFrame().setVisible(true);
14      }
15
16/**
17      * 构造⽅法
18*/
19public MyFirstJFrame() {
20          InitialComponent();
21      }
22
23/**
24      * 初始化组件的⽅法
25*/
26private void InitialComponent(){
27// 设置窗体参数
28
29// 设置布局模式
30          setLayout(null);
31// 设置窗体⼤⼩
32          setSize(480, 360);
33// 设置窗体居中(⾮常规⽅法)
34          setLocationRelativeTo(null);
35// 关闭窗体退出程序
36          setDefaultCloseOperation(DISPOSE_ON_CLOSE);
37
38// 初始化⾯板
39          panel = new JPanel();
40          panel.Width(), Height());
41          panel.setLocation(0,0);
42          panel.setLayout(null);
43
44// 初始化表格
45          table = new JTable(new DefaultTableModel(new Object[][]{{"第⼀⾏"},{"第⼆⾏"},{"第三⾏"},{"第四⾏"}}, new String[]{"测试⾏1","测试⾏2"}){
46/* (non-Javadoc)
47              * 重写⽅法,判断表单元格是否可编辑
48              * 可以通过row和column索引判断某⼀个单元格是否可编辑
49              * 此处设为都不可编辑
50              * @see javax.swing.table.DefaultTableModel#isCellEditable(int, int)
51*/
52              @Override
53public boolean isCellEditable(int row, int column) {
javaswing实现购买
54return false;
55              }
56          });
57
58// 开始向表格中添加复选框(注意:此⽰例较为简单,缺省很多判断,也没有动态代码⽀持)
59// 通过设置列渲染
60
61// ⽅法⼀:直接⽅式使⽤TableColumn的setCellRenderer⽅法(推荐)
62// 此⽅法可以设置某⼀列的渲染(即使⽤某⼀个组件--即控件来显⽰单元格数据)
63          ColumnModel().getColumn(1).setCellRenderer(new TableCellRenderer(){
64
65/*(non-Javadoc)
66              * 此⽅法⽤于向⽅法调⽤者返回某⼀单元格的渲染器(即显⽰数据的组建--或控件)
67              * 可以为JCheckBox JComboBox JTextArea 等
68              * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) 69*/
70              @Override
71public Component getTableCellRendererComponent(JTable table,
72                      Object value, boolean isSelected, boolean hasFocus,
73int row, int column) {
74// 创建⽤于返回的渲染组件
75                  JCheckBox ck = new JCheckBox();
76// 使具有焦点的⾏对应的复选框选中
77                  ck.setSelected(isSelected);
//设置背景颜⾊这⾥是设置jcheckbox的背景颜⾊直接设置为透明,我这⾥是⽤了⼀种明暗交替的颜⾊转换,所以背景颜⾊设置了⼀下
ck.setOpaque(false);
78// 设置单选box.setSelected(hasFocus);
79// 使复选框在单元格内居中显⽰
80                  ck.setHorizontalAlignment((int) 0.5f);
81return ck;
82              }});
83
84// ⽅法⼆:先设置列编辑器,然后设置单元格渲染
85// 设置列编辑器
86// 在以复选框为对象设置列编辑器时,必须保证该列能够被编辑,否则⽆法更改状态
87// (此步骤可以省略,省略时不要忘记将列设为不可编辑)
88// ColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(new JCheckBox()));
89
90// 设置单元格渲染(这⾥是设置表格级别的渲染)
91/*table.setDefaultRenderer(Object.class, new TableCellRenderer(){
92
93            @Override
94            public Component getTableCellRendererComponent(JTable table,
95                    Object value, boolean isSelected, boolean hasFocus,
96                    int row, int column) {
97                // 判断是否为需要渲染的列
98                if(column == 1){
99                    // 和⽅法⼀基本⼀致
100                    JCheckBox box = new JCheckBox();
101                    box.setSelected(isSelected);
102                    // 设置单选box.setSelected(hasFocus);
103                    box.setHorizontalAlignment((int) CENTER_ALIGNMENT);    // 0.5f
104                    return box;
105                    }
106                // 如果不是需要渲染的列,封装⽂本域显⽰数据
107                return new String());
108            }});*/
109
110// 在多选是需要按住Ctrl键或者⿏标按住拖过连续的需要选中的⾏,应该给⽤户说明
111// 第⼀种⽅法是被推荐的,因为它具有选中的⾼亮显⽰,界⾯能更加友好
112          table.Width(),Height() - 90);
113          table.setLocation(0, 0);
114
115
116          btn = new JButton("Test");
117          btn.setSize(80,40);
118          btn.setLocation((Width()) / 2 - 40, Height() - 80);
119
120// 按钮点击时显⽰当前选中项
121          btn.addActionListener(new ActionListener(){
122
123              @Override
124public void actionPerformed(ActionEvent e) {
125for(int rowindex : SelectedRows()){
126                      JOptionPane.showMessageDialog(null, rowindex + " " + ValueAt(rowindex, 0));
127                  }
128              }});
129
130          panel.add(table);
131          panel.add(btn);
132this.add(panel);
133
134      }
135
136// 定义⼀些必要的组件
137private JPanel panel;
138private JTable table;
139private JButton btn;
140  }
  上⾯的代码有⼀些缺陷,⼤家需要做⼀些修改。实际上我也不希望贴上完全⽆误的perfect的代码,对需要学习的朋友不是好事⼉。
  总结:充分理解Java的⽅法返回值作为判断依据。
  1、匿名内部类(匿名对象后{}的妙⽤)。
  2、窗体的布局:默认布局为(最后添加?)的控件占据其窗体的全部空间。
  3、编辑器、渲染。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。