26 Customization of UI Controls javafx

来源:互联网 发布:stm32 isp下载软件 编辑:程序博客网 时间:2024/05/03 01:01

This chapter describes the aspects of UI control customization and summarizes some tips and tricks provided by Oracle to help you modify the appearance and behavior of UI controls.

You can learn how to customize the controls from the sample applications in the UIControlSamples project by applying Cascading Style Sheets (CSS), redefining the default behavior, and using cell factories. For more specific cases, when the task of your application requires unique features that cannot be implemented with the classes of thejavafx.scene.control package, extend the Control class to invent your own control.

Applying CSS

You can change the look of UI controls by redefining the style definitions of the JavaFX caspian style sheets. Skinning JavaFX Applications with CSS explains the general concepts and approaches to modifying the styles and enabling them in a JavaFX application.

Consider some of the specific tasks that are frequently requested by developers at the JavaFX forum.

Although the Tooltip class does not have any properties or methods to change the default color of the tooltip, you can modify the -fx-background-color property of the .tooltip CSS class as shown in Example 26-1.

Example 26-1 Changing the Background Color of a Tooltip

.tooltip {        -fx-background-color: linear-gradient(#e2ecfe, #99bcfd);}.page-corner {    -fx-background-color: linear-gradient(from 0% 0% to 50% 50%,#3278fa,#99bcfd);}

The .page-corner CSS class defines the color of the right-bottom corner of the tooltip. When you add the code in Example 26-1 to the style sheets of the TooltipSample and apply the style sheets to the scene, the tooltip changes its color to blue. See Figure 26-1 to evaluate the effect.

Figure 26-1 Tooltip with the Blue Background Color

Description of Figure 26-1 follows
Description of "Figure 26-1 Tooltip with the Blue Background Color"

Note that when you modify the default style of a tooltip, the new look is applied to all the tooltips in your application.

Another popular design task is changing the default marks for the controls. For example, the default style of the CheckBox class defines the traditional check mark for the selected state. You can redefine the shape of the mark as well as its color as shown in Example 26-2.

Example 26-2 Alternative Mark for a Checkbox

.check-box .mark {    -fx-shape:"M2,0L5,4L8,0L10,0L10,2L6,5L10,8L10,10L8,10L5,6L2,10L0,10L0,8L4,5L0,2L0,0Z";}.check-box:selected .mark {    -fx-background-color: #0181e2;}

The -fx-shape property sets the new SVG path for the mark, and the -fx-background-color property defines its color. When the modified style sheets are enabled in the CheckBoxSample application, the selected checkboxes contain X marks instead of check marks, as shown inFigure 26-2.

Figure 26-2 ComboBoxSample with the Modified Checkbox Style

Description of Figure 26-2 follows
Description of "Figure 26-2 ComboBoxSample with the Modified Checkbox Style"

Many developers asked how to overcome the limitation in visual style of the TableView andListView controls. By default, all rows in these controls are shown, whether they are empty or not. With the proper CSS settings, you can set a specific color for all empty rows. Example 26-3 implements this task for a TableView control.

Example 26-3 Setting Color for Empty Rows in a Table View

.table-row-cell:empty {    -fx-background-color: lightyellow;} .table-row-cell:empty .table-cell {    -fx-border-width: 0px;}

The first CSS style determines that all empty rows, regardless of whether they are even or odd, should have light yellow backgrounds. When the table-row-cell is empty, the second CSS statement removes the vertical border that is painted on the right-hand side of all table cells.

When the CSS styles from Example 26-3 are enabled in the TableViewSample application, the Address Book table looks as shown Figure 26-3.

Figure 26-3 TableViewSample with Color Added to the Empty Rows

Description of Figure 26-3 follows
Description of "Figure 26-3 TableViewSample with Color Added to the Empty Rows"

You can even set the null value for the background color of the empty cells. The style sheets will use the default background color of the table view in this case. See Figure 26-4 to evaluate the effect.

Figure 26-4 TableViewSample with Null Background Color Added to the Empty Rows

Description of Figure 26-4 follows
Description of "Figure 26-4 TableViewSample with Null Background Color Added to the Empty Rows"

You can set more CSS properties for UI Controls to alter their shapes, color schemes, and the applied effects. See the JavaFX CSS Reference Guide for more information about available CSS properties and classes.

Altering Default Behavior

Many developers requested a specific API to restrict input in the text field, for example, to allow only number values. Example 26-4 provides a simple application with a numeric text field.

Example 26-4 Prohibiting Letters in the Text Field

import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.geometry.Insets;import javafx.scene.Group;import javafx.scene.Scene;import javafx.scene.control.*;import javafx.scene.layout.GridPane;import javafx.scene.layout.HBox;import javafx.stage.Stage;public class CustomTextFieldSample extends Application {        final static Label label = new Label();     @Override    public void start(Stage stage) {        Group root = new Group();        Scene scene = new Scene(root, 300, 150);        stage.setScene(scene);        stage.setTitle("Text Field Sample");         GridPane grid = new GridPane();        grid.setPadding(new Insets(10, 10, 10, 10));        grid.setVgap(5);        grid.setHgap(5);         scene.setRoot(grid);        final Label dollar = new Label("$");        GridPane.setConstraints(dollar, 0, 0);        grid.getChildren().add(dollar);                final TextField sum = new TextField() {            @Override            public void replaceText(int start, int end, String text) {                if (!text.matches("[a-z, A-Z]")) {                    super.replaceText(start, end, text);                                     }                label.setText("Enter a numeric value");            }             @Override            public void replaceSelection(String text) {                if (!text.matches("[a-z, A-Z]")) {                    super.replaceSelection(text);                }            }        };         sum.setPromptText("Enter the total");        sum.setPrefColumnCount(10);        GridPane.setConstraints(sum, 1, 0);        grid.getChildren().add(sum);                Button submit = new Button("Submit");        GridPane.setConstraints(submit, 2, 0);        grid.getChildren().add(submit);                submit.setOnAction(new EventHandler<ActionEvent>() {            @Override            public void handle(ActionEvent e) {                label.setText(null);            }        });                GridPane.setConstraints(label, 0, 1);        GridPane.setColumnSpan(label, 3);        grid.getChildren().add(label);                scene.setRoot(grid);        stage.show();    }     public static void main(String[] args) {        launch(args);    }}

To redefine the default implementation of the TextField class, you must override thereplaceText and replaceSelection methods inherited from the TextInputControl class.

When the user tries to enter any letter in the Sum text field, no symbols appear, and the warning message is shown. Figure 26-5 illustrates this situation.

Figure 26-5 Attempt to Enter Letter Symbols

Description of Figure 26-5 follows
Description of "Figure 26-5 Attempt to Enter Letter Symbols"

However, when the user attempts to enter the numeric values, they appear in the field as shown in Figure 26-6.

Figure 26-6 Entering Numeric Values

Description of Figure 26-6 follows
Description of "Figure 26-6 Entering Numeric Values"

Implementing Cell Factories

Appearance and even behavior of four UI controls can be entirely customized by using the mechanism of cell factories. You can apply cell factories to TableViewListViewTreeView, andComboBox. A cell factory is used to generate cell instances, which are used to represent any single item of these controls.

The Cell class extends the Labeled class, which provides all the required properties and methods to implement the most typical use case — showing and editing text. However, when the task of your application requires showing graphical objects in the lists or tables, you can use the graphic property and place any Node in the cell (see the Cell class API specification for more information about custom cells).

For instance, the code fragments in Example 26-5 create a cell factory for the list view and redefine the content of the cells within the updateItem method, so that the list shows rectangles of different colors.

Example 26-5 Implementing Cell Factories for the ListView Control

list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {    Override public ListCell<String> call(ListView<String> list) {        return new ColorRectCell();    }});...static class ColorRectCell extends ListCell<String> {    @Override     public void updateItem(String item, boolean empty) {        super.updateItem(item, empty);        Rectangle rect = new Rectangle(100, 20);        if (item != null) {            rect.setFill(Color.web(item));            setGraphic(rect);        } else {            setGraphic(null);        }    }}

Figure 26-7 shows how this customized list looks in the ListViewSample of the UIControlSamples project.

Figure 26-7 List View with Color Rectangles

Description of Figure 26-7 follows
Description of "Figure 26-7 List View with Color Rectangles"

This tutorial uses the cell factory mechanism extensively to customize UI controls. Table 26-1summarizes the coding templates that you can use to implement cell factories on your applications.

Table 26-1 Cell Factory Coding Patterns

ControlCoding Pattern

ListView,ComboBox

list.setCellFactory(new Callback<ListView<String>,ListCell<String>>() {                @Override             public ListCell<String> call(ListView<String> list) {               //cell implementation                        }});

TableView

column.setCellFactory(new Callback<TableColumn,    TableCell>() {        public TableCell call(TableColumn p) {                    //cell implementation                                }        });

TreeView

tree.setCellFactory(new Callback<TreeView<String>,     TreeCell<String>>(){            @Override            public TreeCell<String> call(TreeView<String> p) {                //cell implementation            }});

You can customize these controls by using the cell factory mechanism or use the prefabricated cell editor implementations that provide specific data models underlying the visualization. Table 26-2 lists the corresponding classes available in the JavafX API.

Table 26-2 Cell Editor Classes for the List View, Tree View, and Table View Controls

ControlCell Editor Classes

List view

  • CheckBoxListCell

  • ChoiceBoxListCell

  • ComboBoxListCell

  • TextFieldListCell

Tree view

  • CheckBoxTreeCell

  • ChoiceBoxTreeCell

  • ComboBoxTreeCell

  • TextFieldTreeCell

Table view

  • CheckBoxTableCell

  • ChoiceBoxTableCell

  • ComboBoxTableCell

  • ProgressBarTableCell

  • TextFieldTableCell


Each cell editor class draws a specific node inside the cell. For example, the CheckBoxListCellclass draws a CheckBox node inside the list cell.

To evaluate more cell factory and cell editor use cases, see the Table View, Tree View, andCombo Box chapters.

Related Documentation and Resources 

  • Skin Applications with CSS

  • JavaFX CSS Reference Guide

  • JavaFX News, Demos, and Insight

    智源软件转载