TableView komponenta je jednou z všestranných komponent často používaných při vývoji aplikací JavaFX. Umožňuje rychle vizuálně organizovat data. Divák může rychle uchopit i implicitní informace zamýšlené informacemi s jejich tabulkovým znázorněním. Tento článek zkoumá tuto komponentu z pohledu organizace dat a jak ji lze efektivně využít v programování v jazyce Java.
Zobrazení tabulky
TableView ovládání poskytuje téměř ekvivalentní funkce jako Jtable Swing součástka. Je navržen tak, aby představoval neomezený počet řádků dat rozdělených do sloupců. V JavaFX existuje další komponenta nazvaná ListView , která je podobná. Jediný rozdíl je v tom, že TableView podporuje více sloupců, zatímco ListView má jeden sloupec. Funkce TableView ovládání jsou následující:
- Protože se tabulka skládá z počtu sloupců, každý sloupec je reprezentován TableColumn třída. Tato třída poskytuje jemnější kontrolu nad sloupcem. Instance této třídy je zodpovědná za zobrazení a úpravu obsahu tohoto sloupce. Proto obsahuje řadu nastavitelných vlastností. Například,
- Jeho velikost lze změnit pomocí vlastnosti width (minWidth, maxWidth, prefWidth, width ).
- Viditelnost sloupce lze přepínat pomocí viditelnosti vlastnictví.
- Pro vlastnosti záhlaví sloupce a textu existují metody setter a getter.
- Lze zobrazit vnořené sloupce.
- Je zde kontextová nabídka, na kterou může uživatel kliknout pravým tlačítkem myši do oblasti záhlaví sloupce.
- Obsah lze třídit (pomocí komparátoru , seřadit , sortType ).
- Existují zásady pro změnu velikosti tabulky, které určují stav tabulky, když uživatel změní velikost sloupce.
- Poskytuje podporu pro řazení více sloupců.
Vytvoření TableView
Vytvořme ukázkovou aplikaci, která ukáže, jak TableView v JavaFX lze použít. Nejprve si představíme základy JavaFX TableView v kódu. Protože tabulka zobrazuje data, vytvoříme třídu, která data obsahuje.
package sample; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class Employee { private StringProperty name; private StringProperty phone; private StringProperty email; private IntegerProperty salary; public Employee(String name, String phone, String email, Integer salary) { setName(name); setPhone(phone); setEmail(email); setSalary(salary); } public StringProperty nameProperty(){ if(name == null) name = new SimpleStringProperty(); return name; } public StringProperty phoneProperty() { if(phone == null) phone = new SimpleStringProperty(); return phone; } public StringProperty emailProperty() { if(email == null) email = new SimpleStringProperty(); return email; } public IntegerProperty salaryProperty() { if(salary == null) salary = new SimpleIntegerProperty(); return salary; } public void setName(String name) { nameProperty().setValue(name); } public String getName() { return nameProperty().get(); } public void setPhone(String phone) {phoneProperty().setValue(phone);} public String getPhone() { return phoneProperty().get(); } public void setEmail(String email) { emailProperty().setValue(email);} public String getEmail() { return emailProperty().get(); } public void setSalary(Integer salary) { salaryProperty().setValue(salary);} public Integer getSalary() { return salaryProperty().get(); } }
Nyní vytvoříme rozložení aplikace a vložíme TableView jako jediná složka do scény.
package sample; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class AppMain extends Application { @Override public void start(Stage primaryStage) throws Exception { BorderPane root = new BorderPane(); root.setPrefSize(600,400); final TableView<Employee> employeeTableView = new TableView<>(); employeeTableView.setPrefWidth(500); employeeTableView.setItems(dummyEmployees()); TableColumn<Employee, String> nameCol = new TableColumn<>("Name"); nameCol.setCellValueFactory( new PropertyValueFactory<Employee, String>("Name")); TableColumn<Employee, String> phoneCol = new TableColumn<>("Phone"); phoneCol.setCellValueFactory( new PropertyValueFactory<Employee, String>("Phone")); TableColumn<Employee, String> emailCol = new TableColumn<>("Email"); emailCol.setCellValueFactory( new PropertyValueFactory<Employee, String>("Email")); TableColumn<Employee, Integer> salaryCol = new TableColumn<>("Salary"); salaryCol.setCellValueFactory( new PropertyValueFactory<Employee, Integer>("Salary")); employeeTableView.getColumns().addAll(nameCol,phoneCol, emailCol,salaryCol); root.setCenter(employeeTableView); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.setTitle("JavaFX TableView Demonstration"); primaryStage.show(); } private static ObservableList<Employee> dummyEmployees() { ObservableList<Employee> employees = FXCollections.observableArrayList(); employees.add(new Employee("Arko Bannerjee", "9876543210","[email protected]", 5600)); employees.add(new Employee("Subir Sha", "8109276354","[email protected]",7200)); employees.add(new Employee("Karoline Bhatt", "638374642","[email protected]",3600)); employees.add(new Employee("Vikas Verma", "425637772","[email protected]",7800)); employees.add(new Employee("Gurmeet Singh", "9876543210","[email protected]",8900)); employees.add(new Employee("Partho Goel", "837743636","[email protected]",5644)); employees.add(new Employee("Hanish Jaiswal", "826355343","[email protected]",6500)); employees.add(new Employee("Preety Ahuja", "9298366454","[email protected]",7800)); employees.add(new Employee("Sandip Paul", "82773554536","[email protected]",8600)); employees.add(new Employee("Sudipto Sarkar", "73664552542","[email protected]",8200)); employees.add(new Employee("Bikash Panda", "6365344245","[email protected]",8400)); employees.add(new Employee("Abhronil Sahu", "7829293663","[email protected]",8000)); employees.add(new Employee("Dilip Das", "9283665455","[email protected]",8100)); return employees; } public static void main(String[] args) { launch(args); } }
Tabulka je vytvořena s následujícím kódem:
final TableView<Employee> employeeTableView = new TableView<>();
Obsah tabulky představují přidané sloupce. Každý sloupec musí mít také záhlaví, které vizuálně označuje obsah sloupce. V tomto příkladu jsme nastavili čtyři sloupce (určené podle vlastnosti definované v Zaměstnanec třída).
TableColumn<Employee, String> nameCol = new TableColumn<>("Name"); nameCol.setEditable(true); nameCol.setCellValueFactory( new PropertyValueFactory<Employee, String>("Name"));
Výstup
Obrázek 1: Obsah tabulky
Dále jsme to nastavili jako hlavní součást rozvržení. To je vše, co musíme udělat, abychom zobrazili nějaký obsah v TableView . Funkce, jako je řazení obsahu, nevyžadují žádné speciální/další zacházení, protože jsou součástí jako výchozí funkce. Vícenásobné řazení lze také provést podržením klávesy SHIFT na klávesnici při výběru sloupců kliknutím myši.
Upravitelné sloupce v tabulce
Pokud chceme vytvořit tabulku, která má upravitelný sloupec, můžeme tak učinit velmi jednoduše. Když dvakrát klikneme na upravitelný sloupec, objeví se textové pole, kde můžeme upravit hodnotu. Aby byla změna trvalá, musíme stisknout klávesu Enter na klávesnici.
Zde je další příklad s upravitelnými sloupci.
package sample; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class PhoneBook { private StringProperty name; private StringProperty phone; public PhoneBook(String name, String phone) { setName(name); setPhone(phone); } public StringProperty nameProperty(){ if(name == null) name = new SimpleStringProperty(); return name; } public StringProperty phoneProperty(){ if(phone == null) phone = new SimpleStringProperty(); return phone; } public void setName(String name) { nameProperty().setValue(name); } public String getName() { return nameProperty().get(); } public void setPhone(String phone) { phoneProperty().setValue(phone);} public String getPhone() { return phoneProperty().get(); } @Override public String toString() { return getName()+" : "+getPhone(); } } package sample; import javafx.application.*; import javafx.beans.value.*; import javafx.collections.*; import javafx.geometry.*; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.cell.*; import javafx.scene.layout.*; import javafx.scene.text.*; import javafx.stage.*; public class PhoneBookTable extends Application { private TableView<PhoneBook> table; private ObservableList data; private Text txtStatus; @Override public void start(Stage primaryStage) { primaryStage.setTitle("Table View Demonstration."); HBox hb = new HBox(); hb.setAlignment(Pos.CENTER); table = new TableView<>(); data = dummyData(); table.setItems(data); TableColumn<PhoneBook,String> nameCol = new TableColumn<>("Name"); nameCol.setCellValueFactory(new PropertyValueFactory<>("name")); TableColumn<PhoneBook,String> phoneCol = new TableColumn("Phone"); phoneCol.setCellValueFactory(new PropertyValueFactory<>("phone")); table.getColumns().setAll(nameCol, phoneCol); table.setPrefWidth(400); table.setPrefHeight(250); table.setColumnResizePolicy(TableView. CONSTRAINED_RESIZE_POLICY); table.getSelectionModel().selectedIndexProperty(). addListener( new RowChangeHandler()); table.setEditable(true); phoneCol.setCellFactory(TextFieldTableCell. forTableColumn()); phoneCol.setOnEditCommit(event -> (event.getTableView(). getItems().get(event.getTablePosition().getRow())). setPhone(event.getNewValue())); txtStatus = new Text(); VBox vbox = new VBox(20); vbox.setPadding(new Insets(20, 20, 20, 20));; vbox.getChildren().addAll(hb, table, txtStatus); // W x H Scene scene = new Scene(vbox, 450, 375); primaryStage.setScene(scene); primaryStage.show(); table.getSelectionModel().select(0); PhoneBook pb = table.getSelectionModel(). getSelectedItem(); txtStatus.setText(pb.toString()); } private class RowChangeHandler implements ChangeListener { @Override public void changed(ObservableValue ov, Object oldVal, Object newVal) { int val = ((Number)newVal).intValue(); if (data.size()<=0) { return; } PhoneBook pb= (PhoneBook) data.get(val); txtStatus.setText(pb.toString()); } } public ObservableList<PhoneBook> dummyData() { ObservableList<PhoneBook> records = FXCollections.observableArrayList(); records.add(new PhoneBook("Mickey Mouse", "7894561230")); records.add(new PhoneBook("Donald Duck", "1234567890")); records.add(new PhoneBook("Alladin", "7418529630")); records.add(new PhoneBook("Zairo", "9638527410")); records.add(new PhoneBook("Batman", "7894561230")); records.add(new PhoneBook("Spiderman", "852478930")); return records; } public static void main(String [] args) { Application.launch(args); } }
Výstup
Obrázek 2: Jeden záznam extrahovaný z tabulky
Závěr
TableView komponenta je docela užitečná při návrhu uživatelského rozhraní, zvláště když děláme databázové programování. JavaFX učinil tuto komponentu všestrannou, i když při implementaci složitých tabulkových reprezentací existují určité nedostatky. Zde ukázaná použitelnost je samozřejmě jen škrábanec. Pomocí TableView lze dosáhnout více , jak uvidíme v dalších článcích.