JTable的高级用法小结(在JTable中添加组件)by:Jungle Yang

来源:互联网 发布:台湾旅游 知乎 编辑:程序博客网 时间:2024/05/06 19:27

前段时间做了一个比较大的课程项目,技术不是很好,用的Java开发,所有的界面、网络通信、数据库连接都是一行行代码敲出来的(PS不懂用framework真心苦逼)。众所周知,Java的Swing写出来的界面确实不敢恭维,但是,深入点探索下,发现其功能还是相对强大的。这里对Swing中的JTable做个小小的高级用法总结。当初为了把这个整清楚,可是牺牲不少夜的睡眠。

         首先,JTable的普通用法:

         API中提供的JTable的单元格中的内容是Object,原则上是可以存放Java中的任何组件的。默认的单元格构造器和渲染器是针对String对象的,可以选中,可以编辑。下面贴出Jable的一些常用的构造方法和涉及到行列等的相关设置:

         构造函数:

         (1)

    JTable table = new JTable(int numRows, int numColumns)
          /*构造一个numRows行,numColumn列的Table*/
          (2)
          TableModel dataModel = new AbstractTableModel() {
               public int getColumnCount() { return 10; }
         public int getRowCount() { return 10;}
         public Object getValueAt(int row, int col) { return new Integer(row*col); }
    };
JTable table = new JTable(dataModel);
JScrollPane scrollpane = new JScrollPane(table);
/*利用TableModel来构造10行10列的 表格*/
(3)
String[] headName = {“1”,”2”,”3”,”4”};//表格的标题
Object[][] someContent = new Object[][]{
           {Object1,Object2,Object3,Object4},
           { Object1,Object2,Object3,Object4},
           { Object1,Object2,Object3,Object4},
           { Object1,Object2,Object3,Object4}
};//表格的内容
JTable table = new JTable(someContent, headName);
/*利用给定的标题和内容构造table*/
 
相关设置:
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
/*设置表格的选择模式为单选,默认的为多选*/
table.setRowHeight(50);//设置表格行高,int值
table.getColumnModel().getColumn(0).setPreferredWidth(100);
/*设置表格列宽,int值*/
table.getTableHeader().setReorderingAllowed(false);
/*禁止拖动表格的列,不改变列的顺序*/
table.setCellSelectionEnabled(true);
/*设置表格单元格可选*/
table.setColumnSelectionAllowed(false);//false,使得表格以行为单位进行选取

table.getColumnModel().getColumn(0).setMaxWidth(140);//设置第1列的最大宽度

table.getColumnModel().getColumn(0).setMinWidth(140);//设置第1列的最小宽度

/*将两个值设置成相同,能够固定表格列宽*/

table.getColumnModel().getColumn(0).setCellRenderer(someCellRenderer);

/*设置第一列单元格的渲染器*/

table.getColumnModel().getColumn(0).setCellEditor(someCellEdit());

/*设置第一列单元格的编辑器*/

/*单元格渲染器和编辑器的设置方法,在往Table的单元格中放入Swing的其他Component时会用到*/

 

其次,API提供的稍高级的JTable用法:

在table的单元格中放入ComboBox(下拉选择列表)

JComboBox comboBox= new JComboBox();

table.getColumnModel().getColumn(0).setCellEditor(newDefaultCellEditor(comboBox));

/*将表格的第一列的单元格设置成显示comBox*/

 

最后,真正的高级用法:

在table的单元格中显示Image、List、TextArea等各种Swing组件:

Java提供的API默认支持在table中放入comBox,但也只支持放入comBox。如果需要放入其他组件,使自己的table功能强大起来,就必须自己写几个继承类,重载一些方法了,下面给出介绍:

(1)    写一个MyTableModel继承AbstractTableModel

class MyTableModel extends AbstractTableModel{

                  /**

                 *@author Jungle Yang

*/

                            privatestatic final long serialVersionUID = 1L;

                            privateString[] columnNames = { "", "", ""};//表格的标题,可以不要

private Object[][] data = {{new ImageIcon(),new JScrollPane(), new JTextArea()}};

public void setObject(Object[][] o){

           data = o;

}//这个函数不必须,自己写来为了以后设置表格内容

public int getColumnCount() {

           return 3;//或者是columnNames.length;

}

public int getRowCount() {

           return data.length;

}

public Object getValueAt(int row, int col) {

           return data[row][col];

}

public Class getColumnClass(int c){

           return getValueAt(0,c).getClass();

}

public boolean isCellEditable(int row, int col){

           if(col==1)

                   returntrue;

                     return false;

         }

/*设置表格的单元格是否可编辑,对这种自己写的组件加入表格,若设置成true,则必须自己写CellEditor,稍候会介绍*/

public void setValueAt(Object value, int row,int col){

         data[row][col]= value;

           fireTableCellUpdated(row, col);

}

}

