JavaFX UI控件教程(二十二)之Titled Pane和Accordion

翻译自  Titled Pane and Accordion

本章介绍如何在JavaFX应用程序中使用accordion和title窗格的组合。

标题窗格是带标题的面板。它可以打开和关闭,它可以封装任何Node诸如UI控件或图像以及添加到布局容器的元素组。

标题窗格可以使用手风琴控件进行分组,这使您可以创建多个窗格并一次显示一个窗格。图21-1显示了一个结合了三个标题窗格的手风琴控件。

图21-1带有三个标题的折叠窗格

使用JavaFX SDK API中的AccordionTitledPane类在应用程序中实现这些控件。

创建标题窗格

创建TitledPane控件定义标题和一些内容。您可以通过使用类的双参数构造函数TitledPane或应用setTextsetContent方法来完成此操作。两种方法都显示在例21-1中

例21-1声明TitledPane对象

//using a two-parameter constructor
TitledPane tp = new TitledPane("My Titled Pane", new Button("Button"));
//applying methods
TitledPane tp = new TitledPane();
tp.setText("My Titled Pane");
tp.setContent(new Button("Button"));

使用任一代码片段编译和运行应用程序将生成如图21-2所示的控件。

图21-2带按钮的标题窗格

标题窗格的大小调整为适应其内容的首选大小。您可以添加多行文本并评估结果,如图21-3所示。

图21-3带有一些文本的标题窗格

不要显式设置标题窗格的最小高度,最大高度或首选高度,因为这可能会在打开或关闭标题窗格时导致意外行为。

例21-2中显示的代码片段通过将几个控件放入GridPane布局容器中,将几个控件添加到标题窗格中。

示例21-2带有GridPane布局容器的标题窗格

TitledPane gridTitlePane = new TitledPane();
GridPane grid = new GridPane();
grid.setVgap(4);
grid.setPadding(new Insets(5, 5, 5, 5));
grid.add(new Label("First Name: "), 0, 0);
grid.add(new TextField(), 1, 0);
grid.add(new Label("Last Name: "), 0, 1);
grid.add(new TextField(), 1, 1);
grid.add(new Label("Email: "), 0, 2);
grid.add(new TextField(), 1, 2);        
gridTitlePane.setText("Grid");
gridTitlePane.setContent(grid);

使用此代码片段运行和编译应用程序时,将显示如图21-4所示的输出。

图21-4包含多个控件的标题窗格

您可以定义标题窗格的打开和关闭方式。默认情况下,所有标题窗格都是可折叠的,并且它们的移动是动画的。如果您的应用程序禁止关闭标题窗格,请使用setCollapsible带有false值的方法。您还可以通过应用setAnimated带有false值的方法来禁用动画打开。例21-3中显示的代码片段实现了这些任务。

例21-3调整标题窗格的样式

TitledPane tp = new TitledPane();
//prohibit closing
tp.setCollapsible(false);
//prohibit animating
tp.setAnimated(false);

将标题窗格添加到折叠中

在您的应用程序中,您可以使用标题窗格作为独立元素,或者可以使用Accordion控件将它们组合在一个组中。不要明确设置手风琴的最小,最大或首选高度,因为这可能会在打开其标题窗格之一时导致意外行为。

向手风琴添加几个标题窗格类似于向切换组添加切换按钮:一次只能在手风琴中打开一个标题窗格。例21-4创建了三个标题窗格并将它们添加到手风琴中。

例21-4折叠和三个标题窗格

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.TitledPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
 
public class TitledPaneSample extends Application {
    final String[] imageNames = new String[]{"Apples", "Flowers", "Leaves"};
    final Image[] images = new Image[imageNames.length];
    final ImageView[] pics = new ImageView[imageNames.length];
    final TitledPane[] tps = new TitledPane[imageNames.length];
           
    public static void main(String[] args) {
        launch(args);
    }
 
    @Override public void start(Stage stage) {
        stage.setTitle("TitledPane");
        Scene scene = new Scene(new Group(), 80, 180);
        scene.setFill(Color.GHOSTWHITE);
                               
        final Accordion accordion = new Accordion ();        
        
        for (int i = 0; i < imageNames.length; i++) {           
            images[i] = new 
                Image(getClass().getResourceAsStream(imageNames[i] + ".jpg"));
            pics[i] = new ImageView(images[i]);
            tps[i] = new TitledPane(imageNames[i],pics[i]); 
        }   
        accordion.getPanes().addAll(tps);
        accordion.setExpandedPane(tps[0]);
 
        Group root = (Group)scene.getRoot();
        root.getChildren().add(accordion);
        stage.setScene(scene);
        stage.show();
    }
}

