JavaFX 2.2.21 Java 7.21
I am trying to display a red border and image on a text cell when there is an error.
I took the address book sample (example 12-11 http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#CJAGAAEE)
and modified it.
In the sample below, the 'last name' field has been changed to salary and must display an error (red border and image) if anything other than an integer is entered.
When there is an error, fail.png displays. After the error is corrected, I need to have it erased.
Using fx-background-image: none; somehow doesn't work.
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.Callback;
public class TableViewSample extends Application {
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Gates", "46", "Gates@example.com"),
new Person("Ellison", "25", "Ellison@example.com"),
new Person("McNealy", "1", "McNealy@example.com"),
new Person("Jobs", "0", "Jobs@example.com"),
new Person("Me", "0", "me@example.com"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(cellFactory);
firstNameCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setFirstName(t.getNewValue());
}
});
TableColumn salaryCol = new TableColumn("Salary");
salaryCol.setMinWidth(100);
salaryCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("salary"));
salaryCol.setCellFactory(cellFactory);
salaryCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setSalary(t.getNewValue());
}
});
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email"));
emailCol.setCellFactory(cellFactory);
emailCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setEmail(t.getNewValue());
}
});
table.setItems(data);
table.getColumns().addAll(firstNameCol, salaryCol, emailCol);
final TextField addFirstName = new TextField();
addFirstName.setPromptText("First Name");
addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
final TextField addSalary = new TextField();
addSalary.setMaxWidth(salaryCol.getPrefWidth());
addSalary.setPromptText("Last Name");
final TextField addEmail = new TextField();
addEmail.setMaxWidth(emailCol.getPrefWidth());
addEmail.setPromptText("Email");
final Button addButton = new Button("Add");
addButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
data.add(new Person(
addFirstName.getText(),
addSalary.getText(),
addEmail.getText()));
addFirstName.clear();
addSalary.clear();
addEmail.clear();
}
});
hb.getChildren().addAll(addFirstName, addSalary, addEmail, addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
scene.getStylesheets().add(getClass().getResource("errorTextField.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty salary;
private final SimpleStringProperty email;
private Person(String fName, String pay, String email) {
this.firstName = new SimpleStringProperty(fName);
this.salary = new SimpleStringProperty(pay);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getSalary() {
return salary.get();
}
public void setSalary(String fName) {
salary.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
class EditingCell extends TableCell<Person, String> {
final String errorCSSClass = "error";
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private boolean validate(String text) {
try {
Integer.parseInt(text);
} catch (NumberFormatException ne) {
return false;
}
return true;
}
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> arg0,
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit(textField.getText());
boolean valid = validate(textField.getText());
if (!valid) {
if (!getStyleClass().contains(errorCSSClass)) {
getStyleClass().add(errorCSSClass);
}
} else {
getStyleClass().remove(errorCSSClass);
}
}
}
});
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if ((event.getCode() == KeyCode.ENTER)) {
commitEdit(textField.getText());
boolean valid = validate(textField.getText());
if (!valid) {
if (!getStyleClass().contains(errorCSSClass)) {
getStyleClass().add(errorCSSClass);
}
} else {
getStyleClass().remove(errorCSSClass);
}
} else if (event.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}
"errorTextField.css"
".text-field.error,.table-cell.error {
-fx-border-color: red ;
-fx-border-width: 2px ;
-fx-background-image:url('fail.png');
-fx-background-repeat: no-repeat;
-fx-background-position: right center;
}
.text-field,.table-cell {
-fx-border-width: 0px ;
-fx-background-image:none;
-fx-background-repeat: no-repeat;
-fx-background-position: right center;
} "
I am trying to display a red border and image on a text cell when there is an error.
I took the address book sample (example 12-11 http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#CJAGAAEE)
and modified it.
In the sample below, the 'last name' field has been changed to salary and must display an error (red border and image) if anything other than an integer is entered.
When there is an error, fail.png displays. After the error is corrected, I need to have it erased.
Using fx-background-image: none; somehow doesn't work.
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.Callback;
public class TableViewSample extends Application {
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Gates", "46", "Gates@example.com"),
new Person("Ellison", "25", "Ellison@example.com"),
new Person("McNealy", "1", "McNealy@example.com"),
new Person("Jobs", "0", "Jobs@example.com"),
new Person("Me", "0", "me@example.com"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(cellFactory);
firstNameCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setFirstName(t.getNewValue());
}
});
TableColumn salaryCol = new TableColumn("Salary");
salaryCol.setMinWidth(100);
salaryCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("salary"));
salaryCol.setCellFactory(cellFactory);
salaryCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setSalary(t.getNewValue());
}
});
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email"));
emailCol.setCellFactory(cellFactory);
emailCol.setOnEditCommit(
new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setEmail(t.getNewValue());
}
});
table.setItems(data);
table.getColumns().addAll(firstNameCol, salaryCol, emailCol);
final TextField addFirstName = new TextField();
addFirstName.setPromptText("First Name");
addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
final TextField addSalary = new TextField();
addSalary.setMaxWidth(salaryCol.getPrefWidth());
addSalary.setPromptText("Last Name");
final TextField addEmail = new TextField();
addEmail.setMaxWidth(emailCol.getPrefWidth());
addEmail.setPromptText("Email");
final Button addButton = new Button("Add");
addButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
data.add(new Person(
addFirstName.getText(),
addSalary.getText(),
addEmail.getText()));
addFirstName.clear();
addSalary.clear();
addEmail.clear();
}
});
hb.getChildren().addAll(addFirstName, addSalary, addEmail, addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
scene.getStylesheets().add(getClass().getResource("errorTextField.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty salary;
private final SimpleStringProperty email;
private Person(String fName, String pay, String email) {
this.firstName = new SimpleStringProperty(fName);
this.salary = new SimpleStringProperty(pay);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getSalary() {
return salary.get();
}
public void setSalary(String fName) {
salary.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
class EditingCell extends TableCell<Person, String> {
final String errorCSSClass = "error";
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private boolean validate(String text) {
try {
Integer.parseInt(text);
} catch (NumberFormatException ne) {
return false;
}
return true;
}
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> arg0,
Boolean arg1, Boolean arg2) {
if (!arg2) {
commitEdit(textField.getText());
boolean valid = validate(textField.getText());
if (!valid) {
if (!getStyleClass().contains(errorCSSClass)) {
getStyleClass().add(errorCSSClass);
}
} else {
getStyleClass().remove(errorCSSClass);
}
}
}
});
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if ((event.getCode() == KeyCode.ENTER)) {
commitEdit(textField.getText());
boolean valid = validate(textField.getText());
if (!valid) {
if (!getStyleClass().contains(errorCSSClass)) {
getStyleClass().add(errorCSSClass);
}
} else {
getStyleClass().remove(errorCSSClass);
}
} else if (event.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}
"errorTextField.css"
".text-field.error,.table-cell.error {
-fx-border-color: red ;
-fx-border-width: 2px ;
-fx-background-image:url('fail.png');
-fx-background-repeat: no-repeat;
-fx-background-position: right center;
}
.text-field,.table-cell {
-fx-border-width: 0px ;
-fx-background-image:none;
-fx-background-repeat: no-repeat;
-fx-background-position: right center;
} "