- 浏览: 2195105 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1240)
- mac/IOS (287)
- flutter (1)
- J2EE (115)
- android基础知识 (582)
- android中级知识 (55)
- android组件(Widget)开发 (18)
- android 错误 (21)
- javascript (18)
- linux (70)
- 树莓派 (18)
- gwt/gxt (1)
- 工具(IDE)/包(jar) (18)
- web前端 (17)
- java 算法 (8)
- 其它 (5)
- chrome (7)
- 数据库 (8)
- 经济/金融 (0)
- english (2)
- HTML5 (7)
- 网络安全 (14)
- 设计欣赏/设计窗 (8)
- 汇编/C (8)
- 工具类 (4)
- 游戏 (5)
- 开发频道 (5)
- Android OpenGL (1)
- 科学 (4)
- 运维 (0)
- 好东西 (6)
- 美食 (1)
最新评论
-
liangzai_cool:
请教一下,文中,shell、C、Python三种方式控制led ...
树莓派 - MAX7219 -
jiazimo:
...
Kafka源码分析-序列5 -Producer -RecordAccumulator队列分析 -
hp321:
Windows该命令是不是需要安装什么软件才可以?我试过不行( ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
hp321:
Chenzh_758 写道其实直接用一下代码就可以解决了:JP ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
huanghonhpeng:
大哥你真强什么都会,研究研究。。。。小弟在这里学到了很多知识。 ...
android 浏览器
最近花了一些时间学习javaFX, 要更深入地理解新GUI包, 自定义控制器可能是一个比较好的方法.
javaFX中也有类似JFormattedTextField和JSpinner的控件. 这对我来说确实是个不错的选择.
这是我的控制器:
控制器及其示例可以在这里下载(可直接导入到netbeans,见附件). 示例中还包含一个css样式文件, 它用于控制Spinner的风格是直角或圆角.
NumberTextField
NumberTextField 的实现很容易,以致我认为这算不上自定义控制器, 而仅仅是改变一个已存在的控制器的一些行为而已. NumberTextField 扩展自JFX中的文本框(TextField), 添加一个使用BigDecimal的NumberProperty作为模型, 并做一些格式化和解析处理. 就这样, 不复杂.
NumberSpinner
NumberSpinner好像复杂一点. 它构建在NumberTextField 上, 并使用递增和递减按钮来改变文本框中数字的值, 每次改变步长为stepwidth.
stepwidth和NumberFormat的初始值在构造器中指定. 文本框和按钮的大小取决于文本的大小. 文本的大小可在.css文件中设置.
number_spinner.css
最后, 控制器的样式可在css文件中设置. 我实现了圆角和直角两种风格(见上文截图). 你可以通过修改 #NumberField, #ButtonBox, #SpinnerButtonUp 和#SpinnerButtonDown 中的border/background-radiuses来切换不同的风格.
结论
从上面的例子可以看出在javaFx中自定义控制器并不困难.
javaFX中也有类似JFormattedTextField和JSpinner的控件. 这对我来说确实是个不错的选择.
这是我的控制器:
- 数字文本框(NumberTextField): 可以配置任意格式的数字;
- 微调控制器( NumberSpinner ): 可以使用键盘方向键或箭头按钮来控制数值;它也是控制器的一部分;
控制器及其示例可以在这里下载(可直接导入到netbeans,见附件). 示例中还包含一个css样式文件, 它用于控制Spinner的风格是直角或圆角.
NumberTextField
NumberTextField 的实现很容易,以致我认为这算不上自定义控制器, 而仅仅是改变一个已存在的控制器的一些行为而已. NumberTextField 扩展自JFX中的文本框(TextField), 添加一个使用BigDecimal的NumberProperty作为模型, 并做一些格式化和解析处理. 就这样, 不复杂.
import java.math.BigDecimal; import java.text.NumberFormat; import java.text.ParseException; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.control.TextField; /** * Textfield implementation that accepts formatted number and stores them in a * BigDecimal property The user input is formatted when the focus is lost or the * user hits RETURN. * * @author Thomas Bolz */ public class NumberTextField extends TextField { private final NumberFormat nf; private ObjectProperty<BigDecimal> number = new SimpleObjectProperty<>(); public final BigDecimal getNumber() { return number.get(); } public final void setNumber(BigDecimal value) { number.set(value); } public ObjectProperty<BigDecimal> numberProperty() { return number; } public NumberTextField() { this(BigDecimal.ZERO); } public NumberTextField(BigDecimal value) { this(value, NumberFormat.getInstance()); } public NumberTextField(BigDecimal value, NumberFormat nf) { super(); this.nf = nf; initHandlers(); setNumber(value); } private void initHandlers() { // try to parse when focus is lost or RETURN is hit setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent arg0) { parseAndFormatInput(); } }); focusedProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (!newValue.booleanValue()) { parseAndFormatInput(); } } }); // Set text in field if BigDecimal property is changed from outside. numberProperty().addListener(new ChangeListener<BigDecimal>() { @Override public void changed(ObservableValue<? extends BigDecimal> obserable, BigDecimal oldValue, BigDecimal newValue) { setText(nf.format(newValue)); } }); } /** * Tries to parse the user input to a number according to the provided * NumberFormat */ private void parseAndFormatInput() { try { String input = getText(); if (input == null || input.length() == 0) { return; } Number parsedNumber = nf.parse(input); BigDecimal newValue = new BigDecimal(parsedNumber.toString()); setNumber(newValue); selectAll(); } catch (ParseException ex) { // If parsing fails keep old number setText(nf.format(number.get())); } } }
NumberSpinner
NumberSpinner好像复杂一点. 它构建在NumberTextField 上, 并使用递增和递减按钮来改变文本框中数字的值, 每次改变步长为stepwidth.
stepwidth和NumberFormat的初始值在构造器中指定. 文本框和按钮的大小取决于文本的大小. 文本的大小可在.css文件中设置.
import java.math.BigDecimal; import java.text.NumberFormat; import javafx.beans.binding.NumberBinding; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.shape.LineTo; import javafx.scene.shape.MoveTo; import javafx.scene.shape.Path; import javax.swing.JSpinner; /** * JavaFX Control that behaves like a {@link JSpinner} known in Swing. The * number in the textfield can be incremented or decremented by a configurable * stepWidth using the arrow buttons in the control or the up and down arrow * keys. * * @author Thomas Bolz */ public class NumberSpinner extends HBox { public static final String ARROW = "NumberSpinnerArrow"; public static final String NUMBER_FIELD = "NumberField"; public static final String NUMBER_SPINNER = "NumberSpinner"; public static final String SPINNER_BUTTON_UP = "SpinnerButtonUp"; public static final String SPINNER_BUTTON_DOWN = "SpinnerButtonDown"; private final String BUTTONS_BOX = "ButtonsBox"; private NumberTextField numberField; private ObjectProperty<BigDecimal> stepWitdhProperty = new SimpleObjectProperty<>(); private final double ARROW_SIZE = 4; private final Button incrementButton; private final Button decrementButton; private final NumberBinding buttonHeight; private final NumberBinding spacing; public NumberSpinner() { this(BigDecimal.ZERO, BigDecimal.ONE); } public NumberSpinner(BigDecimal value, BigDecimal stepWidth) { this(value, stepWidth, NumberFormat.getInstance()); } public NumberSpinner(BigDecimal value, BigDecimal stepWidth, NumberFormat nf) { super(); this.setId(NUMBER_SPINNER); this.stepWitdhProperty.set(stepWidth); // TextField numberField = new NumberTextField(value, nf); numberField.setId(NUMBER_FIELD); // Enable arrow keys for dec/inc numberField.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent keyEvent) { if (keyEvent.getCode() == KeyCode.DOWN) { decrement(); keyEvent.consume(); } if (keyEvent.getCode() == KeyCode.UP) { increment(); keyEvent.consume(); } } }); // Painting the up and down arrows Path arrowUp = new Path(); arrowUp.setId(ARROW); arrowUp.getElements().addAll(new MoveTo(-ARROW_SIZE, 0), new LineTo(ARROW_SIZE, 0), new LineTo(0, -ARROW_SIZE), new LineTo(-ARROW_SIZE, 0)); // mouse clicks should be forwarded to the underlying button arrowUp.setMouseTransparent(true); Path arrowDown = new Path(); arrowDown.setId(ARROW); arrowDown.getElements().addAll(new MoveTo(-ARROW_SIZE, 0), new LineTo(ARROW_SIZE, 0), new LineTo(0, ARROW_SIZE), new LineTo(-ARROW_SIZE, 0)); arrowDown.setMouseTransparent(true); // the spinner buttons scale with the textfield size // TODO: the following approach leads to the desired result, but it is // not fully understood why and obviously it is not quite elegant buttonHeight = numberField.heightProperty().subtract(3).divide(2); // give unused space in the buttons VBox to the incrementBUtton spacing = numberField.heightProperty().subtract(2).subtract(buttonHeight.multiply(2)); // inc/dec buttons VBox buttons = new VBox(); buttons.setId(BUTTONS_BOX); incrementButton = new Button(); incrementButton.setId(SPINNER_BUTTON_UP); incrementButton.prefWidthProperty().bind(numberField.heightProperty()); incrementButton.minWidthProperty().bind(numberField.heightProperty()); incrementButton.maxHeightProperty().bind(buttonHeight.add(spacing)); incrementButton.prefHeightProperty().bind(buttonHeight.add(spacing)); incrementButton.minHeightProperty().bind(buttonHeight.add(spacing)); incrementButton.setFocusTraversable(false); incrementButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent ae) { increment(); ae.consume(); } }); // Paint arrow path on button using a StackPane StackPane incPane = new StackPane(); incPane.getChildren().addAll(incrementButton, arrowUp); incPane.setAlignment(Pos.CENTER); decrementButton = new Button(); decrementButton.setId(SPINNER_BUTTON_DOWN); decrementButton.prefWidthProperty().bind(numberField.heightProperty()); decrementButton.minWidthProperty().bind(numberField.heightProperty()); decrementButton.maxHeightProperty().bind(buttonHeight); decrementButton.prefHeightProperty().bind(buttonHeight); decrementButton.minHeightProperty().bind(buttonHeight); decrementButton.setFocusTraversable(false); decrementButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent ae) { decrement(); ae.consume(); } }); StackPane decPane = new StackPane(); decPane.getChildren().addAll(decrementButton, arrowDown); decPane.setAlignment(Pos.CENTER); buttons.getChildren().addAll(incPane, decPane); this.getChildren().addAll(numberField, buttons); } /** * increment number value by stepWidth */ private void increment() { BigDecimal value = numberField.getNumber(); value = value.add(stepWitdhProperty.get()); numberField.setNumber(value); } /** * decrement number value by stepWidth */ private void decrement() { BigDecimal value = numberField.getNumber(); value = value.subtract(stepWitdhProperty.get()); numberField.setNumber(value); } public final void setNumber(BigDecimal value) { numberField.setNumber(value); } public ObjectProperty<BigDecimal> numberProperty() { return numberField.numberProperty(); } public final BigDecimal getNumber() { return numberField.getNumber(); } // debugging layout bounds public void dumpSizes() { System.out.println("numberField (layout)=" + numberField.getLayoutBounds()); System.out.println("buttonInc (layout)=" + incrementButton.getLayoutBounds()); System.out.println("buttonDec (layout)=" + decrementButton.getLayoutBounds()); System.out.println("binding=" + buttonHeight.toString()); System.out.println("spacing=" + spacing.toString()); } }
number_spinner.css
最后, 控制器的样式可在css文件中设置. 我实现了圆角和直角两种风格(见上文截图). 你可以通过修改 #NumberField, #ButtonBox, #SpinnerButtonUp 和#SpinnerButtonDown 中的border/background-radiuses来切换不同的风格.
.root{ -fx-font-size: 24pt; /* -fx-base: rgb(255,0,0);*/ /* -fx-background: rgb(50,50,50);*/ } #NumberField { -fx-border-width: 1; -fx-border-color: lightgray; -fx-background-insets:1; -fx-border-radius:3 0 0 3; /* -fx-border-radius:0 0 0 0;*/ } #NumberSpinnerArrow { -fx-fill: gray; -fx-stroke: gray; /* -fx-effect: innershadow( gaussian , black , 2 , 0.6 , 1 , 1 )*/ } #ButtonsBox { -fx-border-color:lightgray; -fx-border-width: 1 1 1 0; -fx-border-radius: 0 3 3 0; /* -fx-border-radius: 0 0 0 0;*/ } #SpinnerButtonUp { -fx-background-insets: 0; -fx-background-radius:0 3 0 0; /* -fx-background-radius:0;*/ } #SpinnerButtonDown { -fx-background-insets: 0; -fx-background-radius:0 0 3 0; /* -fx-background-radius:0;*/ }
结论
从上面的例子可以看出在javaFx中自定义控制器并不困难.
发表评论
-
小程序textarea完美填坑
2020-07-07 16:09 518相信做微信小程序的码友们都被textarea这个原生组件坑过 ... -
Nginx+Https自己敲命令生成证书
2020-05-18 09:35 945一、准备 环境:centos6.8 ... -
https证书生成环境搭建配置(基于Tomcat和Nginx)
2020-04-24 11:06 819一、基于Tomcat、JDK内置密钥工具: 1、生成服务端证 ... -
史上最强Tomcat8性能优化
2019-11-01 21:41 882授人以鱼不如授人以渔 ... -
SpringBoot配置HTTPS,并实现HTTP访问自动转HTTPS访问
2019-10-07 09:13 5591.使用jdk自带的 keytools 创建证书 打开cmd ... -
Spring Boot工程集成全局唯一ID生成器 UidGenerator
2019-09-16 09:04 854概述 流水号生成器(全局唯一 ID生成器)是服务化系统的基础 ... -
CentOS7下Redis的安装与使用
2019-08-17 11:45 605一、手动安装过程 1、准备工作(安装gcc依赖) yum ... -
Nginx与tomcat组合的简单使用
2019-08-17 10:05 428配置tomcat跳转 请求http出现400的时候在这里配置 ... -
linux下lvs+keepalived安装配置
2019-07-10 14:20 461keepalived主机:192.168.174. ... -
使用Docker搭建Tomcat运行环境
2019-02-08 21:32 4871 准备宿主系统 准备一 ... -
Netty笔记-GlobalEventExecutor
2019-02-06 23:00 6341.概念 /** * Single-thread si ... -
Netty4转发服务的实现方案
2019-02-06 15:03 1132如果用Netty做转发服务(不需要同步应答),Netty中有一 ... -
java手机号归属地查询
2018-12-25 17:16 744所需的包:carrier-1.75.jar 、geocoder ... -
基于Netty4的HttpServer和HttpClient的简单实现
2018-10-17 20:02 682Http 消息格式: Http request: Met ... -
我的Java(定制你的Java/JavaFX Runtime)
2018-10-12 23:29 677最新的JDK 11发布了,撒花 新版本的JDK终于有了ope ... -
javaFX的几个新特性,让swing彻底过时
2018-10-12 22:42 665首先声明,Java的GUI曾经 ... -
mac os系统用install4j把jar包生成app
2018-10-05 23:02 1423install4j有windows版也有mac版 mac电脑 ... -
JavaFX Alert对话框
2018-10-05 22:01 23631. 标准对话框 消息对话框 Alert alert = ... -
IDEA Properties中文unicode转码问题
2017-02-17 19:54 1031摘要: 如何让IDEA的properties中的中文进行uni ... -
spring 3中新增的@value注解
2016-11-01 09:32 638在spring 3.0中,可以通过使用@value,对一些如x ...
相关推荐
总之,`javafx2 : 支持使用微调(spinner)控制的数字的文本框(NemberTextField)`涉及到的关键知识点包括JavaFX的`Spinner`控件、`NumberTextField`(可能来自第三方库)的使用,以及如何将两者绑定实现数值输入的同步...
### JavaFX: 开发丰富的互联网应用 #### 一、引言 随着互联网技术的飞速发展,用户对于网络应用的视觉效果与交互体验有了更高的期待。为了满足这一需求,Sun Microsystems 在 2008 年推出了 JavaFX,这是一种全新的...
### JavaFX:Java的现代UI革命 #### JavaFX概述 JavaFX是Java生态系统中的一个重要组成部分,专注于提供现代、丰富的用户界面开发解决方案。随着用户对于应用界面的要求越来越高,JavaFX成为了开发高质量、跨平台...
在贪吃蛇游戏中,我们需要使用JavaFX的Scene类来定义游戏区域,以及Rectangle、Circle等图形对象来表示蛇、食物和边界。 项目中的`Snake_code.zip`包含了源代码,我们可以从中学习如何使用JavaFX编写游戏逻辑。游戏...
2. **Rich UI 控件**:JavaFX 提供了一系列内置的UI控件,如按钮、文本框、菜单、表格、滑块、进度条等,这些控件都具有良好的可定制性和响应性。 3. **2D 和 3D 图形**:JavaFX 支持2D和3D图形渲染,允许开发者...
在JavaFX中,实现百度文本框的下拉提示功能,主要涉及到的是文本输入与实时匹配的概念,这在很多用户界面中都有广泛的应用,如搜索引擎、输入法等。这个功能能够提高用户体验,帮助用户快速找到他们可能正在寻找的...
在这个项目中,“Chess-JavaFX”是一款使用JavaFX技术开发的国际象棋游戏,它展示了JavaFX在游戏开发中的应用。下面将详细介绍这个项目的相关知识点。 一、JavaFX基础 JavaFX提供了丰富的API,可以方便地创建出...
Javafx 2.0: Introduction by Example
JavaFX 使用指南 JavaFX 是一个基于 Java 语言的软件平台,用于开发桌面应用程序、移动应用程序和网络应用程序。它提供了一个统一的编程模型,可以跨平台运行,具有高清晰度的图形用户界面和多媒体支持。 JavaFX ...
这个压缩包“JavaFX:用于练习 JavaFX 和示例实现的文件夹”显然是一个学习资源,包含了练习和示例代码,帮助开发者熟悉JavaFX的使用。 JavaFX 的核心特性包括: 1. **丰富的UI组件**:JavaFX 提供了一系列预定义的...
本项目“JavaFx:使用javaFx gui API的todolist”显然是一个基于JavaFX实现的任务管理应用,它利用了JavaFX的GUI API来设计和实现待办事项列表的功能。 在JavaFX中,我们首先需要导入相关的库,通常通过在`pom.xml`...
【JVx JavaFX:使用JavaFX的JVx UI实现】是一种开源技术,它结合了JavaFX的图形渲染能力和JVx(Java Virtual eXtension)的业务逻辑框架,为开发者提供了一种创建本机JavaFX应用程序的新途径。JVx是一个灵活且可扩展...
使用 akka 框架的 JavaFX 的 EventBus 使用命令构建并安装到本地 maven: gradle install 然后你可以从你的本地 Maven 中包含这个依赖: repositories { mavenCentral() mavenLocal() } dependencies { ...
1. **组件库**:JavaFX 提供了一系列预先构建的 UI 控件,如按钮、文本框、表格、菜单等,这些控件可以轻松地组合起来创建复杂的用户界面。 2. **样式和皮肤**:JavaFX 支持 CSS 样式化,允许开发者通过 CSS 文件来...
《FlappyBird-JavaFx:使用JavaFx构建经典游戏》 在编程世界中,复现经典游戏是一种常见的学习和实践方式。"FlappyBird-JavaFx"项目正是这样一个实例,它利用JavaFx这一强大的图形用户界面(GUI)库,重新实现了广...
在该项目中,开发者使用了`mvn javafx:run`命令来启动应用。这是Maven的JavaFX插件提供的一个目标,它能够自动处理JavaFX的运行时环境,并且编译、打包以及运行项目。这表明项目使用了Maven作为构建工具,Maven能...
可以使用CSS设置JavaFX组件的样式,并且可以使用FXML而不是Java代码来构成图形用户界面。 这使得在不浪费时间在Java代码上的情况下,更容易快速地将GUI放在一起,或者更改外观或布局。 JavaFX包含一组现成的图表...
在JavaFX中,你可以使用FXML(FXML Layout)进行界面设计,这是一种XML格式的文件,可以分离UI设计与业务逻辑,使得代码更易维护。同时,JavaFX还支持CSS样式,让开发者能够像设计网页一样定制应用的外观和感觉。 ...