分享
 
 
 

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

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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

很高兴有时间写下自己开发的经历,又一次改变,从数据底层到了界面的GUI,一次又一次的挑战,我想,我在成长.

等我以后开发了新的东西或者解决新的问题,再写一遍血泪史,国庆的假期就为这个属性表给占了

不说太多,入正题:

用过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!!

如果用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的机制的问题.好了,说到这里问题就已经解决了,如果大家有问题请跟和我联络.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有