JavaFx中的表格
前几天,在公司的项目中做了个小工具,就想起用一下JavaFx来了,貌似JavaFx不是很火啊,网上的资料还真不多,在开发过程中遇到了一些问题,下面和大家分享一下。
JavaFx学习起来不难,很快就能上手,效果也很好,但是JavaFx中没有表格,这个令我很郁闷,上网发现了一个E文的博客,里面有我想到的东西,感兴趣的可以去看看:http://blogs.sun.com/rakeshmenonp/entry/javafx_database_table
?
表格是用长方形一个一个拼上去的,不过效果挺好,我改了一下他的代码,增加了一些功能:
效果图:
主类,表格主体:
?
?
import javafx.scene.CustomNode;import javafx.scene.Node;import javafx.scene.paint.Color;import javafx.scene.shape.Rectangle;import javafx.scene.Group;import javafx.scene.layout.Panel;import javafx.scene.control.ScrollBar;import javafx.scene.layout.ClipView;import javafx.scene.layout.Resizable;import javafx.scene.input.KeyCode;import javafx.util.Math;import javafx.util.Sequences;import javafx.scene.control.CheckBox;import cn.com.jit.auth.ums.deletetool.info.User; /** * @author Rakesh Menon * @改造 helly2115 */public class CustomerTable extends CustomNode, Resizable { //列名public var columnName : String[] = [ "姓名", "ID", "性别", "地址" ];//列宽度 public var columnWidth : Number[] = [ 50, 180, 120, 40 ]; //行高度 public def rowHeight = 20.0; //是否包含复选框 public var comboBox:Boolean = false; //是否包含序号 public var index:Boolean = false; def columnCount = bind sizeof columnName; //当前选择的行 public var selectedIndex = -1 on replace {if((columnCount > 0) and (selectedIndex >= 0)) {setSelectedIndex(selectedIndex); }}//当前选择的列var columnIndex = -1;//这里是一个只读变量,用户存储用户信息,这里使用了程序在其他定义的javabean做为数据类型,也可以给这个table单独做一个javabeanpublic-read var customerList : User[] = [];//复选框存储变量,所有的复选框public-read var checkBoxList : CheckBox[] = [];//全选复选框var HeadCheckBox:CheckBox; def panel : Panel = Panel {layoutX: 1layoutY: 1onLayout: onLayout}def panelClipView = ClipView {node: panel width: bind background.width height: bind background.heightclipX: bind hScroll.valueclipY: bind vScroll.valuepannable: false}def background : Rectangle = Rectangle {width: bind widthheight: bind heightfill: Color.DARKGRAY}//纵向滚动条def vScroll:ScrollBar = ScrollBar {vertical: truelayoutX: bind background.widthheight: bind heightmax: bind Math.max(panel.boundsInLocal.height - background.height, 1)}//横向滚动条def hScroll:ScrollBar = ScrollBar {vertical: false layoutY: bind background.heightwidth: bind width max: bind Math.max(panel.boundsInLocal.width - background.width, 1) }//创建组件,是覆盖CustomNode中的抽象方法,自己写组件时必须用到的。override function create() : Node { //插入复选框 if(comboBox){ insert '' before columnName[0]; insert 20 before columnWidth[0]; } //插入序号 if(index){ insert '序号' before columnName[0];insert 40 before columnWidth[0];} //创建列头addHeader(); Group {content: [background, panelClipView, hScroll, vScroll]}; }function onLayout() : Void {var col = 0; var row = 0; var colX = 0.0; for(cell in panel.content) {cell.layoutX = colX; cell.layoutY = (rowHeight + 1) * row; (cell as Cell).width = columnWidth[col]; (cell as Cell).height = rowHeight; colX += columnWidth[col] + 1; col++; if(col >= columnCount) {col = 0; colX = 0; row++; }}}//鼠标按下事件,主要是计算当前行和当前列override var onMousePressed = function(e) {requestFocus(); if(e.source.parent.parent instanceof Cell) {var cell = (e.source.parent.parent) as Cell; var index = Sequences.indexOf(panel.content, cell)/columnCount; if(index >= 0) {selectedIndex = index - 1;}var cindex = Sequences.indexOf(panel.content, cell) mod columnCount;if(cindex >= 0) {columnIndex = cindex;}}} //鼠标点击事件,触发复选框的点击override var onMouseClicked = function(e) { if(columnIndex==1 and sizeof customerList>0){ if(selectedIndex==-1){ var flag = HeadCheckBox.selected; //全选 for(checkBox in checkBoxList){ if(flag){ checkBox.selected = false; HeadCheckBox.selected = false; }else{ checkBox.selected = true; HeadCheckBox.selected = true; }} }else{ var cb:CheckBox = checkBoxList[selectedIndex]; if(cb.selected){ cb.selected = false; }else{ cb.selected = true; } } }}//鼠标滚轮事件override var onMouseWheelMoved = function(e){ if(e.wheelRotation>0){ var index = selectedIndex + 1; if(index < ((sizeof (panel.content)/columnCount) - 1)) { selectedIndex = index; } }else{ var index = selectedIndex - 1; if(index >= 0) { selectedIndex = index; } } var total:Number = (sizeof (panel.content)/columnCount)- 1; var now:Number = selectedIndex+1; var max:Number = vScroll.max; if(total!=0){ if(selectedIndex==0){ vScroll.value = 0; }else{ vScroll.value = max*now/total; } }}//键盘事件,上下可以移动表格override var onKeyPressed = function(e) {if(e.code == KeyCode.VK_UP) {var index = selectedIndex - 1; if(index >= 0) { selectedIndex = index; }} else if(e.code == KeyCode.VK_DOWN) { var index = selectedIndex + 1; if(index < ((sizeof (panel.content)/columnCount) - 1)) { selectedIndex = index; }}}//设置被选中的function setSelectedIndex(index : Integer) : Void {for(node in panel.content) {(node as Cell).selected = false; } var arrayIndex = (index + 1) * columnCount; for(i in [arrayIndex..(arrayIndex + columnCount - 1)]) {(panel.content[i] as Cell).selected = true; }}//添加列头function addHeader() {for(header in columnName) {if(header==''){ HeadCheckBox = CheckBox{}; insert HeaderCell { graphic:HeadCheckBox } into panel.content}else{insert HeaderCell { text: "{header}" } into panel.content;} } } //增加行public function addRow(customer : User) : Void { //序号 if(index){insert Cell { text: "{(sizeof customerList)+1}" } into panel.content;} //复选框 if(comboBox){ var cb = CheckBox{}; insert cb into checkBoxList;insert Cell { graphic:cb } into panel.content; } //插入行中每一个元素 insert Cell { text: "{customer.getName()}" } into panel.content; insert Cell { text: "{customer.getIdcardnum()}" } into panel.content; insert Cell { text: "{customer.getOrgpath()}" } into panel.content; insert Cell { text: "{customer.getX509subject()}" } into panel.content; insert customer into customerList; }//清空表格public function clear() : Void { delete customerList; delete panel.content; delete checkBoxList; selectedIndex = -1; addHeader(); } //删除行public function deleteRow(index : Integer) : Void { if(index < 0) {return;} var startIndex = (columnCount * (index + 1)); for(i in [startIndex..(startIndex + columnCount - 1)]) { delete panel.content[startIndex]; }delete customerList[index]; if(index == selectedIndex) { selectedIndex = -1; }} //获取高度,覆盖Resizable中的方法override function getPrefHeight(w: Number) { if(height <= 0) { return 300;}return height; } //获取宽度,覆盖Resizable中的方法 override function getPrefWidth(h: Number) { if(width <= 0) { return 300;}return width; } }?
?列头类:
?
?
import javafx.scene.paint.Color;import javafx.scene.text.Font;import javafx.scene.text.FontWeight;/** * @author Rakesh Menon */public class HeaderCell extends Cell { override var fill = Color.rgb(93, 93, 93); override var textFill = Color.LIGHTGRAY; override var font = Font.font("sansserif", FontWeight.BOLD, 12);}
?
行类:
?
?
import javafx.scene.CustomNode;import javafx.scene.Node;import javafx.scene.paint.Color;import javafx.scene.shape.Rectangle;import javafx.scene.control.Label;import javafx.scene.Group;import javafx.scene.layout.Resizable;import javafx.scene.paint.Paint;import javafx.scene.text.Font;import javafx.scene.text.FontWeight;/** * * @author Rakesh Menon */ def margin = 3;public class Cell extends CustomNode, Resizable { public var text : String; public var graphic: Node; public var selected = false; public var fill: Paint = Color.WHITE; public var selectedFill: Paint = Color.rgb(0, 147, 255); public var textFill: Paint = Color.BLACK; public var selectedTextFill: Paint = Color.WHITE; public var font: Font = Font.font("sansserif", FontWeight.REGULAR, 12); def background = Rectangle { fill: bind if(selected) selectedFill else fill width: bind width height: bind height } def label = Label {layoutX: margin layoutY: margin text: bind "{text}"graphic: bind graphic width: bind width - (margin * 2) font: bind font textFill: bind if(selected) selectedTextFill else textFill} override function create() : Node {Group {content: [background, label] } } override function getPrefHeight(width: Number) {label.getPrefHeight(width); } override function getPrefWidth(height: Number) { label.getPrefWidth(height); }}1 楼 stride 2010-07-27 放个运行截图上来呀 2 楼 helly2115 2011-12-28 现在看这玩应真不怎么地