首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

学习定做表格树的项(一)

2012-11-21 
学习定制表格树的项(一)原文:http://www.eclipse.org/articles/article.php?fileArticle-CustomDrawingTa

学习定制表格树的项(一)
原文:http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html

本来将原来那篇拷贝过来,想写一些注释的,但太大了,太慢了,还是另写吧:

??总述

1,为什么要定制去画呢?

因为原来的Item有自己的局限性:?For?example,?an?item?in?a?table?or?tree?can?only?contain?one?image,?and?it?must?appear?before?its?text.?Item的一个单元只能支持一个图像,而且只能默认画在字符串的前面。

?

2,在定制Item的时候,是基于Cell来画制的,什么是Cell,如果一个Table有2列3行,那么它就有6个Cell。

?

3,定制Item是由三个事件完成的,SWT.MeasureItem,SWT.EraseItem和SWT.PaintItem。

?1,?SWT.MeasureItem

1,SWT.MeasureItem是第一调用的用户定制事件。

2,SWT.MeasureItem中控制的content?size而不是cell?size,因为cell?size包括了额外的装饰如checkboxes?or?tree?indentation

SWT.MeasureItem事件预定的变量:

?

?3,例子

??

public?class?Snippet271?{

public?static?void?main(String[]?args)?{

Display?display?=?new?Display();

Shell?shell?=?new?Shell(display);

shell.setBounds(10,10,150,150);

shell.setLayout(new?FillLayout());

?

Table?table?=?new?Table(shell,?SWT.NONE);

table.setLinesVisible(true);

for?(int?i?=?0;?i<3;?i++)?{

new?TableItem(table,?SWT.NONE).setText("item?"?+?i);

}

table.addListener(SWT.MeasureItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

event.height?=?event.gc.getFontMetrics().getHeight()?*?2;

event.width?*=??2;

}

});

shell.open();

while?(!shell.isDisposed())?{

if?(!display.readAndDispatch())?display.sleep();

}

display.dispose();

}

}

?


?
学习定做表格树的项(一)
?
?

?程序中设置了Item的高度为gc字体高度的两倍,宽度为本来宽度的两倍。

??


学习定做表格树的项(一)
?

这个是不改变Item高和宽的情况。

4,利用SWT.MeasureItem?改变Item的宽和高的有如下的限制:

a,现在宽和高时不可以缩小到比默认的小的,只能放大,不能缩小。

b,所有的Item在一个表格或一个Tree中,只有一个大小的高,增大一个,增大所有。

c,对于已经设置了宽度的column,SWT.MeasureItem?不起作用,在column调用Pack的时候,起作用。

例子:

?

public?class?Snippet272?{

public?static?void?main(String[]?args)?{

Display?display?=?new?Display();?

Shell?shell?=?new?Shell(display);

shell.setBounds(10,10,400,200);

Table?table?=?new?Table(shell,?SWT.NONE);

table.setBounds(10,10,350,150);

table.setHeaderVisible(true);

table.setLinesVisible(true);

final?TableColumn?column0?=?new?TableColumn(table,?SWT.NONE);

column0.setWidth(100);?column0.setText("col1");

final?TableColumn?column1?=?new?TableColumn(table,?SWT.NONE);

column1.setWidth(100);?column1.setText("col2");

column0.addListener(SWT.Selection,?new?Listener()?{

public?void?handleEvent(Event?event)?{

column0.pack();

}

});

for?(int?i?=?0;?i?<?5;?i++)?{

TableItem?item?=?new?TableItem(table,?SWT.NONE);

item.setText(0,?"item?"?+?i?+?"?col?0");

item.setText(1,?"item?"?+?i?+?"?col?1");

}

table.addListener(SWT.MeasureItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

event.width?*=?2;

}

});

?

shell.open();

while?(!shell.isDisposed())?{

if?(!display.readAndDispatch())?display.sleep();

}

display.dispose();

}

}

?

?

?

学习定做表格树的项(一)
?
??

col1只用在点击时调用column0.pack(),SWT.MeasureItem中定义的宽带加倍才起作用。

?

2,SWT.EraseItem?

SWT.EraseItem是被调用的第二个事件,这个事件是在画背景前调用。背景包括背景和选择背景,这个事件允许用户画背景和选择背景。

