位于上海,服务全国!

位于上海,服务全国!

理解基本的JavaFX类,并知道如何使用它们

作者:admin 分类: 时间:2018-03-22 21:59:43 点击量:6005


 

java GUI的旅程开始于AWT,后来被一个更好的GUI框架所取代,其被称为Swing。Swing在GUI领域有将近20年的历史。但是,它缺乏许多当今需求的视觉功能,其不仅要求可在多个设备上运行,还要有很好的外观和感觉。在java GUI领域最有前景的是JavaFX,但没有贬低老的AWT和Swing库。因此,java自带的三个GUI工具包--AWT,Swing,和JavaFX -- 做几乎相同的工作。而JavaFX使用一些不同的方法进行GUI编程,尤其是对于Swing;在这里,我们将主要进行基础性介绍,尤其是基础类的使用和如何进行编程使用。
java GUI的一瞥
java始终缺乏一个集中GUI库的设计基础,可能是因为它不是太注重开发桌面应用程序,至少在最初阶段是这样。随着时间的推移,大众化程度逐渐提高,大家把它看作是一种通用的编程语言。最初,java提供AWT工具包,但后来被Swing GUI框架取代。他们都是java类库的的一部分,称为java基础类(JFC)。Swing成为最新的GUI工具包,其组件比以前的组件更丰富。但是,这些工具包存在一些问题,无论是性能方面还是需要的功能方面都有些问题。同时还有一些第三方库,如SWT和QtJambi,试图抢风头,但没能获得太多的开发商的兴趣,仅在小范围或社区被使用。Eclipse IDE是SWT产品的一个经典案例,且无疑其是一款优秀的产品。所以,Swing有相当长的时间 在java GUI领域被广泛使用。但Swing的问题在于它的设计不太好。

即使在最简单的情况下,它也需要进行大量的调整以适应开发者的需求,并且它也不支持现代触摸设备。除了具有良好的桌面应用程序开发环境之外,GUI组件必须能在多种设备平台上正常运行。而AWT和Swing显然都缺乏这种功能。现在,JavaFX已被推出(这个库在等待被大家注意到)。而JavaFX的新GUI工具包在巩固此类情况。好的方面在于,它重新从零开始(java FX 2版),并从GUI的视角专注于发展。自从java SE 7 Update 6和java FX 2.2,它确定性地在标准JDK分发找到了自己的位置,进而捆绑至java SE平台。目前,该命名方案符合JDK版本,如java SE 9已捆绑JavaFX 9。这是否意味着JavaFX挥手告别Swing吗?不,因为在这个框架还有很强的应用基础。但是,事实是,JavaFX是来势汹涌,Swing将继续存在,但几乎不会有太多的发展。
JavaFX与 Swing的编程结构对比
对于Swing GUI编程,许多人已经习惯了,而JavaFX开始于不同的组织结构和程序流程。
通常情况下,在Swing中的一个类,其保存所有用户组件可被称为一个框架,具有代表性的是javax.swing.jframe类。它是awt java.awt.frame类的扩展,且也是JFC/Swing组件架构的补充支持。然而,它与框架类不完全兼容,不应互换使用。JFrame 包含有次级框架 JRootPane。它是由JRootPane提供的内容面板,其包括所有JFrame中的非菜单组件,并在后台运行。这是AWT框架和Swing 框架的主要区别。现在,从程序员的角度来看,JFrame是个空的控制面板,我们可以往其添加一个或多个JPanels。JPanels像是所指定区域,我们可根据与JPanel相关的布局安排组件。有一些布局类,如FlowLayout、BorderLayout,GridLayout,等等,得在java.awt包中定义。任何有经验的java程序员会告诉你,布局类是比较粗糙的和与原代码一起运行会比较麻烦。GUI程序通常通过构建一个JFrame实例在java类中运行。

A Quick Example in Swing
package sample;
import javax.swing.*;
import java.awt.*;
public class SwingFrame extends JFrame {
   private Container container;
   public SwingFrame() throws Exception {
      super("Swing Demo");
      setSize(400, 600);
      container = getContentPane();
      container.setLayout(new BorderLayout(10, 10));
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      container.add(loginPanel(), BorderLayout.CENTER);
      setVisible(true);
      pack();
   }
   private JPanel loginPanel() throws Exception {
      JLabel l1 = new JLabel("User Name");
      JLabel l2 = new JLabel("Password");
      JTextField t1 = new JTextField();
      JPasswordField t2 = new JPasswordField();
      JButton b1 = new JButton("Login");
      JPanel panel = new JPanel(new GridLayout(3, 1, 5, 5));
      panel.add(l1);
      panel.add(t1);
      panel.add(l2);
      panel.add(t2);
      panel.add(new JLabel(""));
      panel.add(b1);
      return panel;
   }

   public static void main(String[] args) throws Exception {
      new SwingFrame();
   }
}
 
图1:用前述的Swing代码创建的登录框

