JavaFx-TableView

2021-03-02 14:56:24 浏览数 (1)

效果
代码
代码语言:javascript复制
//表格视图
public class TableViewSample extends Application {

	/*
	TableView类内置提供了对列数据排序的功能。用户可以通过单击列头来改变数据顺序。
	第一次点击将会升序排列,第二次会降序排列,第三次则会取消对该列排序。
	默认情况下不会对任何一列进行排序。
	 */
	private final TableView<Person>      table = new TableView<>();
	//由于ObservableList对象具有自动追踪其包含元素的改变的功能,所以TableView的内容将会在数据改变时自动更新。
	private final ObservableList<Person> data  =
			FXCollections.observableArrayList(
					new Person("Jacob", "Smith", "jacob.smith@example.com"),
					new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
					new Person("Ethan", "Williams", "ethan.williams@example.com"),
					new Person("Emma", "Jones", "emma.jones@example.com"),
					new Person("Michael", "Brown", "michael.brown@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<Person, String>,
				TableCell<Person, String>> cellFactory
				= (TableColumn<Person, String> p) -> new EditingCell();

		TableColumn<Person, String> firstNameCol =
				new TableColumn<>("First Name");
		firstNameCol.setMinWidth(100);
		//下一步则是将数据关联到表格中的列
		/*
		setCellValueFactory方法为每列指定了一个单元格工厂(cell factory),
		这些cell factory是通过PropertyValueFactory类来实现的,
		它将Person类中对应的属性映射到对应的表格列中。
		 */
		firstNameCol.setCellValueFactory(
				new PropertyValueFactory<>("firstName"));

		//TableView类不仅仅可以展现表格数据,并且提供了编辑功能。使用setEditable方法来启用对表格内容的编辑。
		//
		//使用setCellFactory方法来重新实现表格的单元格,使用TextFieldTableCell类来使其变成一个文本域。
		//setOnEditCommit方法处理编辑过程,并且将更新后的值分配给对应的表格单元格
		//注意TextField控件默认实现的行为是在用户按下回车键后提交对内容的编辑。
		//你可以重新定义TextField的行为使其在失去焦点时提交对内容的编辑
//		firstNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
		firstNameCol.setCellFactory(cellFactory);

		firstNameCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
			@Override
			public void handle(CellEditEvent<Person, String> event) {
				event.getTableView().getItems().get(event.getTablePosition().getRow());
			}
		});
		firstNameCol.setOnEditCommit(
				(CellEditEvent<Person, String> t) -> {
					((Person) t.getTableView().getItems().get(
							t.getTablePosition().getRow())
					).setFirstName(t.getNewValue());
				});


		TableColumn<Person, String> lastNameCol =
				new TableColumn<>("Last Name");
		lastNameCol.setMinWidth(100);
		lastNameCol.setCellValueFactory(
				new PropertyValueFactory<>("lastName"));
//		lastNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
		lastNameCol.setCellFactory(cellFactory);
		lastNameCol.setOnEditCommit(
				(CellEditEvent<Person, String> t) -> {
					((Person) t.getTableView().getItems().get(
							t.getTablePosition().getRow())
					).setLastName(t.getNewValue());
				});

		TableColumn<Person, String> emailCol = new TableColumn<>("Email");
		emailCol.setMinWidth(200);
		emailCol.setCellValueFactory(
				new PropertyValueFactory<>("email"));
//		emailCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
		emailCol.setCellFactory(cellFactory);
		;
		emailCol.setOnEditCommit(
				(CellEditEvent<Person, String> t) -> {
					((Person) t.getTableView().getItems().get(
							t.getTablePosition().getRow())
					).setEmail(t.getNewValue());
				});

//		TableColumn firstEmailCol = new TableColumn("Primary");
//		TableColumn secondEmailCol = new TableColumn("Secondary");
//		emailCol.getColumns().addAll(firstEmailCol, secondEmailCol);
//作为开发者,你可以通过setSortType方法来为每一列设置排序特性。
//你可以指定升序和降序类型。例如,使用下面的代码行可以将emailCol列设置为降序:
//		emailCol.setSortType(TableColumn.SortType.DESCENDING);
		/*
		你可以通过setVisible方法来管理列的可见性。
		例如需要隐藏电子邮件信息列,你可以通过emailCol.setVisible(false)来实现。
		 */