该事件的预定义的变量:

detail:?the?logical?OR?of?one?or?more?of?the?following?bits,?indicating?what?will?be?drawn?by?default:?

?

?

doit:?this?boolean?indicates?whether?the?table?will?do?the?drawing?specified?in?the?detail?field?once?this?listener?has?completed?(default?is?true)

?

?例子:

?

public?class?Example3?{

public?static?void?main(String[]?args)?{

Display?display?=?new?Display();?

Shell?shell?=?new?Shell(display);

final?Color?red?=?display.getSystemColor(SWT.COLOR_RED);

final?Color?yellow?=?display.getSystemColor(SWT.COLOR_YELLOW);

final?Table?table?=?new?Table(shell,?SWT.FULL_SELECTION);

table.setHeaderVisible(true);

new?TableColumn(table,?SWT.NONE).setWidth(100);

new?TableColumn(table,?SWT.NONE).setWidth(100);

new?TableColumn(table,?SWT.NONE).setWidth(100);

for?(int?i?=?0;?i?<?5;?i++)?{

TableItem?item?=?new?TableItem(table,?SWT.NONE);

item.setText(0,?"item?"?+?i?+?"?col?0");

item.setText(1,?"item?"?+?i?+?"?col?1");

item.setText(2,?"item?"?+?i?+?"?col?2");

}

table.addListener(SWT.EraseItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

event.detail?&=?~SWT.HOT;

if?((event.detail?&?SWT.SELECTED)?==?0)?return;?/*?item?not?selected?*/

int?clientWidth?=?table.getClientArea().width;

GC?gc?=?event.gc;

Color?oldForeground?=?gc.getForeground();

Color?oldBackground?=?gc.getBackground();

gc.setForeground(red);

gc.setBackground(yellow);

gc.fillGradientRectangle(event.x,?event.y,?event.width,?event.height,?false);

gc.setForeground(oldForeground);

gc.setBackground(oldBackground);

event.detail?&=?~SWT.SELECTED;

}

});

?

table.pack();

shell.pack();

shell.open();

while?(!shell.isDisposed())?{

if?(!display.readAndDispatch())?display.sleep();

}

display.dispose();

}

}

?

?
学习定做表格树的项(一)
?
?实现了选择的在Item中,画上一个渐变的背景色。

这里要注意:

a,不能用event.detail==SWT.SELECTED的方法来判断有没有被选择上,这里detail可能好多位有效。

b,处理完最好要取消SWT.SELECTED事件,event.detail?&=?~SWT.SELECTED取消,要不然默认的处理SELECTED的事件还是要被调用。

c,这里的gc.fillGradientRectangle(0,?event.y,?clientWidth,?event.height,?false);坐标用的0和clientWidth,如果用gc.fillGradientRectangle(event.x,?event.y,?event.width,?event.height,?false);就成了下图的效果,想想就知道了,EraseItem事件是针对每一个cell,这样就是三个独立的cell画了三次,实际上上面也是画了三次,只不过都是重复了。



学习定做表格树的项(一)
?
?

?

再一个画背景的例子:

?

public?class?Snippet273?{

public?static?void?main(String[]?args)?{

final?String[]?MONTHS?=?{

"Jan",?"Feb",?"Mar",?"Apr",?"May",?"Jun",

"Jul",?"Aug",?"Sep",?"Oct",?"Nov",?"Dec"

};

final?int[]?HIGHS?=?{-7,?-4,?1,?11,?18,?24,?26,?25,?20,?13,?5,?-4};

final?int[]?LOWS?=?{-15,?-13,?-7,?1,?7,?13,?15,?14,?10,?4,?-2,?-11};

final?int?SCALE_MIN?=?-30;?final?int?SCALE_MAX?=?30;

final?int?SCALE_RANGE?=?Math.abs(SCALE_MIN?-?SCALE_MAX);

?

Display?display?=?new?Display();

Shell?shell?=?new?Shell(display);

shell.setBounds(10,10,400,350);

shell.setText("Ottawa?Average?Daily?Temperature?Ranges");

final?Color?blue?=?display.getSystemColor(SWT.COLOR_BLUE);

final?Color?white?=?display.getSystemColor(SWT.COLOR_WHITE);

final?Color?red?=?display.getSystemColor(SWT.COLOR_RED);

//?final?Image?parliamentImage?=?new?Image(display,?"./parliament.jpg");

final?Table?table?=?new?Table(shell,?SWT.NONE);

table.setHeaderVisible(true);

table.setLinesVisible(true);

table.setBounds(10,10,350,300);

//?table.setBackgroundImage(parliamentImage);

for?(int?i?=?0;?i?<?12;?i++)?{

TableItem?item?=?new?TableItem(table,?SWT.NONE);

item.setText(MONTHS[i]?+?"?("?+?LOWS[i]?+?"C..."?+?HIGHS[i]?+?"C)");

}

final?int?clientWidth?=?table.getClientArea().width;

?

table.addListener(SWT.MeasureItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

int?itemIndex?=?table.indexOf((TableItem)event.item);

int?rightX?=?(HIGHS[itemIndex]?-?SCALE_MIN)?*?clientWidth/SCALE_RANGE;

event.width?=?rightX;

}

});

