在JavaFX 2,使用CSS,是有可能创造有2种颜色背景? 认为如的TableCell
10像素的高度。 我想第一个2像素(垂直)为红色,其余8个像素(垂直)应保持在默认的背景颜色。 是的JavaFX 2中可能使用CSS? 怎么样?
例:
原始背景:
期望的结果:
(上2个像素由红色取代)
感谢有这方面的暗示!
在JavaFX 2,使用CSS,是有可能创造有2种颜色背景? 认为如的TableCell
10像素的高度。 我想第一个2像素(垂直)为红色,其余8个像素(垂直)应保持在默认的背景颜色。 是的JavaFX 2中可能使用CSS? 怎么样?
例:
原始背景:
期望的结果:
(上2个像素由红色取代)
感谢有这方面的暗示!
我用的背景颜色的简单层,以产生红色高亮(类似的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;
}
对于像stackpane标准的区域,你真正需要做的是运用上述CSS(较少-fx-text-fill
),以获得所需的结果。
下面是使用的梯度来定义颜色另一个棘手的方式:
-fx-background-color:
linear-gradient(
from 0px 0px to 0px 2px,
firebrick, firebrick 99%,
gainsboro
);
下面的屏幕截图,该值细胞被突出显示(通过具有highlighted-cell
施加到它们的CSS类)如果具有值false
。
突出单元样式类开关逻辑:
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");
}
...
}
}
当它看起来很不错highlighted-cell
(一种在应用到一个标准的表格单元格样式类的updateItem调用自定义单元格),但确实有一些缺点。 该表色彩方案是非常微妙和复杂。 它具有用于奇/偶数值,亮点亮点为选定的行,亮点,用于为选定盘旋了聚焦的行和细胞等的行,亮点加上它有所有上述的各种组合。 只需直接在高亮细胞类设置背景色是一种暴力的方式来实现你想要的,因为它没有考虑所有这些细微之处考虑在内,只是压倒他们,所以已经使用这个突出的一个细胞风格看起来总是相同的,无论什么临时CSS伪类的状态已被应用到它。
这是很好的,真的,而是一个更好的解决方案将颜色突出显示单元不同,这取决于伪类的状态。 这是相当做虽然一件棘手的事情,你可能会浪费大量的时间与各国和CSS选择器的组合玩耍,试图得到很好的改变亮点。 总之,在这个例子中它似乎并不值得额外的努力对我来说,虽然它可能适合你。
测试程序(这个长度和复杂性的道歉,这对我的风格高亮逻辑集成到现有的方案只是更容易):
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();
}
}
}
你看,如何理解CSSRef:
http://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html
看着
-fx-背景图像:
S [,S] *
一系列图像的URI的由逗号分隔。
看着
-fx-背景重复
重复式[,重复式] *
其中,重复式=重复-X | 重复-Y | [重复| 空间| 轮| 舒展| 不重复] {1,2}
一系列值的由逗号分隔。 该系列中的每个重复式的项目适用于背景图片系列中的相应的图像。
请看:-fx背景位置
BG-位置[,BG-位置] *其中= [[[大小| 左| 中心| 右] [SIZE | 顶部| 中心| 底部] ] | [中心| [左| 合适的尺码? ] || [中心| [顶| 底部]大小? ]]
一系列值的由逗号分隔。 系列中的每个BG-位置项适用于在背景图像系列中的相应的图像。
所以,你可以看到:你应该描述2个图像,(2×2像素,每个像素 - 一红一 - 灰色)两个BG位置,和两个重复的样式为他们每个人的相应。
怎么样?
例如:
{
-fx-backdround-image : "path_to_red", "path_to_grey";
-fx-background-repeat : repeat-x, stretch;
-fx-background-position : 0px 0px, 0px 2px;
}
我不给的代码的workness一个garantee,但这个想法似乎是正确的。
也许可能仅颜色,而不是使用插图时的图像。 从原来的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个字符...]