<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.Scene?> <?import javafx.scene.layout.*?> <?import javafx.scene.control.*?> <?import javafx.scene.control.cell.PropertyValueFactory?> <?import javafx.collections.FXCollections?> <?import addressbook.*?> <Scene xmlns:fx="http://javafx.com/fxml" fx:controller="addressbook.Controller" stylesheets="addressbook/addressbook.css"> <GridPane styleClass="grid-pane"> <Label id="address-book" text="%addressBook" GridPane.columnIndex="0" GridPane.rowIndex="0"/> <TableView fx:id="tableView" tableMenuButtonVisible="true" GridPane.columnIndex="0" GridPane.rowIndex="1"> <columns> <TableColumn fx:id="firstNameColumn" text="%firstName" prefWidth="100"> <cellValueFactory> <PropertyValueFactory property="firstName"/> </cellValueFactory> <cellFactory> <FormattedTableCellFactory alignment="CENTER" addRowContextMenu="true"/> </cellFactory> </TableColumn> <TableColumn text="%lastName" prefWidth="100"> <cellValueFactory> <PropertyValueFactory property="lastName"/> </cellValueFactory> </TableColumn> <TableColumn text="%email" prefWidth="210" sortable="false"> <cellValueFactory> <PropertyValueFactory property="email"/> </cellValueFactory> </TableColumn> </columns> <Person firstName="Jacob" lastName="Smith" email="[email protected]"/> <Person firstName="Isabella" lastName="Johnson" email="[email protected]"/> <Person firstName="Ethan" lastName="Williams" email="[email protected]"/> <Person firstName="Emma" lastName="Jones" email="[email protected]"/> <Person firstName="Michael" lastName="Brown" email="[email protected]"/> <sortOrder> <fx:reference source="firstNameColumn"/> </sortOrder> </TableView> <HBox styleClass="h-box" GridPane.columnIndex="0" GridPane.rowIndex="2"> <TextField fx:id="firstNameField" promptText="%firstName" prefWidth="90"/> <TextField fx:id="lastNameField" promptText="%lastName" prefWidth="90"/> <TextField fx:id="emailField" promptText="%email" prefWidth="150"/> <Button text="%add" onAction="#addPerson"/> </HBox> </GridPane> </Scene>
/** * An address book application. * * @author HAN */ package addressbook;
# Title of window title=FXML Address Book # Name of label above the table view addressBook=Address Book # Name of the first table column # & Prompt text of text field for the first table column firstName=First Name # Name of the second table column # & Prompt text of text field for the second table column lastName=Last Name # Name of the third table column # & Prompt text of text field for the third table column email=Email Address # Name of button for adding rows to table add=Add
# Title of window title=FXML\u5730\u5740\u7C3F # Name of label above the table view addressBook=\u5730\u5740\u7C3F # Name of the first table column # & Prompt text of text field for the first table column firstName=\u540D\u5B57 # Name of the second table column # & Prompt text of text field for the second table column lastName=\u59D3 # Name of the third table column # & Prompt text of text field for the third table column email=\u7535\u5B50\u90AE\u4EF6 # Name of button for adding rows to table add=\u6DFB\u52A0
.grid-pane { -fx-alignment: center; -fx-hgap: 10; -fx-vgap: 10; -fx-padding: 10; } #address-book { -fx-font: NORMAL 20 Tahoma; } .h-box { -fx-spacing:10; -fx-alignment: bottom-right; }
package addressbook; import java.text.Format; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableRow; import javafx.scene.text.TextAlignment; import javafx.util.Callback; public class FormattedTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> { /** * The alignment for both the multiline text and label position within cell. */ private TextAlignment alignment; /** * Specify a Format if required to format the cell item. */ private Format format; /** * This variable is set because normally only one time of adding context * menu to table row is needed. So be aware of cooccurrence when setting * cell factory for multiple columns. */ private boolean addRowContextMenu; public TextAlignment getAlignment() { return alignment; } public Format getFormat() { return format; } public boolean getAddRowContextMenu() { return addRowContextMenu; } public void setAlignment(TextAlignment alignment) { this.alignment = alignment; } public void setFormat(Format format) { this.format = format; } public void setAddRowContextMenu(boolean addRowContextMenu) { this.addRowContextMenu = addRowContextMenu; } @Override public TableCell<S, T> call(TableColumn<S, T> arg0) { final TableCell<S, T> cell = new TableCell<S, T>() { @Override protected void updateItem(T item, boolean empty) { if (item == getItem()) { return; } super.updateItem(item, empty); if (item == null) { setText(null); setGraphic(null); } else if (item instanceof Node) { setText(null); setGraphic((Node) item); } else if (format != null) { setText(format.format(item)); setGraphic(null); } else { setText(item.toString()); setGraphic(null); } if (addRowContextMenu) addCM(this); } }; if (alignment == null) alignment = TextAlignment.LEFT; cell.setTextAlignment(alignment); switch (alignment) { case CENTER: cell.setAlignment(Pos.CENTER); break; case RIGHT: cell.setAlignment(Pos.CENTER_RIGHT); break; default: cell.setAlignment(Pos.CENTER_LEFT); } return cell; } private MenuItem delete = new MenuItem("Delete"); private ContextMenu contextMenu = new ContextMenu(delete); private void addCM(final TableCell<S, T> cell) { @SuppressWarnings("rawtypes") final TableRow row = cell.getTableRow(); delete.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { cell.getTableView().getItems().remove(row.getItem()); } }); if (row != null) { if (row.getItem() != null) { row.setContextMenu(contextMenu); } } } }
package addressbook; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; /** * A Bean convention based data model. * * @author HAN */ public class Person { private StringProperty firstName = new SimpleStringProperty(); private StringProperty lastName = new SimpleStringProperty(); private StringProperty email = new SimpleStringProperty(); public Person() { this("", "", ""); } public Person(String firstName, String lastName, String email) { setFirstName(firstName); setLastName(lastName); setEmail(email); } public final String getFirstName() { return firstName.get(); } public final String getLastName() { return lastName.get(); } public final String getEmail() { return email.get(); } public final void setFirstName(String firstName) { this.firstName.set(firstName); } public final void setLastName(String lastName) { this.lastName.set(lastName); } public final void setEmail(String email) { this.email.set(email); } public StringProperty firstNameProperty() { return firstName; } public StringProperty lastNameProperty() { return lastName; } public StringProperty emailProperty() { return email; } }
package addressbook; import javafx.fxml.FXML; import javafx.scene.control.TableView; import javafx.scene.control.TextField; public class Controller { @FXML private TableView<Person> tableView; @FXML private TextField firstNameField; @FXML private TextField lastNameField; @FXML private TextField emailField; @FXML private void addPerson() { tableView.getItems().add( new Person(firstNameField.getText(), lastNameField.getText(), emailField.getText())); firstNameField.clear(); lastNameField.clear(); emailField.clear(); } }
package addressbook; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; public class Model extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { Locale locale = getCurrentLocale(); ResourceBundle resources = ResourceBundle .getBundle("addressbook/addressbook", locale, Model.class.getClassLoader()); stage.setTitle(resources.getString("title")); stage.setScene((Scene) FXMLLoader.load( Model.class.getResource("View.fxml"), resources)); stage.show(); } private Locale getCurrentLocale() { Map<String, String> namedParams = getParameters().getNamed(); String languageParam = namedParams.get("language"); String countryParam = namedParams.get("country"); Locale locale = Locale.getDefault(); if (languageParam != null && languageParam.trim().length() > 0) { if (countryParam != null && countryParam.trim().length() > 0) { locale = new Locale(languageParam.trim(), countryParam.trim()); } else { locale = new Locale(languageParam.trim()); } } return locale; } }