A Quick Example in JavaFX
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class Main extends Application {
   @Override
   public void start(Stage primaryStage)
         throws Exception {
      primaryStage.setTitle("Login Window");
      StackPane root = new StackPane();
      root.getChildren().add(createLoginPane());
      Scene scene = new Scene(root, 400, 200);
      primaryStage.setScene(scene);
      primaryStage.show();
   }
   private Pane createLoginPane() {
      GridPane grid = new GridPane();
      grid.setPadding(new Insets(5, 5, 5, 5));
      grid.setHgap(5);
      grid.setVgap(5);
      grid.add(new Label("User Name"), 0, 0);
      grid.add(new TextField(), 1, 0);
      grid.add(new Label("Password"), 0, 1);
      grid.add(new PasswordField(), 1, 1);
      grid.add(new Button("Login"), 1, 2);
      return grid;
   }
   public static void main(String[] args) {
      launch(args);
   }
}

 
图2:通过 JavaFX创建的类似登录框
在JavaFX中,组件的顶层容器被称为一个舞台,其模仿了现实生活中的平台,其上所有的故事可能发生。实际上,也有一个名字叫“舞台”的类。在桌面上,它表示显示区域或窗口。用户界面的控件和组件包含在舞台的场景中。你猜是什么?也有一个名字叫“场景”的类。其的构思是,一个应用程序是由多个场景组成,但舞台只能在任何给定的时间段执行一个场景。场景包含一个场景图,它阐述控件和组件的位置,还包括其他事项,如控件,布局、组、形状等。这些通常称为节点,节点代表的抽象类。这种行为就像舞台上的演员一样。
有趣的是,不像Swing,布局与面板相关联,JavaFX布局子类节点与其他控件和组件类似。这个简单的构思应用了一种可以以非繁琐方式扩展的设计。
性能介绍使得JavaFX的事件处理机制简单、可轻松的跨多平台应用。
JavaFX编程的基本结构
包含有JavaFX元素的包以JavaFX前缀开始。JavaFX GUI的主要功能在四个包内定义:javafx.application,javafx.stage,javafx.scene,和javafx.scene.layout。而且,在这些包的所有类中,最重要的类是:应用程序、舞台和场景。
每一个JavaFX应用程序是应用程序类的扩展。其提供了应用程序执行的入口点。一个独立的应用程序通常是通过调用这个类定义的静态方法来运行的。应用程序类定义了三个生命周期的方法:init(), start(),和stop()。
在应用类加载和构造后不久,init()方法开始初始化。由于此方法在应用程序执行之前执行,所以我们可以在实际运行应用程序之前,执行自定义初始化过程。然而,应该指出的是,这种方法不是通过JavaFX应用程序线程调用。因此,我们不能试图用这种方法实例化一个场景或舞台。然而,我们可以通过其他JavaFX方法创建它们。
start()方法可在init()后被调用。这是构造和设置场景的地方。一个场景是以一个舞台对象而构建的。运行系统提供第一舞台,被称为主舞台。一个舞台是顶级的JavaFX容器,可以在应用程序中创建一些舞台。一个舞台对象在JavaFX应用程序线程中被构造和修改。为便于快速理解,舞台是一个典型的窗口,其由一个场景在给定的时间点装饰。

package sample;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
   @Override
   public void start(Stage primaryStage)
         throws Exception {
      Text content=new Text(10,20,"Primary Stage:
         Scene 1: Content  ");
      content.setFont(Font.font("",
         FontWeight.BOLD,20));
      Scene scene=new Scene(new Group(content));
      primaryStage.setScene(scene);
      primaryStage.sizeToScene();
      primaryStage.show();
   }

   public static void main(String[] args) {
      launch(args);
   }
}

 
图3:主舞台对象的组件
当应用程序终止时,stop()方法会被调用。这种方法通常是空的,除非在应用程序关闭之前执行一些清理操作。
关于场景的内容
包含场景的每个元素通常由一个被称为节点抽象类的节点表示。并且,节点的集合被组织在一个树形结构中,称为场景图。由于它是树形结构,所以节点之间的关系被设计为父子关系。因此,一个场景总是包含一个根节点,所有其他节点都是直接或间接由此而来。

一些常用的节点子类有父、形、画布、摄像机、控件、组、区域等。例如,不同类型的控件,如ButtonBar, SToolBar, SChoiceBox, SAccordion, SSlider, SSpinner等等,都是控制节点的子类。同样的布局,StackPane, SHbox, SVbox, SBorderPane, SGridPane,和类似的区域子类,等等。
事件处理的基础
GUI控件总与一些事件相关联,比如按钮有一个关联的处理程序事件,它定义了该按钮被单击时的功能。类似地还有,组合框、复选框、列表,都在使用时产生某个事件。虽然在JavaFX中的事件处理类似于Swing或AWT,JavaFX的事件处理机制更具有组织性。一个JavaFX事件的基础是事件类。有几个子类的事件;其中一个是ActionEvent。这个事件类处理按钮的操作。下面给出一个简单的程序演示JavaFX处理按钮的事件。

package sample;
import javafx.application.Application;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
   private static int count=0;
   @Override
   public void start(Stage primaryStage)
         throws Exception {

      Text txt=new Text(10,20,"");
      txt.setFont(Font.font("",
         FontWeight.BOLD,20));
      FlowPane root=new
         FlowPane(Orientation.VERTICAL);
      root.setHgap(10);
      root.setVgap(10);
      Button button=new Button("Click Me!");
      button.setOnAction(new EventHandler() {
         @Override
         public void handle(ActionEvent event) {
            button.setText("You clicked me "
               +(++count)+" time(s)");
            txt.setText("Your Lucky Number is "
               +(int)(Math.random()*100));
         }
      });
      root.getChildren().add(button);
      root.getChildren().add(txt);
      Scene scene=new Scene(root,400,100);
      primaryStage.setScene(scene);
      primaryStage.show();
   }

   public static void main(String[] args) {
      launch(args);
   }
}

结论
还有许多其他的类,以上介绍的只是JavaFX的基础知识,希望至少对初学者有些帮助。