前几天,在公司的项目中做了个小工具,就想起用一下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);
}
}
分享到:
相关推荐
- `TableColumn`类用于定义表格中的列。每个`TableColumn`对象都有一个特定的数据类型,用于存储该列中的数据。例如,在示例中,`firstNameCol`、`lastNameCol`和`emailCol`分别用于存储名字、姓氏和电子邮件地址。...
本案例主要关注如何使用JavaFX 2.0来读取数据并展示在简单的表格中,特别是从Oracle数据库中获取数据并进行组装的过程。 首先,我们需要确保已经安装了JavaFX SDK,并且在项目中正确设置了相关的依赖。JavaFX 2.0...
- `TableView`是JavaFX中的一个核心组件,用于显示二维数据表格。 - 可以通过设置`TableColumn`来定义列,每个`TableColumn`对应一个数据字段。 - 支持数据绑定,可以将数据模型(如`ObservableList`)与表格视图...
在"JavaFX+Jfoenix 学习笔记(三)--TableView数据表格源码"中,我们将重点讨论如何使用JavaFX的TableView组件结合JFoenix来展示和操作数据。TableView是JavaFX中的一个核心组件,它允许用户以表格的形式查看和操作...
每个实例代表表格中的一行。 5. **列定义**:TableView的每一列都需要定义,通过`TableColumn`对象完成。每个TableColumn对应数据模型的一个属性,并指定如何显示和处理该属性。 6. **事件处理**:为了实现增删...
通过使用 FXML,开发者可以轻松地构建静态布局,如表单、控件和表格等,并且能够结合脚本实现动态布局。由于 FXML 基于 XML,因此大多数 Web 开发者和 RIA(Rich Internet Applications)平台的开发者对其感到非常...
JavaFX提供了一系列的控件,如按钮、文本框、表格、菜单等,以及强大的图形和媒体处理能力。这些功能使得开发者可以创建出具有现代用户界面的应用程序,而不必依赖于传统的AWT和Swing组件。JavaFX支持CSS样式,允许...
JavaFX学习,将表1内容拖拽至表2.
网格布局(GridPane)是一种非常灵活的布局方式,它按照行和列的二维结构组织子节点,类似于HTML中的表格。开发者可以指定节点放置在网格的特定行和列中,并且可以通过设置行列跨度来使节点横跨多行或多列。 流式...
2. **JavaFX Controls**: 这个模块包含了各种常见的GUI控件,如按钮、文本框、菜单、表格等。`javafx.controls.jar`提供了这些控件的API,开发者可以方便地创建复杂的用户界面。 3. **JavaFX Graphics**: 提供了2D...
在JavaFX 2.0中,FXML(FXML Language)被引入,这是一种基于XML的声明性语言,专门用于定义应用程序的用户界面。这个高级教程主要关注如何使用FXML来设计和构建用户界面。 FXML的优势在于它的声明性,使得UI布局...
6. **表格数据处理**: JavaFX 提供了TableView组件,可以用来展示和操作表格数据。在ERP项目中,这可能是用于显示和编辑数据库中的记录,如员工信息、订单详情等。 7. **表单数据**: 表单是收集用户输入的重要手段...
在使用JavaFX Scene Builder 2.0时,开发者可以从一个丰富的组件库中选择元素,如按钮、文本字段、表格、菜单等,将它们放置到设计画布上,并调整它们的属性,如大小、位置、颜色等。此外,可以设置布局管理器,如...
1. **丰富的UI组件库**:JavaFX包含一套完整的UI组件,如按钮、文本框、表格、菜单等,这些组件具有高度可定制性和可扩展性。 2. **2D和3D图形**:JavaFX支持高性能的2D和3D图形渲染,允许开发者创建复杂的视觉效果...
JavaFX的一个demo,带checkbox的tableview,选中一行获取所选中行的数据。
JavaFX支持多种内置组件,如按钮(Button)、文本框(TextField)、标签(Label)、表格(TableView)等,它们可以方便地通过FXML或者编程方式添加到场景中。此外,还可以自定义组件,满足特定需求。 项目中可能还...
- **用户见面控件(UI控件)**:JavaFX提供了丰富的UI控件集,涵盖了从简单的按钮到复杂的表格视图等多种类型的控件。 - **JavaFX2.0中支持的UI控件**:详细列举了JavaFX2.0版本中提供的UI控件类型及其用途。 以上...
1. **图形用户界面**:JavaFX提供丰富的组件库,如按钮、文本框、表格等,方便构建美观且交互性强的GUI。 2. **响应式设计**:JavaFX支持事件监听,使得用户交互更加直观。 3. **跨平台**:JavaFX的程序可以在不同...
在JavaFX中,开发者通常会使用Scene Builder来设计用户界面,包括按钮、文本框、表格视图等组件,以实现用户与应用的交互。例如,一个新闻查询界面可能包含一个文本框供用户输入关键词,一个按钮触发查询操作,以及...