不是我的问题,只是要澄清一下: 我正在尝试开发一个包含多个表格视图的应用程序。这些表格视图是在运行时单击按钮时创建的。我设法使用选项卡和选项卡完成此任务,并且还设法向这些选项卡添加不同的表格视图。通过该用户可以根据自己的需要创建表。选项卡在这里可以关闭,并可以通过单击按钮创建任意数量的用户想要的选项卡。一个选项卡包含一个表格视图。
我的问题: 所以在这里我只用一种模型处理太多的表格视图。这些表格视图包含每个列和单元格上的文本字段和按钮。它还具有在表视图中添加和删除行的功能。 所以这是我的主要问题,当用户单击按钮在特定表视图中添加行时,该行会自动添加到另一个选项卡中的另一个表视图(我不想要)中。当未选择表视图或用户不想添加行时,我不想在表视图中添加行。删除行时也会发生同样的情况。 那么,如何在多个表视图上添加和删除行而不出现任何这些问题?
这是我尝试过但失败的代码。给出大量代码块的目的是为了明确我是否走在正确的道路上。如果没有,请显示执行此操作的正确路径。
public static ObservableList<myModel> list = FXCollections.observableArrayList();
// in @override initialize method
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
@Override
public void changed(ObservableValue<? extends Tab> observableValue, Tab oldValue, Tab newValue) {
System.out.println("Tab selected: " + newValue.getText());
if (newValue.getContent() == null) {
System.out.println("New table created");
TableView<myModel> tableView = new TableView<>();
TableColumn<myModel, String> columnA = new TableColumn<>("A");
TableColumn<myModel, String> ColumnB = new TableColumn<>("B");
TableColumn<myModel, String> ColumnC = new TableColumn<>("C");
TableColumn<myModel, String> ColumnD = new TableColumn<>("D");
TableColumn<myModel, String> ColumnE = new TableColumn<>("E");
TableColumn<myModel, Button> ColumnF = new TableColumn<>("F");
Callback<TableColumn<myModel, Button>, TableCell<myModel, Button>> btncellFactory =
new Callback<TableColumn<myModel, Button>, TableCell<myModel, Button>>() {
@Override
public TableCell<myModel, Button> call(TableColumn<myModel, Button> elementsStringTableColumn) {
final TableCell<myModel, Button> cell = new TableCell<myModel, Button>() {
private final Button button = new Button("Delete");
{
button.setFocusTraversable(false);
button.setOnAction((ActionEvent event) -> {
System.out.println("Deleting rows");
TableRow row = this.getTableRow();
row.updateSelected(true);
System.out.println("row item: " + row.getItem() +" Index: "+ (row.getIndex()+1) + row.isSelected());
getTableView().getItems().remove(row.getIndex()); //remove rows but not specific with tableviews thats why remove rows from all tableview
});
}
@Override
public void updateItem(Button item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(button);
}
}
};
return cell;
}
};
columnA.setCellFactory(ACellFactory.cell());
ColumnB.setCellFactory(BCellFactory.cell());
ColumnC.setCellFactory(CCellFactory.cell());
ColumnD.setCellFactory(DCellFactory.cell());
ColumnE.setCellFactory(ECellFactory.cell());
ColumnF.setCellFactory(btncellFactory);
addRowBtn.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
list.add(new mymodel(myModel.getA(), myModel.getB(), myModel.getC(), myModel.getD(), myModel.getE())); // on button click create a row
}
});
// I tried to do this to be specific on tableview which is on selected tab but failed
if (newValue.getText().equals(newValue.getText())) tableView.setItems(list);
tableView.getColumns().setAll(columnA, ColumnB, ColumnC, ColumnD, ColumnE, ColumnF);
newValue.setContent(tableView);
} else System.out.println("Containing table: " + newValue.getContent());
}
});
如果有人提供解决此问题的代码,请添加有关您的代码块实际用途的评论。
所以在这里我只用一个模型处理太多的表格视图。
假设我正确理解你的问题,解决方案就是显而易见的:为每个表使用不同的模型(即不同的
ObservableList
)。
如果您只是以正常方式进行设置,也就是说,只需创建一个带有添加和删除按钮的表视图以及表视图的模型,然后每次向选项卡式窗格添加一个新模型,那么默认情况下基本上会发生这种情况你需要。
这是一个简单的例子。首先,表项的模型类:
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Item {
private final StringProperty name = new SimpleStringProperty();
public Item(String name) {
setName(name);
}
public StringProperty nameProperty(){
return name;
}
public final String getName() {
return nameProperty().get();
}
public final void setName(String name) {
nameProperty().set(name);
}
}
带有表视图的 FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jamesd.examples.tabbedtables.ItemTableController">
<center>
<TableView fx:id="table">
<columns>
<TableColumn fx:id="nameCol"/>
</columns>
</TableView>
</center>
<bottom>
<HBox spacing="5">
<padding><Insets topRightBottomLeft="5"/></padding>
<TextField fx:id="nameField" onAction="#addItem"/>
<Button text="Add" onAction="#addItem"/>
<Button fx:id="removeButton" text="Remove" onAction="#deleteSelected" />
</HBox>
</bottom>
</BorderPane>
及其控制器,它在这里创建项目列表(您可以按照您需要的任何方式重构它,只要您为控制器的每个实例都有一个新列表):
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
public class ItemTableController {
private final ObservableList<Item> itemList = FXCollections.observableArrayList();
@FXML
private Button removeButton;
@FXML
private TableView<Item> table;
@FXML
private TextField nameField;
@FXML
private TableColumn<Item, String> nameCol;
@FXML
private void initialize() {
table.setItems(itemList);
nameCol.setCellValueFactory(data -> data.getValue().nameProperty());
removeButton.disableProperty().bind(Bindings.isEmpty(table.getSelectionModel().getSelectedItems()));
}
@FXML
private void addItem() {
Item item = new Item(nameField.getText());
itemList.add(item);
nameField.clear();
}
public void deleteSelected(ActionEvent actionEvent) {
itemList.remove(table.getSelectionModel().getSelectedItem());
}
}
这是“主”视图,带有选项卡窗格和用于添加新选项卡的按钮(每个选项卡中都有表格):
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jamesd.examples.tabbedtables.TabbedTablesController">
<center>
<TabPane fx:id="tabPane"/>
</center>
<bottom>
<HBox alignment="CENTER">
<padding><Insets topRightBottomLeft="10"/></padding>
<Button text="New Table" onAction="#newTable"/>
</HBox>
</bottom>
</BorderPane>
及其控制器,该控制器加载第一个 FXML 并将其包装在选项卡中添加到选项卡窗格中:
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import java.io.IOException;
public class TabbedTablesController {
@FXML
private TabPane tabPane;
@FXML
private void newTable() throws IOException {
Tab tab = new Tab(STR."Table \{tabPane.getTabs().size() + 1}");
tab.setContent(FXMLLoader.load(getClass().getResource("ItemTable.fxml")));
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tab);
}
}
最后是应用类:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class TabbedTableApp extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(TabbedTableApp.class.getResource("TabbedTables.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 800, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
由于表的每个控制器创建不同的后备列表,因此表的数据是独立的。这是添加两个新表(向第一个表添加两个项目,向第二个表添加一个项目)后的屏幕截图: