NetBeans项目

课本上的时钟例子

在教材的第14.12节中,作者展示了JavaFX自定义窗格类ClockPane的扩展示例。

如果您可以访问教科书,您应该从阅读第14.11节开始,该节涵盖了在JavaFX窗格中绘制的基础知识。然后,阅读第14.12节中绘制模拟时钟的窗格类的扩展示例。如果你没有课本,我将在这些笔记中给出ClockPane示例的简要概述。

JavaFX中自定义窗格的基础知识

我们已经看到,JavaFX提供了广泛的类来实现常见的用户界面元素,如文本字段、按钮和菜单。对于大多数赢博体育程序,JavaFX提供的用户界面元素将足以满足您的需求。对于某些赢博体育程序,您会发现需要JavaFX不提供的用户界面元素。为了满足这些赢博体育程序的需要,JavaFX为程序员提供了构建他们自己的自定义用户界面元素的能力。

在几乎赢博体育情况下,在JavaFX中创建自己的用户界面元素的最佳方法是基于JavaFX Pane类构造一个类。Pane类被设计为与更广泛的JavaFX系统集成,并被设计为与其他常见JavaFX元素一起放置在用户界面中。同时,Pane类提供了一个空白面板,我们可以在其中放置自己的自定义绘图和事件处理。

作者的ClockPane示例首先创建一个类来扩展javafx.scene.layout.Pane类:

公共类ClockPane扩展Pane {}

在窗格中绘图

在JavaFX中创建的每个自定义窗格类都有自己独特的外观。为此,我们将添加一组JavaFX形状对象作为窗格的子对象。当JavaFX绘制窗格时,它会自动告诉窗格中包含的赢博体育形状对象自己绘制。

JavaFX中可用的一些标准形状对象包括用于创建基本形状的Line、Rectangle和Circle类,以及用于显示文本的Text类。

放置在窗格中的每个形状都有一个位置。要设置元素的位置,您将使用图形坐标系统。在这个坐标系中,基本的度量单位是像素。坐标系的原点在窗格的左上角,正x方向从那个角向右延伸,正y方向从那个角向下延伸。

您将使用的每个不同形状使用略微不同的方法来设置其位置。例如,要在窗格中放置一条线,您可以设置线段两端两点的坐标。要放置矩形,您需要指定矩形左上角的位置,然后设置矩形的宽度和高度。要放置一个圆,您需要指定圆心的位置,然后设置圆的半径。要放置文本,您需要为文本基线的起始位置指定一个位置,该基线是文本所在的假想线。

一旦你设置了一个形状的位置,你就可以设置其他重要的属性,比如它的颜色。例如,对于矩形或圆形,您可以通过调用setStroke()来设置形状边界的颜色,并通过调用setFill()来设置形状内部的颜色。

画时钟

下面是作者的ClockPane类中最重要的方法的代码,该方法设置绘制钟面所需的形状:

private void paintClock(){//初始化时钟参数double clockRadius = Math.min(getWidth(), getHeight()) * 0.8 * 0.5;double centerX = getWidth() / 2;double centerY = getHeight() / 2;//绘制圆圈圆圈圆圈= new circle (centerX, centerY, clockRadius);circle.setFill (Color.WHITE);circle.setStroke (Color.BLACK);Font = Font。Font ("sans-serif", 12);Text t1 = new Text(centerX - 5, centerY - clockRadius + 12, "12");t1.setFont(字体);Text t2 = new Text(centerX - clockRadius + 3, centerY + 5, "9");t2.setFont(字体);Text t3 = new Text(centerX + clockRadius - 10, centerY + 3, "3");t3.setFont(字体);Text t4 = new Text(centerX - 3, centerY + clockRadius - 3, "6");t4.setFont(字体);//绘制秒针double length = clockRadius * 0.8;double secondX = centerX + length * Math。sin(秒)*(2)*数学。PI / 60);double secondY = centerY - length * Math。cos(秒)*(2 *数学。PI / 60);Line sLine = new Line(centerX, centerY, secondX, secondY);sLine.setStroke (Color.RED);//绘制分针double mLength = clockRadius * 0.65;double xMinute = centerX + mLength * Math。sin(分钟)*(2)*数学。PI / 60);double minuteY = centerY - mLength * Math。cos(minute) *(2) *数学。PI / 60);Line mLine = new Line(centerX, centerY, xMinute, minuteY);mLine.setStroke (Color.BLUE);//绘制时针double hLength = clockRadius * 0.5;double hourX = centerX + hLength * Math。sin((小时% 12 +分钟/ 60.0)* (2)PI / 12);double hourY = centerY - hLength * Math。cos((小时% 12 +分钟/ 60.0)* (2)PI / 12);Line hLine = new Line(centerX, centerY, hourX, hourY);hLine.setStroke (Color.GREEN);.clear getChildren () ();getChildren()。addAll(circle, t1, t2, t3, t4, sLine, mLine, hLine);}

此方法将在ClockPane决定需要重新绘制其内容时被调用。例如,当您调用setCurrentTime()方法来设置时钟上显示的时间时,该方法将调用paintClock()来重新绘制时钟面。如果用户调整包含窗格的窗口的大小,JavaFX将调用窗格的setWidth()和setHeight()方法,这些方法又将调用paintClock()。

FXML时钟示例

我进一步更新了作者的时钟示例,以演示将自定义JavaFX窗格放入FXML用户界面。在这些注释的顶部,你会发现一个下载项目的按钮。

正如您所看到的,我已经包含了作者的ClockPane类的更新版本,作为这个项目中的一个类。

项目中超出作者在第14.12节中所演示的部分是将ClockPane集成到赢博体育程序的FXML接口所需的代码。

为了提供对自定义窗格的支持,我们像往常一样在Scene Builder中设置其余的用户界面。示例赢博体育程序的主窗口使用BorderPane作为主窗口的顶层窗格。关于这个BorderPane需要注意的重要事情是,我有意将BorderPane的中心区域保留为空:当赢博体育程序启动时,我们将在该区域插入一个ClockPane。用户界面中唯一的其他元素最初是一个出现在BorderPane底部的按钮。像往常一样,我在主控制器中设置了一个动作方法来响应对该按钮的点击。

下面是赢博体育程序主控制器类的完整代码:

公共类PrimaryController实现Initializable {@FXML BorderPane mainPane;ClockPane时钟;@FXML private void setTime(ActionEvent evt) {clock.setCurrentTime();} @Override public void initialize(URL URL, ResourceBundle rb) {clock = new ClockPane();mainPane.setCenter(时钟);}}

这个简单类中最重要的代码是initialize()方法。这就是我们创建ClockPane对象的地方,将其存储在一个成员变量中,然后将ClockPane设置为BorderPane的中心区域。

一旦将ClockPane设置为成员变量,我们就可以对其调用方法。例如,在按钮动作方法的代码中,我告诉ClockPane设置一个新的时间值。