前几天,在公司的项目中做了个小工具,就想起用一下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单独做一个javabean public-read var customerList : User[] = []; //复选框存储变量,所有的复选框 public-read var checkBoxList : CheckBox[] = []; //全选复选框 var HeadCheckBox:CheckBox; def panel : Panel = Panel { layoutX: 1 layoutY: 1 onLayout: onLayout } def panelClipView = ClipView { node: panel width: bind background.width height: bind background.height clipX: bind hScroll.value clipY: bind vScroll.value pannable: false } def background : Rectangle = Rectangle { width: bind width height: bind height fill: Color.DARKGRAY } //纵向滚动条 def vScroll:ScrollBar = ScrollBar { vertical: true layoutX: bind background.width height: bind height max: bind Math.max(panel.boundsInLocal.height - background.height, 1) } //横向滚动条 def hScroll:ScrollBar = ScrollBar { vertical: false layoutY: bind background.height width: 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
现在看这玩应真不怎么地