		//当数据模型被定义完毕,并且数据被关联到列之后,
		//你可以通过TableView类的setItems方法来向表格中添加数据:如:table.setItems(data)。
		table.setItems(data);
		table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);


		final TextField addFirstName = new TextField();
		addFirstName.setPromptText("First Name");
		addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
		final TextField addLastName = new TextField();
		addLastName.setMaxWidth(lastNameCol.getPrefWidth());
		addLastName.setPromptText("Last Name");
		final TextField addEmail = new TextField();
		addEmail.setMaxWidth(emailCol.getPrefWidth());
		addEmail.setPromptText("Email");

		final Button addButton = new Button("Add");
		addButton.setOnAction((ActionEvent e) -> {
			data.add(new Person(
					addFirstName.getText(),
					addLastName.getText(),
					addEmail.getText()));
			addFirstName.clear();
			addLastName.clear();
			addEmail.clear();
		});


//		table.setRowFactory(tv -> {
//			TableRow<Person> row = new TableRow<>();
//			row.setOnMouseClicked(event -> {
//				if (event.getClickCount() == 2 && (!row.isEmpty())) {
//					Person rowData = row.getItem();
//					System.out.println("Double click on: "   rowData);
//				}
//			});
//			return row;
//		});

		final Button RemoveButton = new Button("Remove");
		RemoveButton.setOnAction((ActionEvent e) -> {
			table.getItems().removeAll(
					table.getSelectionModel().getSelectedItems()
			);
		});


		hb.getChildren().addAll(addFirstName, addLastName, addEmail, addButton, RemoveButton);
		hb.setSpacing(3);

		//关闭
		final Button closeButton = new Button("close");
		closeButton.setOnAction((ActionEvent e) -> {
			stage.close();
		});

		final VBox vbox = new VBox();
		vbox.setSpacing(5);
		vbox.setPadding(new Insets(10, 0, 0, 10));
		vbox.getChildren().addAll(label, table, hb, closeButton);

		((Group) scene.getRoot()).getChildren().addAll(vbox);

		stage.setScene(scene);
		stage.show();
	}


	private MenuBar menuBar(Stage stage) {
		Menu fileMenu = new Menu("test");
		MenuItem locationRemove = new MenuItem("test1");
		MenuItem locationAdd = new MenuItem("test2");
		MenuItem exit = new MenuItem("Exit");
		exit.setOnAction((ActionEvent e) -> {
			stage.close();
		});
		fileMenu.getItems().addAll(
				locationAdd,
				new SeparatorMenuItem(),
				locationRemove,
				new SeparatorMenuItem(),
				exit
		);

		MenuBar menuBar = new MenuBar();
		menuBar.getMenus().addAll(fileMenu);
		return menuBar;
	}

	public static class Person {

		private final SimpleStringProperty firstName;
		private final SimpleStringProperty lastName;
		private final SimpleStringProperty email;

		private Person(String fName, String lName, String email) {
			this.firstName = new SimpleStringProperty(fName);
			this.lastName = new SimpleStringProperty(lName);
			this.email = new SimpleStringProperty(email);
		}

		public String getFirstName() {
			return firstName.get();
		}

		public void setFirstName(String fName) {
			firstName.set(fName);
		}

		public String getLastName() {
			return lastName.get();
		}

		public void setLastName(String fName) {
			lastName.set(fName);
		}

		public String getEmail() {
			return email.get();
		}

		public void setEmail(String fName) {
			email.set(fName);
		}

		@Override
		public boolean equals(Object o) {
			if (this == o) return true;
			if (o == null || getClass() != o.getClass()) return false;
			Person person = (Person) o;
			return Objects.equals(getFirstName(), person.getFirstName()) && Objects.equals(getLastName(), person.getLastName()) && Objects.equals(getEmail(), person.getEmail());
		}

		@Override
		public int hashCode() {
			return Objects.hash(getFirstName(), getLastName(), getEmail());
		}

		@Override
		public String toString() {
			return "Person{"  
					"firstName="   firstName  
					", lastName="   lastName  
					", email="   email  
					'}';
		}
	}

	class EditingCell extends TableCell<Person, String> {

		private       TextField   textField;
		private final ContextMenu addMenu = new ContextMenu();

		public EditingCell() {
			MenuItem addMenuItem = new MenuItem("Add Employee");
			addMenu.getItems().add(addMenuItem);
			addMenuItem.setOnAction((ActionEvent t) -> {
				data.add(new Person(
						"new",
						"new",
						"new"));
			});
		}

		@Override
		public void startEdit() {
			if (!isEmpty()) {
				super.startEdit();
				createTextField();
				setText(null);
				setGraphic(textField);
				textField.selectAll();
//				textField.clear();
			}
		}

		@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);
					setContextMenu(addMenu);
				}
			}
		}

		private void createTextField() {
			textField = new TextField(getString());
			textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
			textField.focusedProperty().addListener(
					(ObservableValue<? extends Boolean> arg0,
					 Boolean arg1, Boolean arg2) -> {
						if (!arg2) {
							commitEdit(textField.getText());
						}
					});
		}

		private String getString() {
			return getItem() == null ? "" : getItem().toString();
		}
	}
}

0 人点赞