在循环内创建三个标题窗格。每个标题窗格的内容都定义为一个ImageView对象。通过使用getPanesaddAll方法将标题窗格添加到手风琴中。您可以使用该add方法而不是addAll方法添加单个标题窗格。

默认情况下,应用程序启动时会关闭所有标题窗格。例21-4中setExpandedPane方法指定在运行样本时将打开带有苹果图片的标题窗格,如图21-5所示。

图21-5带有三个标题窗格的折叠

处理具有标题窗格的折叠的事件

您可以使用标题窗格和折叠在应用程序中显示不同的数据。例21-5创建了一个独立的标题窗格,其中GridPane包含布局容器和使用折叠组合的三个标题窗格。独立标题窗格包含电子邮件客户端的UI元素。折叠使图像的选择能够出现在Grid标题窗格的Attachment字段中。

例21-5为Accordion实现ChangeListener

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
 
public class TitledPaneSample extends Application {
    final String[] imageNames = new String[]{"Apples", "Flowers", "Leaves"};
    final Image[] images = new Image[imageNames.length];
    final ImageView[] pics = new ImageView[imageNames.length];
    final TitledPane[] tps = new TitledPane[imageNames.length];
    final Label label = new Label("N/A");
       
    public static void main(String[] args) {
        launch(args);
    }
 
    @Override public void start(Stage stage) {
        stage.setTitle("TitledPane");
        Scene scene = new Scene(new Group(), 800, 250);
        scene.setFill(Color.GHOSTWHITE);
        
        // --- GridPane container
        TitledPane gridTitlePane = new TitledPane();
        GridPane grid = new GridPane();
        grid.setVgap(4);
        grid.setPadding(new Insets(5, 5, 5, 5));
        grid.add(new Label("To: "), 0, 0);
        grid.add(new TextField(), 1, 0);
        grid.add(new Label("Cc: "), 0, 1);
        grid.add(new TextField(), 1, 1);
        grid.add(new Label("Subject: "), 0, 2);
        grid.add(new TextField(), 1, 2);        
        grid.add(new Label("Attachment: "), 0, 3);
        grid.add(label,1, 3);
        gridTitlePane.setText("Grid");
        gridTitlePane.setContent(grid);
        
        // --- Accordion
        final Accordion accordion = new Accordion ();                
        for (int i = 0; i < imageNames.length; i++) {
            images[i] = new 
                Image(getClass().getResourceAsStream(imageNames[i] + ".jpg"));
            pics[i] = new ImageView(images[i]);
            tps[i] = new TitledPane(imageNames[i],pics[i]); 
        }   
        accordion.getPanes().addAll(tps);        
        accordion.expandedPaneProperty().addListener(new 
            ChangeListener<TitledPane>() {
                public void changed(ObservableValue<? extends TitledPane> ov,
                    TitledPane old_val, TitledPane new_val) {
                        if (new_val != null) {
                            label.setText(accordion.getExpandedPane().getText() + 
                                ".jpg");
                        }
              }
        });
        
        HBox hbox = new HBox(10);
        hbox.setPadding(new Insets(20, 0, 0, 20));
        hbox.getChildren().setAll(gridTitlePane, accordion);
 
        Group root = (Group)scene.getRoot();
        root.getChildren().add(hbox);
        stage.setScene(scene);
        stage.show();
    }
}

当用户在折叠中打开标题窗格时,expandedPaneProperty折叠会改变。将ChangeListener通知对象此更改,并且折叠中的扩展标题窗格用于构造附件的文件名。此文件名设置为相应Label对象的文本。

图21-6显示了应用程序启动后的外观。附件标签包含“N / A”,因为没有选择标题窗格。

图21-6 TitledPaneSample应用程序的初始视图

如果展开Leaves标题窗格,Attachment标签将包含“Leaves.jpg”,如图21-7所示。

图21-7带叶子标题窗格的TitledPaneSample应用程序扩展

因为TitledPaneAccordion类都是类的扩展,所以Node可以对它们应用视觉效果或转换。您还可以通过应用CSS样式来更改控件的外观。

相关的API文档 

猜你喜欢

转载自blog.csdn.net/moakun/article/details/83050940