Sfondo con 2 colors in JavaFX?

In JavaFX 2, usando i CSS, è ansible creare uno sfondo con 2 colors? Pensa ad esempio a una TableCell con un’altezza di 10 px. Voglio che il primo 2 px (verticalmente) sia rosso, il restante 8 px (verticalmente) deve rimanere al colore di sfondo predefinito. È ansible usare i CSS in JavaFX 2? Come?

Esempio:

Sfondo originale:

inserisci la descrizione dell'immagine qui

Risultato desiderato:

inserisci la descrizione dell'immagine qui (i 2 pixel superiori sono stati sostituiti dal rosso)

Grazie per qualsiasi suggerimento su questo!

Ho usato un semplice strato di colors di sfondo per produrre un’evidenziazione rossa (simile alla soluzione suggerita da Stefan).

 /** * file: table.css * Place in same directory as TableViewPropertyEditorWithCSS.java. * Have your build system copy this file to your build output directory. **/ .highlighted-cell { -fx-text-fill: -fx-text-inner-color; -fx-background-color: firebrick, gainsboro; -fx-background-insets: 0, 2 0 0 0; } 

Per una regione standard come uno stack, tutto ciò che devi veramente fare è applicare il css sopra (meno il -fx-text-fill ) per ottenere il risultato desiderato.


Ecco un altro modo complicato per definire il colore usando un gradiente:

 -fx-background-color: linear-gradient( from 0px 0px to 0px 2px, firebrick, firebrick 99%, gainsboro ); 

Nello screenshot sottostante, le celle del valore sono evidenziate (avendo la class css della highlighted-cell applicata) se hanno il valore false .

highlightedcells

Evidenzia la logica di commutazione della class di stile della cella:

 public void updateItem(Object item, boolean empty) { super.updateItem(item, empty); if (empty) { .... getStyleClass().remove("highlighted-cell"); } else { if (getItem() instanceof Boolean && (Boolean.FALSE.equals((Boolean) getItem()))) { getStyleClass().add("highlighted-cell"); } else { getStyleClass().remove("highlighted-cell"); } ... } } 

Sembra buono quando la class di stile highlighted-cell applicata a una cella di tabella standard (durante una chiamata updateItem per una cella personalizzata) ma presenta un paio di inconvenienti. Lo schema di colorazione della tavola è molto sottile e complesso. Ha punti salienti per i valori pari / dispari, punti salienti per le file selezionate, punti salienti per le righe selezionate, punti salienti per righe e celle focalizzate, ecc. Inoltre ha varie combinazioni di tutto quanto sopra. Basta impostare il colore di sfondo direttamente nella class delle celle di evidenziazione è una sorta di metodo di forza bruta per ottenere ciò che vuoi perché non prende tutte queste sottigliezze in considerazione e semplicemente le sostituisce, quindi una cella che è stata evidenziata usando questo lo stile sembra sempre lo stesso, indipendentemente da quale stato temporaneo di css psuedo-class sia stato applicato ad esso.

Va bene davvero, ma una soluzione migliore colorerebbe la cella evidenziata in modo diverso a seconda degli stati di class psuedo. Questa è una cosa abbastanza complicata da fare e potresti sprecare un sacco di tempo a giocare con vari stati e combinazioni di selettori di CSS per cercare di ottenere il bel cambiamento. In tutto, per questo esempio non mi è valso la pena di fare uno sforzo in più per me, anche se potrebbe essere per voi.


