gpt4 book ai didi

绑定(bind) JavaFX 2 TableView 元素

转载 作者:行者123 更新时间:2023-12-05 01:27:52 28 4
gpt4 key购买 nike

我正在使用 JavaFx 2.1 中的简单绑定(bind)在 MacOSX 上使用 java 1.7.0_04-b21 开发一个小型应用程序。实际上,我目前将 Mac OSX 上 Cocoa 的绑定(bind)机制与 JavaFx 进行比较,并面临几个问题:

该应用程序使用一个模型来保存一个 observableArrayList(称为 messageList),它被设置为 TableView 的项目。向列表中添加新条目有效。该条目出现在 TableView 中。

问题 1:删除所选项目不起作用。当我从可观察列表中删除一个项目时,它不会消失。

问题 2:我想用存储在 TableView 中选择的对象的一个​​字段中的值填充 textField。
实际上,在 Cocoa 中,即使在绑定(bind)定义的时间点 this 为空(因此没有选择任何内容),也可以定义对选择的绑定(bind)。这实际上是一个非常有用的概念,我没有发现这在 JavaFX 中是如何实现的。

问题 3:仅当已经选择了一个对象时,才能建立绑定(bind),以便我最终编写了一个 EventHandler 对不断变化的选择使用react,并始终重新建立我的文本字段与模型字段的正确绑定(bind)。但是对于这种方法,我的应用程序出于某种我现在不明白的原因破坏了模型。

只需单击添加按钮三四次,然后选择条目并查看 textField 的更新。模型中的数据被破坏和覆盖 - 条目通常会变短......欢迎解释效果。

到目前为止,我在 TableView 上找不到绑定(bind)示例,因此欢迎任何输入。

我的演示项目的代码包含在以下文件中。所有这些都在同一个包 com.es.javaFxTest 中。

MainWindowController.java:

/*
* Created on 19.05.2012
*/
package com.es.javaFxTest;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ResourceBundle;

import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;

public class MainWindowController implements Initializable
{

public Model model;

public TableView<Message> messageListTableView;

public TableColumn<Message, String> messageTableMessageNameColumn;

public Button addMessageButton;

public Button deleteMessageButton;

public TextField messageNameTextField;

public SimpleObjectProperty<Message> selectedMessage;

/* (non-Javadoc)
* @see javafx.fxml.Initializable#initialize(java.net.URL, java.util.ResourceBundle)
*/
@Override
public void initialize(URL arg0, ResourceBundle arg1)
{
model = new Model();

messageTableMessageNameColumn.setCellValueFactory(new PropertyValueFactory<Message, String>("messageName"));
messageListTableView.setItems(model.getMessageList());

addMessageButton.setOnAction(new EventHandler<ActionEvent>() {
StringBuffer str = new StringBuffer("a"); // to fill some dummy data

@Override
public void handle(ActionEvent e)
{
// adding an object to the observed list works and the result is shown in the tableView
model.getMessageList().add(new Message(str.toString()));
str.append("x");
}
});
deleteMessageButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event)
{ // observation does not work here; also the following code does not work.
ObservableList<Integer> selectedIndices = messageListTableView.getSelectionModel().getSelectedIndices();
ArrayList<Integer> selectedIndices2 = new ArrayList<Integer>(selectedIndices);
Collections.sort(selectedIndices2);
for (int i = selectedIndices2.size() - 1; i >= 0; i--)
{
model.getMessageList().remove(selectedIndices2.get(i));
}
}
});

selectedMessage = new SimpleObjectProperty<Message>();
selectedMessage.bind(messageListTableView.getSelectionModel().selectedItemProperty());

selectedMessage.addListener(new ChangeListener<Message>() {

@Override
public void changed(ObservableValue< ? extends Message> observable, Message oldValue, Message newValue)
{
System.out.format("ObservableValue %s, \n oldValue %s\n newValue %s\n\n", observable, oldValue, newValue);
if (oldValue != null)
{
messageNameTextField.textProperty().unbind();
oldValue.messageName.unbind();
}
if (newValue != null)
{
messageNameTextField.textProperty().set(newValue.getMessageName());
newValue.messageName.bindBidirectional(messageNameTextField.textProperty());
}
}
});
}
}

