2013-04-24 17 views
8

W JavaFX 2, używając CSS, czy można utworzyć tło z 2 kolorami? Pomyśl o np. a TableCell o wysokości 10 pikseli. Chcę, aby pierwsze 2 piksele (pionowo) miały kolor czerwony, pozostałe 8 pikseli (w pionie) pozostaną na domyślnym kolorze tła. Czy to możliwe przy użyciu CSS w JavaFX 2? W jaki sposób?Tło z 2 kolorami w JavaFX?

przykład:

oryginalny tła:

enter image description here

Pożądany wynik:

enter image description here (górne 2 pikseli zostały zastąpione przez czerwony)

dzięki za wskazówkę na to!

Odpowiedz

0

Spójrz, jak zrozumieć CSSRef:

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

spojrzeć na

-fx-background-image:

[uri, uri] *

Seria identyfikatorów URI obrazków oddzielonych przecinkami.

Spójrz na

-fx-background-repeat

powtórz stylu [powtórzyć stylu] *

gdzie repeat-style = repeat-x | repeat-y | [powtórz | przestrzeń kosmiczna okrągły | rozciągnąć | no-repeat] {1,2}

Seria wartości oddzielonych przecinkami. Każdy element w stylu powtarzania w serii odnosi się do odpowiedniego obrazu w serii obrazów tła.

Spójrz: -fx-background-position

BG-pozycyjnego [BG-position] * gdzie = [ [[size | lewo | centrum | prawo] [rozmiar | top | centrum | Dolny ]? ] | [[centrum | [left | dobry rozmiar? ] || [centrum | [góra | Dolny rozmiar? ] ]

Seria wartości oddzielonych przecinkami. Każdy element pozycji w pozycji bg w serii dotyczy odpowiedniego obrazu w serii obrazów tła.

Co możesz zobaczyć: powinieneś opisać dwa obrazy (2x2 piksele każdy - jeden czerwony i jeden szary) Dwie pozycje bg i dwa powtórzenia dla każdego z nich odpowiadające.

Jak?

przykład:

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

nie dać Gwarantujemy na workness kodu, ale idea wydaje się prawidłowe.

Może być możliwe tylko z kolorami, a nie z obrazkami w przypadku wstawek. Przykład z oryginalnym JavaFX CSS:

.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 znaków ...]

+0

ah, nie byłem świadomy, że można bezpośrednio podać wiele obrazów, ale nawet zdjęcia nie są potrzebne, jeśli się nie mylę :-) Dzięki za wskazówki! Nie przetestowałem go jeszcze, ponieważ jest to trochę więcej fiddlingu (komórka z tabelą-tertą faktycznie nie ma granicy, ale robi sztuczki z tłem symulującym granice - sprawia, że ​​rzeczy są nieco bardziej złożone), ale przypuszczam, że to działa. Aktualizacja nastąpi. –

+0

Jeśli uważasz, że zamiast obrazów można użyć koloru tła, ale wydaje się, jesteś w błędzie, ponieważ kolor nie ma rozmiaru, to tylko kolor, ale obraz ma rozmiar, więc można go powtórzyć, itp ...W przeciwnym razie będziesz musiał określić rozmiar kolorowego smth .. –

+0

Alexander, to może nadal jest możliwe za pomocą wstawek, zobacz swój post/odpowiedź (ja to edytowałem). Co o tym myślisz? –

12

użyłem prostego warstwy kolorów tła produkować czerwone podświetlenie (podobny do proponowanego rozwiązania Stefana).

/** 
* 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; 
} 

Dla standardowego regionu jak stackpane, wszystko co naprawdę trzeba zrobić, to zastosować powyższą CSS (mniej -fx-text-fill), aby uzyskać pożądany efekt.


Oto kolejny trudne sposób określić kolor stosując gradient:

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

w poniższej ekranu komórki wartości są podkreślone (poprzez klasy highlighted-cell CSS do nich stosowane) jeśli ma wartość false.

highlightedcells

Highlight przełącznik klasy styl komórek logika:

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"); 
    } 
    ... 
    } 
} 

To wygląda dobrze, gdy klasa highlighted-cell styl zastosowany do standardowej komórki tabeli (podczas updateItem zaproszenia do komórki niestandardowego) ale ma kilka wad. Schemat kolorowania stołu jest bardzo subtelny i złożony. Ma podświetlenia dla wartości nieparzystych/parzystych, podświetlenia dla wybranych rzędów, podświetlenia dla wybranych ukrytych rzędów, podświetlenia dla skupionych rzędów i komórek, itd. Dodatkowo ma różne kombinacje powyższych. Samo ustawienie koloru tła bezpośrednio w klasie highlight-cell jest rodzajem brutalnego sposobu na osiągnięcie tego, co chcesz, ponieważ nie bierze pod uwagę wszystkich innych subtelności i po prostu je zastępuje, czyli komórkę, która została podświetlona za pomocą tego styl zawsze wygląda tak samo, bez względu na to, jaki tymczasowy stan css psuedo został w nim zastosowany.

W porządku, ale ładniejsze rozwiązanie może podbarwić zaznaczoną komórkę inaczej, w zależności od stanów klasy psuedo. To dość trudna rzecz do zrobienia i możesz stracić dużo czasu, bawiąc się różnymi stanami i kombinacjami selsynów, aby spróbować uzyskać ładną, zmieniającą się atrakcję. Podsumowując, dla tego przykładu nie wydawało mi się to warte tego dodatkowego wysiłku, choć może dla ciebie.


Program testowy (przepraszam za długość i złożoność tego, to było po prostu łatwiej mi się zintegrować styl podkreślający logiki do istniejącego programu):

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<NamedProperty> table = new TableView(); 
    table.setEditable(true); 
    table.setItems(createNamedProperties(aPerson)); 
    TableColumn<NamedProperty, String> nameCol = new TableColumn("Name"); 
    nameCol.setCellValueFactory(new PropertyValueFactory<NamedProperty, String>("name")); 
    TableColumn<NamedProperty, Object> valueCol = new TableColumn("Value"); 
    valueCol.setCellValueFactory(new PropertyValueFactory<NamedProperty, Object>("value")); 
    valueCol.setCellFactory(new Callback<TableColumn<NamedProperty, Object>, TableCell<NamedProperty, Object>>() { 
     @Override 
     public TableCell<NamedProperty, Object> call(TableColumn<NamedProperty, Object> param) { 
     return new EditingCell(); 
     } 
    }); 
    valueCol.setOnEditCommit(
      new EventHandler<CellEditEvent<NamedProperty, Object>>() { 
     @Override 
     public void handle(CellEditEvent<NamedProperty, Object> 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<NamedProperty> createNamedProperties(Object object) { 
    ObservableList<NamedProperty> 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<NamedProperty, Object> { 

    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<Boolean>() { 
     @Override 
     public void changed(ObservableValue<? extends Boolean> 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<Boolean>() { 
     @Override 
     public void changed(ObservableValue<? extends Boolean> 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(); 
    } 
    } 
} 
+1

Wow, dzięki za tak dużo pracy, że zainwestowałeś tutaj! –

+0

Bardzo ładne. Dziękuję Ci. – jkaufmann