Programma di test (scuse per la lunghezza e la complessità di questo, per me è stato più semplice integrare la logica di evidenziazione dello stile in un programma esistente):

 import java.lang.reflect.*; import java.util.logging.*; import javafx.application.Application; import javafx.beans.property.*; import javafx.beans.value.*; import javafx.collections.*; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.TableColumn.CellEditEvent; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.*; import javafx.stage.Stage; import javafx.util.Callback; // click in the value column (a couple of times) to edit the value in the column. // property editors are defined only for String and Boolean properties. // change focus to something else to commit the edit. public class TableViewPropertyEditorWithCSS extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { final Person aPerson = new Person("Fred", false, false, "Much Ado About Nothing"); final Label currentObjectValue = new Label(aPerson.toString()); TableView table = new TableView(); table.setEditable(true); table.setItems(createNamedProperties(aPerson)); TableColumn nameCol = new TableColumn("Name"); nameCol.setCellValueFactory(new PropertyValueFactory("name")); TableColumn valueCol = new TableColumn("Value"); valueCol.setCellValueFactory(new PropertyValueFactory("value")); valueCol.setCellFactory(new Callback, TableCell>() { @Override public TableCell call(TableColumn param) { return new EditingCell(); } }); valueCol.setOnEditCommit( new EventHandler>() { @Override public void handle(CellEditEvent t) { int row = t.getTablePosition().getRow(); NamedProperty property = (NamedProperty) t.getTableView().getItems().get(row); property.setValue(t.getNewValue()); currentObjectValue.setText(aPerson.toString()); } }); table.getColumns().setAll(nameCol, valueCol); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); VBox layout = new VBox(10); layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;"); layout.getChildren().setAll( currentObjectValue, table); VBox.setVgrow(table, Priority.ALWAYS); Scene scene = new Scene(layout, 650, 600); scene.getStylesheets().add(getClass().getResource("table.css").toExternalForm()); stage.setScene(scene); stage.show(); } private ObservableList createNamedProperties(Object object) { ObservableList properties = FXCollections.observableArrayList(); for (Method method : object.getClass().getMethods()) { String name = method.getName(); Class type = method.getReturnType(); if (type.getName().endsWith("Property")) { try { properties.add(new NamedProperty(name, (Property) method.invoke(object))); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { Logger.getLogger(TableViewPropertyEditorWithCSS.class.getName()).log(Level.SEVERE, null, ex); } } } return properties; } public class NamedProperty { public NamedProperty(String name, Property value) { nameProperty.set(name); valueProperty = value; } private StringProperty nameProperty = new SimpleStringProperty(); public StringProperty nameProperty() { return nameProperty; } public StringProperty getName() { return nameProperty; } public void setName(String name) { nameProperty.set(name); } private Property valueProperty; public Property valueProperty() { return valueProperty; } public Object getValue() { return valueProperty.getValue(); } public void setValue(Object value) { valueProperty.setValue(value); } } public class Person { private final SimpleStringProperty firstName; private final SimpleBooleanProperty married; private final SimpleBooleanProperty hasChildren; private final SimpleStringProperty favoriteMovie; private Person(String firstName, Boolean isMarried, Boolean hasChildren, String favoriteMovie) { this.firstName = new SimpleStringProperty(firstName); this.married = new SimpleBooleanProperty(isMarried); this.hasChildren = new SimpleBooleanProperty(hasChildren); this.favoriteMovie = new SimpleStringProperty(favoriteMovie); } public SimpleStringProperty firstNameProperty() { return firstName; } public SimpleBooleanProperty marriedProperty() { return married; } public SimpleBooleanProperty hasChildrenProperty() { return hasChildren; } public SimpleStringProperty favoriteMovieProperty() { return favoriteMovie; } public String getFirstName() { return firstName.get(); } public void setFirstName(String fName) { firstName.set(fName); } public Boolean getMarried() { return married.get(); } public void setMarried(Boolean isMarried) { married.set(isMarried); } public Boolean getHasChildren() { return hasChildren.get(); } public void setHasChildren(Boolean hasChildren) { this.hasChildren.set(hasChildren); } public String getFavoriteMovie() { return favoriteMovie.get(); } public void setFavoriteMovie(String movie) { favoriteMovie.set(movie); } @Override public String toString() { return firstName.getValue() + ", isMarried? " + married.getValue() + ", hasChildren? " + hasChildren.getValue() + ", favoriteMovie: " + favoriteMovie.get(); } } class EditingCell extends TableCell { private TextField textField; private CheckBox checkBox; public EditingCell() { } @Override public void startEdit() { if (!isEmpty()) { super.startEdit(); if (getItem() instanceof Boolean) { createCheckBox(); setText(null); setGraphic(checkBox); } else { createTextField(); setText(null); setGraphic(textField); textField.selectAll(); } } } @Override public void cancelEdit() { super.cancelEdit(); if (getItem() instanceof Boolean) { setText(getItem().toString()); } else { setText((String) getItem()); } setGraphic(null); } @Override public void updateItem(Object item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); getStyleClass().remove("highlighted-cell"); } else { if (getItem() instanceof Boolean && (Boolean.FALSE.equals((Boolean) getItem()))) { getStyleClass().add("highlighted-cell"); } else { getStyleClass().remove("highlighted-cell"); } if (isEditing()) { if (getItem() instanceof Boolean) { if (checkBox != null) { checkBox.setSelected(getBoolean()); } setText(null); setGraphic(checkBox); } else { if (textField != null) { textField.setText(getString()); } setText(null); setGraphic(textField); } } else { setText(getString()); setGraphic(null); } } } private void createTextField() { textField = new TextField(getString()); textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); textField.focusedProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { if (!newValue) { commitEdit(textField.getText()); } } }); } private void createCheckBox() { checkBox = new CheckBox(); checkBox.setSelected(getBoolean()); checkBox.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); checkBox.focusedProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { if (!newValue) { commitEdit(checkBox.isSelected()); } } }); } private String getString() { return getItem() == null ? "" : getItem().toString(); } private Boolean getBoolean() { return getItem() == null ? false : (Boolean) getItem(); } } } 

Guarda come interpretare il CSSRef:

http://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html

Guarda a

-fx-background-image:

uri [, uri] *

Una serie di URI immagine separati da virgole.

Guarda a

-fx-background-repeat

repeat-style [, repeat-style] *

dove repeat-style = repeat-x | repeat-y | [ripeti | spazio | rotondo | allungare | no-repeat] {1,2}

Una serie di valori separati da virgole. Ogni elemento di stile ripetuto della serie si applica all’immagine corrispondente nella serie di immagini di sfondo.

Guarda: -fx-background-position

bg-position [, bg-position] * where = [[[size | sinistra | centro | destra] [dimensione | in alto | centro | parte inferiore ]? ] | [[center | [sinistra | misura giusta? ] || [centro | [in alto | dimensione inferiore? ]]

Una serie di valori separati da virgole. Ogni articolo di posizione bg della serie si applica all’immagine corrispondente nella serie di immagini di sfondo.

Quindi, cosa puoi vedere: dovresti descrivere 2 immagini, (2×2 pixel ciascuna – una rossa e una – grigia). Due posizioni bg e due stili di ripetizione per ognuna di esse corrispondenti.

Come?

esempio :

 { -fx-backdround-image : "path_to_red", "path_to_grey"; -fx-background-repeat : repeat-x, stretch; -fx-background-position : 0px 0px, 0px 2px; } 

Non conferisco una garanzia sulla funzionalità del codice, ma l’idea sembra corretta.

Forse ansible con solo colors invece di immagini quando si usano gli inserti. Esempio da CSS JavaFX originale:

 .table-row-cell:odd { -fx-background-color: -fx-table-cell-border-color, derive(-fx-control-inner-background,-5%); -fx-background-insets: 0, 0 0 1 0; } 

[6 caratteri …]