zoukankan      html  css  js  c++  java
  • java swing 添加 jcheckbox复选框

    最近接触了一点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。

      最后,表格(每一个单元格)可以设置渲染效果。

      我把完整的代码贴出来:

    复制代码
      1 import java.awt.Component;
      2  import java.awt.event.ActionEvent;
      3  import java.awt.event.ActionListener;
      4  
      5  import javax.swing.*;
      6  import javax.swing.table.*;
      7  
      8  
      9  public class MyFirstJFrame extends JFrame {
     10      
     11      // 作为测试的main方法
     12      public static void main(String[] args) {
     13          new MyFirstJFrame().setVisible(true);
     14      }
     15      
     16      /**
     17       * 构造方法
     18       */
     19      public MyFirstJFrame() {
     20          InitialComponent();
     21      }
     22      
     23      /**
     24       * 初始化组件的方法
     25       */
     26      private 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.setSize(this.getWidth(), this.getHeight());
     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
     53              public boolean isCellEditable(int row, int column) {
     54                  return false;
     55              }
     56          });
     57          
     58          // 开始向表格中添加复选框(注意:此示例较为简单,缺省很多判断,也没有动态代码支持)
     59          // 通过设置列渲染
     60          
     61          // 方法一:直接方式 使用TableColumn的setCellRenderer方法(推荐)
     62          // 此方法可以设置某一列的渲染(即使用某一个组件--即控件来显示单元格数据)
     63          table.getColumnModel().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
     71              public Component getTableCellRendererComponent(JTable table,
     72                      Object value, boolean isSelected, boolean hasFocus,
     73                      int 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); 81 return ck; 82 }}); 83 84 // 方法二:先设置列编辑器,然后设置单元格渲染 85 // 设置列编辑器 86 // 在以复选框为对象设置列编辑器时,必须保证该列能够被编辑,否则无法更改状态 87 // (此步骤可以省略,省略时不要忘记将列设为不可编辑) 88 // table.getColumnModel().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 JTextArea(value.toString()); 108 }});*/ 109 110 // 在多选是需要按住Ctrl键或者鼠标按住拖过连续的需要选中的行,应该给用户说明 111 // 第一种方法是被推荐的,因为它具有选中的高亮显示,界面能更加友好 112 table.setSize(panel.getWidth(),panel.getHeight() - 90); 113 table.setLocation(0, 0); 114 115 116 btn = new JButton("Test"); 117 btn.setSize(80,40); 118 btn.setLocation((panel.getWidth()) / 2 - 40, panel.getHeight() - 80); 119 120 // 按钮点击时显示当前选中项 121 btn.addActionListener(new ActionListener(){ 122 123 @Override 124 public void actionPerformed(ActionEvent e) { 125 for(int rowindex : table.getSelectedRows()){ 126 JOptionPane.showMessageDialog(null, rowindex + " " + table.getValueAt(rowindex, 0)); 127 } 128 }}); 129 130 panel.add(table); 131 panel.add(btn); 132 this.add(panel); 133 134 } 135 136 // 定义一些必要的组件 137 private JPanel panel; 138 private JTable table; 139 private JButton btn; 140 }
    复制代码

      上面的代码有一些缺陷,大家需要做一些修改。实际上我也不希望贴上完全无误的perfect的代码,对需要学习的朋友不是好事儿。

      总结:充分理解Java的方法返回值作为判断依据。

      1、匿名内部类(匿名对象后{}的妙用)。

      2、窗体的布局:默认布局为(最后添加?)的控件占据其窗体的全部空间。

      3、编辑器、渲染。

  • 相关阅读:
    codevs 1213 解的个数(我去年打了个表
    176. [USACO Feb07] 奶牛聚会
    codevs 1515 跳
    codevs 1994 排队 排列组合+高精度
    poj 1811 Pallor Rho +Miller Rabin
    Miller_Rabin codevs 1702 素数判定2
    Lucas
    cos改ip
    用户名 不在 sudoers文件中,此事将被报告
    continue break
  • 原文地址:https://www.cnblogs.com/llzzy/p/3216863.html
Copyright © 2011-2022 走看看