table.addListener(SWT.EraseItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

int?itemIndex?=?table.indexOf((TableItem)event.item);

int?leftX?=?(LOWS[itemIndex]?-?SCALE_MIN)?*?clientWidth/SCALE_RANGE;

int?rightX?=?(HIGHS[itemIndex]?-?SCALE_MIN)?*?clientWidth/SCALE_RANGE;

GC?gc?=?event.gc;

Rectangle?clipping?=?gc.getClipping();

clipping.x?=?leftX;

clipping.width?=?rightX?-?leftX;

gc.setClipping(clipping);

?

Color?oldForeground?=?gc.getForeground();

Color?oldBackground?=?gc.getBackground();

gc.setForeground(blue);

gc.setBackground(white);

gc.fillGradientRectangle(event.x,?event.y,?event.width/2,?event.height,?false);

gc.setForeground(white);

gc.setBackground(red);

gc.fillGradientRectangle(

event.x?+?event.width/2,?event.y,?event.width/2,?event.height,?false);

gc.setForeground(oldForeground);

gc.setBackground(oldBackground);

event.detail?&=?~SWT.BACKGROUND;

event.detail?&=?~SWT.HOT;

}

});

shell.open();

while?(!shell.isDisposed())?{

if?(!display.readAndDispatch())?display.sleep();

}

//?parliamentImage.dispose();

display.dispose();

}

}

?



学习定做表格树的项(一)
?
这个程序画了渥太华的12个月的温度情况,画的非常的逼真啊。

?画法就是每一列的长度为【(HIGHS[itemIndex]?-?SCALE_MIN)?*?clientWidth/SCALE_RANGE;】,画的时候把gc中设置一个clipping,这样就只有这个回形针区域可以画上去了。然后两段都是渐进第一段蓝色到白色渐进,第二段是白色到红色渐进,蓝色表示冷,红色表示热了。还是比较形象的。

?

?3,SWT.PaintItem?

这个事件在默认的前景已经画好后,再调用。

这个事件的预定义的变量有:

例子:

?

public?class?Snippet220?{

public?static?void?main(String?[]?args)?{

Display?display?=?new?Display();

Shell?shell?=?new?Shell(display);

shell.setBounds(10,?10,?350,?200);

Image?xImage?=?new?Image?(display,?16,?16);

GC?gc?=?new?GC(xImage);

gc.setForeground(display.getSystemColor(SWT.COLOR_RED));

gc.drawLine(1,?1,?14,?14);

gc.drawLine(1,?14,?14,?1);

gc.drawOval(2,?2,?11,?11);

gc.dispose();

final?int?IMAGE_MARGIN?=?2;

final?Tree?tree?=?new?Tree(shell,?SWT.CHECK);

tree.setBounds(10,?10,?300,?150);

TreeItem?item?=?new?TreeItem(tree,?SWT.NONE);

item.setImage(xImage);

item.setText("root?item");

for?(int?i?=?0;?i?<?4;?i++)?{

TreeItem?newItem?=?new?TreeItem(item,?SWT.NONE);

newItem.setText("descendent?"?+?i);

if?(i?%?2?==?0)?{

newItem.setData(xImage);

}

newItem.setImage(xImage);

item.setExpanded(true);

item?=?newItem;

}

?

tree.addListener(SWT.MeasureItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

TreeItem?item?=?(TreeItem)event.item;

Image?trailingImage?=?(Image)item.getData();

if?(trailingImage?!=?null)?{

event.width?+=?trailingImage.getBounds().width?+?IMAGE_MARGIN;

}

}

});

