我一直在努力了解有关使用JavaFX的更多信息,并决定启动一个可以利用它的项目。现在,我对Java很新,并且正在自学。我已经弄清楚如何创建TableView
以及如何向其中添加内容,但我对如何编辑现有内容感到困惑。
在这个应用程序中我已经设置好了,所以一个人可以在桌面视图中添加玩家名称和某些统计数据,但我现在想要添加一个随机滚动并添加dex和其他修饰符并填充表格视图它。这将驻留在rollInitBtnClicked()
模块中。
请帮助我理解(因为上帝的爱解释它,所以初学者可以理解它)我需要做什么。
这是我的Main
课程。
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
TextField playerName;
TextField dexMod;
TextField otherMod;
TableView<Players> playersTable;
Button addPlayerBtn;
Button rollInitBtn;
Button delPlayerBtn;
public static void main(String[] args){
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Initiative");
// TextField so the user can enter a players Name
playerName = new TextField();
playerName.setPrefSize(200, 20);
playerName.setPromptText("Player Name");
//playerName.setFocusTraversable(false);
// TextField so the user can enter the players dex mod
dexMod = new TextField();
dexMod.setPrefSize(50, 20);
dexMod.setPromptText("Dex");
//dexMod.setFocusTraversable(false);
// TextField so the user can enter the players other mods
otherMod = new TextField();
otherMod.setPrefSize(50, 20);
otherMod.setPromptText("Other");
//otherMod.setFocusTraversable(false);
addPlayerBtn = new Button("Add Player");
addPlayerBtn.setOnAction(e -> addPlayerBtnClicked());
delPlayerBtn = new Button("Delete Player");
delPlayerBtn.setOnAction(e -> delPlayerBtnClicked());
rollInitBtn = new Button("Roll Initiative");
rollInitBtn.setOnAction(e -> rollInitBtnClicked());
//TableView Name Columns
TableColumn<Players, String> nameColumn = new TableColumn<>("Name");
nameColumn.setMinWidth(200);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
//TableView dexMod Columns
TableColumn<Players, String> dexColumn = new TableColumn<>("Dex Mod");
dexColumn.setMinWidth(50);
dexColumn.setStyle( "-fx-alignment: CENTER;");
dexColumn.setCellValueFactory(new PropertyValueFactory<>("dexMod"));
//TableView otherMod Columns
TableColumn<Players, String> otherColumn = new TableColumn<>("Other Mods");
otherColumn.setMinWidth(50);
otherColumn.setStyle( "-fx-alignment: CENTER;");
otherColumn.setCellValueFactory(new PropertyValueFactory<>("otherMod"));
//TableView roll Columns
TableColumn<Players, String> rollColumn = new TableColumn<>("Die Roll");
rollColumn.setMinWidth(50);
rollColumn.setStyle( "-fx-alignment: CENTER;");
rollColumn.setCellValueFactory(new PropertyValueFactory<>("roll"));
//TableView total Columns
TableColumn<Players, String> totalColumn = new TableColumn<>("Total");
totalColumn.setMinWidth(50);
totalColumn.setStyle( "-fx-alignment: CENTER;");
totalColumn.setCellValueFactory(new PropertyValueFactory<>("total"));
playersTable = new TableView<>();
playersTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
playersTable.setItems(getPlayers());
playersTable.getColumns().addAll(nameColumn, dexColumn, otherColumn, rollColumn, totalColumn);
HBox hLayout = new HBox();
hLayout.setPadding(new Insets(10, 10, 10, 10)); // sets the padding on the top right left and bottom of the layout
hLayout.setSpacing(10); // sets the spacing between the TextFields and buttons
hLayout.getChildren().addAll(playerName, dexMod, otherMod, addPlayerBtn, rollInitBtn, delPlayerBtn);
VBox vLayout = new VBox();
vLayout.getChildren().addAll(playersTable, hLayout);
Scene mainScene = new Scene(vLayout, 800, 400);
primaryStage.setScene(mainScene);
primaryStage.show();
}
// What happens when the user clicks the Add Player button
public void addPlayerBtnClicked() {
Players players = new Players();
players.setName(playerName.getText());
players.setDexMod(Integer.parseInt(dexMod.getText()));
players.setOtherMod(Integer.parseInt(otherMod.getText()));
playersTable.getItems().add(players);
playerName.clear();
dexMod.clear();
otherMod.clear();
}
// What happens when the user clicks the Delete Player button
public void delPlayerBtnClicked() {
ObservableList<Players> playerSelected, allPlayers;
allPlayers = playersTable.getItems();
playerSelected = playersTable.getSelectionModel().getSelectedItems();
playerSelected.forEach(allPlayers::remove);
}
public void rollInitBtnClicked() {
Players players = new Players();
ObservableList<Players> playerSelected, allPlayers;
allPlayers = playersTable.getItems();
playerSelected = playersTable.getSelectionModel().getSelectedItems();
players.setRoll((int)Math.ceil(Math.random() * 20));
}
public ObservableList<Players> getPlayers(){
ObservableList<Players> players = FXCollections.observableArrayList();
return players;
}
}
以下活动名为Players
。
public class Players {
private String name;
private int dexMod;
private int otherMod;
private int roll;
private int total;
// default method to enter default data
public Players(){
}
// overloaded method to enter data that is handed to it
public Players(String name, int dexMod, int otherMod, int roll, int total){
this.name = name;
this.dexMod = dexMod;
this.otherMod = otherMod;
this.roll = roll;
this.total = total;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDexMod() {
return dexMod;
}
public void setDexMod(int dexMod) {
this.dexMod = dexMod;
}
public int getOtherMod() {
return otherMod;
}
public void setOtherMod(int otherMod) {
this.otherMod = otherMod;
}
public int getRoll() {
return roll;
}
public void setRoll(int roll) {
this.roll = roll;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
}
我很抱歉,如果这已被解决了40次但是新的我很难搞清楚并找出可能已经提供的解决方案。
答案 0 :(得分:0)
首先需要将表格标记为可编辑
playersTable.setEditable(true);
您还需要更改任何可编辑列的单元格工厂。
nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
对于整数类型列,您还需要指定转换器。
otherColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
rollColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
totalColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
并修正从<Players, String>
到<Players, Integer>
的声明,即
TableColumn<Players, Integer> totalColumn = new TableColumn<>("Total");
您现在可以通过执行&#34;长按&#34;或按F2来编辑表格,就像标准应用程序一样...
中找到更多信息答案 1 :(得分:0)
要使TableView
收到修改通知,您需要将ObservableValue
包装可用的属性值通知修改。 PropertyValueFactory
使用方法<propertyName>Property()
来检索此ObservableValue
。如果不存在这样的方法,则使用getter;但是在这种情况下,TableView
未通知任何修改。此外,total
属性不应该自行修改。
从JavaFX 8u60开始,refresh
中有一个TableView
方法,允许您手动触发刷新:
private final Random random = new Random();
public void rollInitBtnClicked() {
List<Players> targets = playersTable.getItems();
for (Players p : targets) {
p.setRoll(random.nextInt(20));
// set total ect...
}
// update table
playersTable.refresh();
}
然而,“与旧版JavaFX兼容的标准方法是修改属性:
private final IntegerProperty roll = new SimpleIntegerProperty();
public int getRoll() {
return roll.get();
}
public void setRoll(int roll) {
this.roll.set(roll);
}
public IntegerProperty rollProperty() {
return this.roll;
}
// same modifications for other int properties
...
private final IntegerBinding total = Bindings.createIntegerBinding(() -> getRoll() + getOtherMod() + getDexMod(), roll, otherMod, dexMod);
public int getTotal() {
return this.total.get();
}
public IntegerBinding totalProperty() {
return this.total;
}
这样您就可以从上面发布的refresh
方法中移除rollInitBtnClicked
来电。
Players
,而应命名为Player
。您使用TableColumn
的错误类型参数。这在此并不重要,因为PropertyValueFactory
无论类型参数如何都可以正常工作,但如果您使用TableColumn
的其他功能,它可能会让您遇到问题。第二个类型参数应始终与ObservableValue
返回的cellValueFactory
的类型参数匹配:
TableColumn<Players, String> nameColumn
TableColumn<Players, Number> dexColumn
TableColumn<Players, Number> otherColumn
TableColumn<Players, Number> rollColumn
TableColumn<Players, Number> totalColumn