MainWindowLayout.java
package com.es.javaFxTest;

/*
* Created on 18.05.2012
*/
import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class MainWindowLayout extends Application
{

@Override
public void start(Stage stage)
{

try
{
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MainWindowLayout.fxml"));
Pane root = (Pane) fxmlLoader.load();
MainWindowController controller = (MainWindowController) fxmlLoader.getController();

Scene scene = new Scene(root);
stage.setTitle("Config");
stage.setScene(scene);
stage.show();

}
catch (IOException e)
{
e.printStackTrace();
}
}

public static void main(String[] args)
{
launch(args);
}

}

消息.java
/*
* Created on 19.05.2012
*
*/
package com.es.javaFxTest;

import javafx.beans.property.SimpleStringProperty;

public class Message
{



/**
* @param canId
* @param messageName
*/
public Message(String messageName)
{
this.messageName = new SimpleStringProperty(messageName);
}


SimpleStringProperty messageName;
/**
* @return the messageName
*/
public String getMessageName()
{
return messageName.getValue();
}
/**
* @param messageName the messageName to set
*/
public void setMessageName(String messageName)
{
this.messageName.set(messageName);
}

public String toString ()
{
return String.format("Name:%s",messageName);
}

}

模型.java
/*
* Created on 20.05.2012
*/
package com.es.javaFxTest;

import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class Model
{
ObservableList<Message> messageList;

SimpleListProperty<Message> messageListProperty;

public Model()
{
messageList = FXCollections.observableArrayList();
messageListProperty = new SimpleListProperty<Message>(this,"messageList",messageList);
}

public final SimpleListProperty<Message> messageListProperty()
{
return messageListProperty;
}

public ObservableList<Message> getMessageList()
{
return messageListProperty.get();
}

public void setMessageList(ObservableList<Message> l)
{
messageListProperty.set(l);
}
}

MainWindowLayout.xml
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="500.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.es.javaFxTest.MainWindowController">
<children>
<SplitPane id="splitPaneHorizontal1" dividerPositions="0.3614457831325301" focusTraversable="true" prefHeight="600.0" prefWidth="900.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane id="anchorPane1" minHeight="0.0" minWidth="0.0" prefHeight="598.0" prefWidth="390.0">
<children>
<VBox id="VBox" alignment="CENTER" prefHeight="598.0" prefWidth="177.0" spacing="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<TableView id="tableView1" fx:id="messageListTableView" editable="true" prefHeight="598.0" prefWidth="406.0">
<columns>
<TableColumn prefWidth="75.0" text="Name" fx:id="messageTableMessageNameColumn" />
</columns>
</TableView>
<HBox id="HBox" alignment="CENTER" spacing="5.0">
<children>
<Button id="button2" fx:id="addMessageButton" text="Add">
<HBox.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</HBox.margin>
</Button>
<Button id="button1" fx:id="deleteMessageButton" text="Delete">
<HBox.margin>
<Insets bottom="5.0" right="5.0" top="5.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
<AnchorPane id="anchorPane2" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<HBox id="HBox" alignment="CENTER" layoutX="44.0" layoutY="177.0" spacing="5.0">
<children>
<Label id="label2" text="Name:" />
<TextField id="textField2" fx:id="messageNameTextField" prefWidth="200.0" text="TextField" />
</children>
</HBox>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>

最佳答案

问题 1 ——您踏入了著名的 Java 自动装箱陷阱之一。

model.getMessageList().remove(selectedIndices2.get(i)); // get(i) returns Integer

来电 List.remove(Object o)而不是 List.remove(int idx)正如你所料。

采用
model.getMessageList().remove(selectedIndices2.get(i).intValue());

反而。

第2-3期

只需将监听器附加到 selectedItem并重新绑定(bind)更改:
    messageListTableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Message>() {

@Override
public void changed(ObservableValue<? extends Message> ov, Message old, Message newM) {
messageNameTextField.textProperty().unbindBidirectional(old.messageName);
messageNameTextField.textProperty().bindBidirectional(newM.messageName);
}
});

并更新您的 Message 类。要正确使用 TableView,它需要完整的 FX“bean”并通过方法公开属性:
public StringProperty messageNameProperty() {
return messageName;
}

关于绑定(bind) JavaFX 2 TableView 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10692654/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com