GUI开发之JTable,实现JB属性表

原创 2004年10月06日 05:58:00

文章所有权归本人所有,如要用作商业用途请和我联系,如果要转贴,请注明出处和作者.
Powered BY G.T.M.


很高兴有时间写下自己开发的经历,又一次改变,从数据底层到了界面的GUI,一次又一次的挑战,我想,我在成长.
等我以后开发了新的东西或者解决新的问题,再写一遍血泪史,国庆的假期就为这个属性表给占了cry_smile.gif
不说太多,入正题:

       用过JB的都知道JB的Design是个不错的界面,今次我参与的项目由于要出个Aplha版,所以要写类似IDE的GUI,我负责属性表和树.
       原本实现一个JTable不难(虽然一开始走了一些弯路,去了搞JList),只要一边是属性名,一边是值就好了.事件响应或者拖拉那些都不是主要问题,  很容易就可以实现,但是要实现到能根据数据动态生成和根据具体属性值而有不同的表现和修改方式,倒有点麻烦,如果是在不同的Column还好,但是如果在同一个Cloumn就......
一开始,我就extends了 AbstractTableModel  写了一个内部类来实现JTable的建立(具体API请看看相关基础教程),为的就是以后好动态生成数据,由于数据的连接我可以定,所以我就定了用HashMap,属性名对属性值,以下是具体代码:
    class MyTableModel extends AbstractTableModel {
        HashMap data;

        public void setData(HashMap hm, JTable table) {
            data = hm;

            /* while (j >= 0) {
                 type=array[j].getClass().toString();
                 if(type.equals("class java.util.Vector")){
                     contain=(Vector)array[j];
                     JComboBox comboBox = new JComboBox();
                     int i=contain.size()-1;
                     while(i>=0){
                         comboBox.addItem(contain.get(i--));
                     }
                     table.prepareEditor(new DefaultCellEditor(comboBox),j,1);
                 }
                 if(type.equals("class java.lang.Boolean")){
                     Boolean tf=(Boolean)array[j];

                     JCheckBox jcbox=new JCheckBox("",tf.booleanValue());
             table.getCellEditor(j,1)= new DefaultCellEditor(jcbox),j,1);

                 }
                 j--;


             }
             table.updateUI();*/

            /* table.setDefaultEditor(Vector.class,
                                    new  MyTableCellEditor());
             table.setDefaultRenderer(Vector.class,
                                      new MyComboBoxRenderer());*/
        }


        public int getColumnCount() {
            return 2;
        }

        public int getRowCount() {
            int rv = data.size();
            return rv;
        }

        public String getColumnName(int col) {
            return "   ";//这个很有意思,没有这个“  “就没有常见的表头,大家可以把它取消然后看看效果
        }

        public Object getValueAt(int row, int col) {
            if (col == 0) {
                Object[] ol = data.keySet().toArray();//这里就是建立JTable每个Cell的具体方法和Set对应
                return ol[row];

            } else {
                Object[] ol2 = data.values().toArray();
                return ol2[row];
            }
        }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */


        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            return col == 1;
        }

        /*
         * Don't need to implement this method unless your table's
         * data can change.
         */
        public void setValueAt(Object value, int row, int col) {
            if (col == 1) {
                Object[] ol = data.values().toArray();
                ol[row] = value;
            }
            fireTableCellUpdated(row, col);

        }

    }

由于一开始的时候是从别人的例子上改的,所以给误导了,因为JTable本身就有自带默认的Editor像ComboBox和CheckBox等,一般可以通过在Model中用getColumnClass方法来获得.注意!!这里就是关键,也是消耗了我国庆假期的元凶!!如果在这个内部类中重写这个方法,将可以整行获得默认的Editor来改写,很方便,如下:
    public void setUpSportColumn(JTable table,
                                 TableColumn Column) {
        //Set up the editor for the sport cells.
        JComboBox comboBox = new JComboBox();
        comboBox.addItem("Snowboarding");
        comboBox.addItem("Rowing");
        comboBox.addItem("Knitting");
        comboBox.addItem("Speed reading");
        comboBox.addItem("Pool");
        comboBox.addItem("None of the above");
        Column.setCellEditor(new DefaultCellEditor(comboBox));

        //Set up tool tips for the sport cells.
        DefaultTableCellRenderer renderer =
                new DefaultTableCellRenderer();
        renderer.setToolTipText("Click for combo box");
        Column.setCellRenderer(renderer);
    }
然后在刚才上面的内部类中添加一个getColunmClass的方法,返回是对应的某行某列的Class(注意,如果Model结构是Object[][]才可以,具体例子大家可以在互联网中找到)
但是不适合我们的需求,因为属性表只有2行,而且没列的表现都可能不同.
于是在JTable本身着手,就是他的  getCellEditor(int row, int column) ,这是我在反复单步调试而获得的最终结论,因为JTable的每个Cell的Renderer和Editor都需要定位,所谓的定位就是找出相应的Editor和Render,它内部实现是按照Column来获得的,也就是说,整个Column都用同一个Editor.这是个恶梦,当我发现的时候.然后我花了大量时间后发现它的prepareEditor(TableCellEditor editor, int row, int column) 和setDefaultEditor(Class columnClass, TableCellEditor editor) 后者是可以通过对象的Class来获得相应的Editor和Render的,但是在JTable中,关键就是getCellEditor(int row, int column)能不能正确返回某行某列的Class由于我用的HashMap(这样的用意除了键值对应还有就是当取出的对象是Vector的时候就自动封装一个JComboBox来修改).但是其实起getCellEditor(int row, int column)内部代码只用了column根本就没用到row!!hitwall.gif
     如果用Model的getColumnClass有不能获得row的参数,在不破坏封装的完整性的前提下,我还是选择了继承,把
getCellEditor(int row, int column)重写一遍
       return  getDefaultEditor(this.getModel().getValueAt(row,column).getClass());
然后在GUI中封装了自己Editor和Renderer,如:
   public class MyComboBoxRenderer implements TableCellRenderer {
        public MyComboBoxRenderer() {

        }

        public Component getTableCellRendererComponent(JTable table,
                Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
            Vector vv = null;
            if (value instanceof Vector) {
                vv = (Vector) value;

                JComboBox box = new JComboBox(vv);

                if (isSelected) {
                    setForeground(table.getSelectionForeground());
                    box.setBackground(table.getSelectionBackground());
                } else {
                    setForeground(table.getForeground());
                    setBackground(table.getBackground());
                }

                // Select the current value
                box.setSelectedItem(value);

                return box;
            }
            return null;
        }
    }
还有Renderer
   public class MyTableCellEditor extends AbstractCellEditor implements
            TableCellEditor {
        // This is the component that will handle the editing of the cell value
        JComboBox box;

        // This method is called when a cell value is edited by the user.
        public Component getTableCellEditorComponent(JTable table, Object value,
                boolean isSelected, int rowIndex, int vColIndex) {
            // 'value' is value contained in the cell located at (rowIndex, vColIndex)
            // JComboBox box=null;
            Vector vv = null;
            // if (value instanceof Vector) {
            vv = (Vector) value;

            box = new JComboBox(vv);

            if (isSelected) {
                setForeground(table.getSelectionForeground());
                box.setBackground(table.getSelectionBackground());
            } else {
                setForeground(table.getForeground());
                setBackground(table.getBackground());
            }

            // Select the current value
            box.setSelectedItem(value);

            return box;
            //}
            // return null;
        }
就能够根据如果某个cell里的是Vector就用JComboBox来修改,如果是Boolean就可以用CheckBox.其实最主要还是了解JTable的机制的问题.好了,说到这里问题就已经解决了,如果大家有问题请跟和我联络.

GUI开发之JTable,实现JB属性表 选择自 eddygtimegod 的 Blog

文章所有权归本人所有,如要用作商业用途请和我联系,如果要转贴,请注明出处和作者.Powered BY G.T.M.很高兴有时间写下自己开发的经历,又一次改变,从数据底层到了界面的GUI,一次又一次的...
  • slayer12345
  • slayer12345
  • 2004年11月28日 01:19
  • 598

java GUI界面之JTable详解

JTable是将数据以表格的形式显示给用户看的一种组件,它包括行和列,其中每列代表一种属性,例如:学号,姓名,成绩等等。而每行代表的是一个实体,例如一个学生。在JTable中,默认情况下列会平均分配父...
  • judyge
  • judyge
  • 2016年07月06日 22:05
  • 669

swing【最后一弹】JTable仿写简单Excel!

历时五天终于把所有的常用swing界面组件过了一遍,很多细节还需日后加深。愈发体会熟练查阅jdk文档的重要性,java各种类和方法太繁琐根本记不住,只能靠熟练的文档粘贴,用Eclipse会好很多。 ...
  • u012566693
  • u012566693
  • 2015年04月07日 10:28
  • 677

Java Swing JTable 表格【11:表格使用自定义渲染器】

TableCellRenderer接口定义了JTable渲染器接口: 贴图如下: 渲染器对象作为一个方法的参数来实现针对表格中的单元格的不同设置的方法之一: ...
  • zp357252539
  • zp357252539
  • 2016年01月11日 22:40
  • 2632

ArcGIS Engine 系统开发设计(三):属性表的访问与显示

这里主要是访问并显示shapefile的属性表,
  • ahlxt123
  • ahlxt123
  • 2014年07月29日 04:25
  • 3620

初用 intelliJ 的GUI Form

在用了一年的eclipse和myeclipse后,偶然在小学期课设中接触到了JetBrains 的 intelliJ ,如此便一发不可收拾地爱上了这一系列的IDE。刚好我也是web开发迷,其他几款如:...
  • hugh77
  • hugh77
  • 2015年02月14日 20:37
  • 7306

JTable中插入图片

继承DefaultTableModel ,具体的TableModel见下class CustomModel extends DefaultTableModel {        public Cust...
  • zhjian624
  • zhjian624
  • 2007年02月06日 21:53
  • 2372

【ArcEngine 10 二次开发】DataGridView显示Layer中的属性表

显示图层Layer中的属性表新建一个Form窗口using System; using System.Collections.Generic; using System.ComponentModel;...
  • gdp12315
  • gdp12315
  • 2015年05月27日 11:28
  • 1408

JTable实现数据库的操作完整版

关键字: jtable操作数据库实现增删改 最近需要使用JTa ble,第一次使用,很多不懂,到网上找了很多资料和例子,发现很多例子都没有完全的实现操作数据库里一张表的数据,摸了两天终于懂了一点,写了...
  • jokeHello
  • jokeHello
  • 2011年06月01日 22:03
  • 2703

Swing表格自定义JTable (表格可编辑)

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->im...
  • zhangli865621030
  • zhangli865621030
  • 2013年12月02日 09:56
  • 1636
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:GUI开发之JTable,实现JB属性表
举报原因:
原因补充:

(最多只允许输入30个字)