/*上面这个例子,是为了构造一个有3列的table,第一列显示图片,第二列存放一个滚动条(以便以后在滚动条上加上其他组件),第三列存放一个TextArea提供比默认的String更强大的编辑功能*/

 

(2)    针对自己要添加的组件编写渲染器,继承DefaultTableCellRenderer

举一个Image的例子:

public        class ImageRenderer extendsDefaultTableCellRenderer{

                            /**

                          *@author Jungle Yang

         */

         privatestatic final long serialVersionUID = 1L;

public Component getTableCellRendererComponent(JTable table, Objectvalue, boolean isSelected, boolean hasFocus, int row, int column) {

super.getTableCellRendererComponent(table, value, isSelected,hasFocus, row, column);

         if(value instanceof Icon){

                    this.setIcon((Icon)value);

                    if(isSelected){

                              if(table.getValueAt(row,1) instanceof JTextArea){

                                       if(((JTextArea)table.getValueAt(row,1)).getText().equals(""))

                                                setBorder(newLineBorder(table.getBackground()));

                                       else

                                                setBorder(newLineBorder(Color.black));

                              }elseif(table.getValueAt(row, 1) instanceof JScrollPane){

                                       setBorder(new LineBorder(Color.black));

                              }else{

                                      setBorder(newLineBorder(Color.red));

                             }

                  }

         }else if (value instanceof String)

                    setText((String)value);

         else

                    setText("");

         returnthis;

}

}

 

                  再贴一个TextArea的例子:

                   publicclass TextAreaRenderer extends JTextArea implements TableCellRenderer {

                  /**

                 *@author Jungle Yang

*/

                            private static final longserialVersionUID = 1L;

                            public Component getTableCellRendererComponent(JTabletable, Object textArea,

                                                                 booleanisSelected, boolean hasFocus, int row, int column) {

                                      if(isSelected){

                                               ((JTextArea)textArea).setBackground(table.getSelectionBackground());

                                      }else{

                                               ((JTextArea) textArea).setBackground(table.getBackground());

                                      }

                                      ((JTextArea)textArea).setToolTipText(((JTextArea) textArea).getText());

                                      ((JTextArea)textArea).setWrapStyleWord(true);

                                      ((JTextArea)textArea).setLineWrap(true);

                                      return (JTextArea) textArea;

}

}

/*上面这段代码涉及了一些TextArea的设置,只是个人需要*/

(3)    针对加入的组件,对有需要进行编辑的写编辑器,继承CellEditor

贴一个ScrollPane的例子,为了使单元格中的ScrollPane的滚动条能够使用

public class ScrollPaneCellEdit implements TableCellEditor {

                  /**

                 *@author Jungle Yang

*/

                            public Component getTableCellEditorComponent(JTabletable, Object value,

                                                                                             booleanisSelected, int row, int column) {

                                      return (JScrollPane)table.getModel().getValueAt(row, column);

                            }

                            public voidaddCellEditorListener(CellEditorListener arg0) {

                            }

                            public voidcancelCellEditing() {

                            }

                            public ObjectgetCellEditorValue() {

                                     return null;

                            }

                            public booleanisCellEditable(EventObject arg0) {

                                     return true;

                            }

                            public voidremoveCellEditorListener(CellEditorListener arg0) {

                            }

                            public booleanshouldSelectCell(EventObject arg0) {

                                      return true;

                            }

                            public booleanstopCellEditing() {

                                     return true;

                            }

}

/*这里对部分重载的方法涵义不是很清楚,就不妄下说明,编写代码的时候在true、false间做一些尝试,应该就能很好的工作*/

(4)    最后一步就是使用刚才写的类了

MyTableModel mtm = new MyTableModel();

mtm.setObject(show);//show是自己要显示的一个Object[][]

table=new JTable(mtm);

table.setModel(mtm);

TableColumnModel columnModel = table.getColumnModel();

columnModel.getColumn(0).setCellRenderer(new LabelRenderer());

columnModel.getColumn(1).setCellRenderer(new ScrollPaneRenderer());

columnModel.getColumn(2).setCellRenderer(new TextAreaRenderer());

columnModel.getColumn(1).setCellEditor(newScrollPaneCellEdit());

 

至此,JTable的用法就基本讲完了,对高级用法,其实关键就只在三处,分别是对AbstractTableModel、DefaultTableCellRenderer、TableCellEditor这三个类写继承类,重载其中的方法。