Showing posts with label CSS. Show all posts
Showing posts with label CSS. Show all posts

Sunday, June 8, 2014

JavaFX TableView with image background in header

I got to wondering how to set the background of a table to an image of some sort. It is pretty straight-forward with CSS. The only trick, really, is setting the background-color of the filler and column-header so the image can be seen. I used a semi-transparent white so the label text is easier to see.

.table-view > .column-header-background {
    -fx-background-image: url("https://duke.kenai.com/models/Duke3DprogressionSmall.jpg");
    -fx-background-size: stretch;
    -my-wash: rgba(255,255,255,.75);
}

.table-view > .column-header-background > .filler {
    -fx-background-color: -my-wash;
}

.table-view > .column-header-background > .nested-column-header > .column-header.table-column {
    -fx-background-color: -my-wash;

}

Sample code to try it on.

    static class Person {
        final StringProperty lastName  = new SimpleStringProperty();
        final StringProperty firstName  = new SimpleStringProperty();
        Person(String lastName, String firstName) {
            this.lastName.set(lastName);
            this.firstName.set(firstName);
        }
        StringProperty lastNameProperty() { return lastName; }
        StringProperty firstNameProperty() { return firstName; }
    }

    @Override
    public void start(Stage stage) throws Exception {

        TableColumn lastName = new TableColumn<>("Last");
        lastName.setCellValueFactory((value) -> value.getValue().lastNameProperty());

        TableColumn firstName = new TableColumn<>("First");
        firstName.setCellValueFactory((value) -> value.getValue().firstNameProperty());

        TableView tableView = new TableView();
        tableView.getColumns().setAll(lastName, firstName);
        tableView.getItems().setAll(
                new Person("Cratchit", "Bob"),
                new Person("Scrooge", "Ebenezer")
        );

        Group root = new Group(tableView);

        Scene scene = new Scene(root, 300, 500);
        scene.getStylesheets().add("/fxtest/test.css");
        stage.setScene(scene);
        stage.show();

    }

Saturday, June 7, 2014

JavaFX CSS selectors for TableView

I had time to kill while on a flight from Boston to Houston and came up with a list of CSS selectors for simple, JavaFX TableView. The comment in each CSS rule states the public API of the selected node.

.table-view > .column-header-background {
    /* StackPane */
}

.table-view > .column-header-background > .filler {
    /* Region - area of header not taken by column headers */
}

.table-view > .column-header-background > .column-drag-header {
    /* StackPane */
}

.table-view > .column-header-background > .column-drag-header > .label {
    /* Label */
}

.table-view > .column-header-background > .column-drag-header > .label > .text {
    /* Text */
}

.table-view > .column-header-background > .nested-column-header {
    /* Region */
}

.table-view > .column-header-background > .nested-column-header > .column-header.table-column {
    /* Region */
}

.table-view > .column-header-background > .nested-column-header > .column-header.table-column > .label {
    /* Label */
}

.table-view > .column-header-background > .nested-column-header > .column-header.table-column > .label > .text {
    /* Text */
}

.table-view > .column-header-background > .nested-column-header > .column-header.table-column > Grid {
    /* Grid */
}

.table-view > .column-header-background > .nested-column-header > .column-header.table-column > Grid > .arrow {
    /* Region */
}

.table-view > .column-header-background > .nested-column-header > Rectangle {
    /* Rectangle - separates column headers. Resize icon on :hover */
}

.table-view > .column-header-background > .show-hide-columns-button {
    /* StackPane */
}

.table-view > .column-header-background > .show-hide-columns-button > .show-hide-column-image {
    /* StackPane */
}

.table-view > .column-overlay {
    /* Region - highlights column being dragged */
}

.table-view > .column-resize-line {
    /* Region - displays where the dragged column will drop  */
}

.table-view > .virtual-flow {
    /* Region */
}

.table-view > .virtual-flow > .clipped-container {
    /* Region */
}

.table-view > .virtual-flow > .clipped-container > .sheet {
    /* Group */
}

.table-view > .virtual-flow > .clipped-container > .sheet > .cell.indexed-cell.table-row-cell {
    /* TableRow */
}
.table-view > .virtual-flow > .clipped-container > .sheet > .cell.indexed-cell.table-row-cell > .cell.indexed-cell.table-cell.table-column {
    /* TableCell */
}

.table-view > .virtual-flow > .clipped-container > .sheet > .cell.indexed-cell.table-row-cell > .cell.indexed-cell.table-cell.table-column > .text {
    /* Text */
}

.table-view > .virtual-flow > .scroll-bar {
    /* ScrollBar - has :vertical and :horizontal (default) pseudo-class state */
}

.table-view > .virtual-flow > .scroll-bar > .track-background {
    /* StackPane */
}

.table-view > .virtual-flow > .scroll-bar > .track {
    /* StackPane */
}

.table-view > .virtual-flow > .scroll-bar > .thumb {
    /* StackPane */
}

.table-view > .virtual-flow > .scroll-bar > .decrement-button {
    /* Region */
}

.table-view > .virtual-flow > .scroll-bar > .decrement-arrow {
    /* Region */
}

.table-view > .virtual-flow > .scroll-bar > .increment-button {
    /* Region */
}

.table-view > .virtual-flow > .scroll-bar > .increment-arrow {
    /* Region */
}

Wednesday, May 28, 2014

Styling Cells in JavaFX

When working with Cells, in a ListView or TableView for example, it is best to use CSS to style the look of the cell. While it is possible to set the value of a property directly, the way cells are reused means that you have to be careful to undo or redo the value when the cell is reused.

Here is an example of a ListView that sets the text fill to red for prime numbers. Notice the use of the pseudo-class state. Adding and removing a style-class is also an option. But a psuedo-class state change has much less overhead.


package fxtest;

import javafx.application.Application;
import javafx.css.PseudoClass;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

import java.util.Arrays;
import java.util.function.IntFunction;
import java.util.stream.IntStream;

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }
 
    final static int MAX_N = 100;
    final static boolean isPrime[] = new boolean[MAX_N];

    static {
        Arrays.fill(isPrime, true);
        for (int i = 2; i*i < MAX_N; i++) {
            if (isPrime[i]) {
                for (int j = i*i; j < MAX_N; j += i) {
                    isPrime[j] = false;
                }
            }
        }
    }

    final static PseudoClass prime = PseudoClass.getPseudoClass("prime");

    final Integer[] items = IntStream.range(0, MAX_N).boxed().toArray(n -> { return new Integer[n]; });

    @Override
    public void start(final Stage stage) {

        ListView<Integer> listView = new ListView<>();
        listView.getItems().addAll(items);

        listView.setCellFactory(lv -> {
            return new ListCell<Integer>() {

                @Override
                public void updateItem(Integer item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty || item == null) {
                        setText(null);
                        pseudoClassStateChanged(prime, false);
                    } else {
                        setText(item.toString());
                        int n = item.intValue();
                        boolean bool = ((1 < n) && (n < isPrime.length) && isPrime[n]);
                        pseudoClassStateChanged(prime, bool);
                    }
                }
            };
        });

        Scene scene = new Scene(new Group(listView));
        scene.getStylesheets().add("/fxtest/test.css");
        stage.setWidth(400);
        stage.setHeight(400);
        stage.setScene(scene);
        stage.show();

    }

}

The file fxtest/test.css:

.list-cell:prime {
    -fx-text-fill: red;
}