当前位置: 代码迷 >> Web前端 >> JavaFx中的报表
  详细解决方案

JavaFx中的报表

热度:241   发布时间:2012-10-31 14:37:31.0
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单独做一个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  
现在看这玩应真不怎么地
  相关解决方案