tree.addListener(SWT.PaintItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

TreeItem?item?=?(TreeItem)event.item;

Image?trailingImage?=?(Image)item.getData();

if?(trailingImage?!=?null)?{

int?x?=?event.x?+?event.width?+?IMAGE_MARGIN;

int?itemHeight?=?tree.getItemHeight();

int?imageHeight?=?trailingImage.getBounds().height;

int?y?=?event.y?+?(itemHeight?-?imageHeight)?/?2;

event.gc.drawImage(trailingImage,?x,?y);

}

}

});

?

shell.open();

while?(!shell.isDisposed())?{

if?(!display.readAndDispatch())?display.sleep();

}

xImage.dispose();

display.dispose();

}

}

?


?
学习定做表格树的项(一)
?

?

在Item的后面,画图像。

可不可完全由我们来画,不好默认的呢?

下面例子:

?

public?class?Snippet231?{

public?static?void?main(String?[]?args)?{

final?int?COLUMN_COUNT?=?4;

final?int?ITEM_COUNT?=?8;

final?int?TEXT_MARGIN?=?3;

Display?display?=?new?Display();

Shell?shell?=?new?Shell(display);

final?Table?table?=?new?Table(shell,?SWT.FULL_SELECTION);

table.setHeaderVisible(true);

table.setLinesVisible(true);

for?(int?i?=?0;?i?<?COLUMN_COUNT;?i++)?{

new?TableColumn(table,?SWT.NONE);

}

for?(int?i?=?0;?i?<?ITEM_COUNT;?i++)?{

TableItem?item?=?new?TableItem(table,?SWT.NONE);

for?(int?j?=?0;?j?<?COLUMN_COUNT;?j++)?{

String?string?=?"item?"?+?i?+?"?col?"?+?j;

if?((i?+?j)?%?3?==?1)?{

string?+="\nnew?line1";

}

if?((i?+?j)?%?3?==?2)?{

string?+="\nnew?line1\nnew?line2";

}

item.setText(j,?string);

}

}

?

table.addListener(SWT.MeasureItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

TableItem?item?=?(TableItem)event.item;

String?text?=?item.getText(event.index);

Point?size?=?event.gc.textExtent(text);

event.width?=?size.x?+?2?*?TEXT_MARGIN;

event.height?=?Math.max(event.height,?size.y?+?TEXT_MARGIN);

}

});

table.addListener(SWT.EraseItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

event.detail?&=?~SWT.FOREGROUND;

}

});

table.addListener(SWT.PaintItem,?new?Listener()?{

public?void?handleEvent(Event?event)?{

TableItem?item?=?(TableItem)event.item;

String?text?=?item.getText(event.index);

/*?center?column?1?vertically?*/

int?yOffset?=?0;

if?(event.index?==?1)?{

Point?size?=?event.gc.textExtent(text);

yOffset?=?Math.max(0,?(event.height?-?size.y)?/?2);

}

event.gc.drawText(text,?event.x?+?TEXT_MARGIN,?event.y?+?yOffset,?true);

}

});

?

for?(int?i?=?0;?i?<?COLUMN_COUNT;?i++)?{

table.getColumn(i).pack();

}

table.pack();

shell.pack();

shell.open();

while?(!shell.isDisposed())?{

if?(!display.readAndDispatch())?display.sleep();

}

display.dispose();

}

}

?

?


学习定做表格树的项(一)
?
??

?表格中width取字符串宽加空白边框,height是字符串高加空白边框。这里的高和宽都是有GC计算的。

SWT.EraseItem事件取消的SWT.FOREGROUND事件,完全有我们自己去画了,画的时候用event.gc.drawText就行了。注意最后的column.pack()是必须的,前面没有设置column的宽度,调用pack才会计算column的宽度。

?

?文章看完了,比较的长,看几遍,有些问题还没有拓展。在网页上编辑,代码总是乱,没有办法只有在word编辑了再考上去了。

原文链接:http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html

?

热点排行