La liaison de JavaFX 2 TableView éléments

Je travaillais sur une petite application à l'aide d'une simple liaison en JavaFx 2.1 à l'aide de java 1.7.0_04-b21 sur MacOSX. En fait je suis actuellement comparer les lier à des mécanismes de Cocoa sur Mac OSX pour la JavaFx et faire face à plusieurs problèmes:

L'application utilise un modèle de la détention d'un observableArrayList (appelé messageList) qui est défini comme les éléments d'une TableView. Ajout d'une nouvelle Entrée à la liste des œuvres. L'entrée s'affiche dans la TableView.

Question 1: la Suppression d'un élément sélectionné ne fonctionne pas. Lorsque je supprime un élément de la observables liste il ne disparaît pas.

Question 2: je veux remplir un champ de texte avec la valeur stockée dans un champ de l'objet sélectionné dans la TableView.
En effet, pour cette dans le Cacao, on peut définir une liaison à une sélection, même si c'est vide (donc, rien n'est sélectionné) au moment de la définition de la liaison. C'est en fait très utile, concept et je n'ai pas trouvé comment cela pourrait être possible en JavaFX.

Question 3: Seulement si un objet est sélectionné, une liaison peut être établie de sorte que j'ai finalement écrit un Gestionnaire de réagir à une évolution de sélection et de rétablissement toujours une bonne liaison de mon champ texte pour les modèles de champ. Mais aussi pour cette approche de mon application détruit le modèle pour une raison que je ne comprends pas maintenant.

Cliquez simplement trois ou quatre fois le Bouton ajouter, puis sélectionnez les entrées et voir les mises à jour de la zone de texte. Les données du modèle sont détruits et remplacé - et les entrées normalement obtenir plus courte... les Explications de l'effet sont les bienvenus.

Jusqu'à présent, je ne pouvais pas trouver un exemple de liaison sur une TableView donc tout commentaires sont les bienvenus.

Le code de mon projet de démonstration est inclus dans les fichiers suivants. Tous sont dans le même package 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);
}
}

Message.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); 
}
}

Model.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>
Cette question a aussi de nombreuses pièces et trop de code. Il serait mieux si chaque partie a été répartie en elle sa propre question avec un minimum de code pour illustrer uniquement le problème décrit dans la première question de la partie.
Bonjour jewelsea, effectivement, la question a beaucoup de pièces - oui. Mais en fait, il se résume à une seule: le mécanisme de liaison de travail pour TableView et si oui, est-il un exemple de travail. Pour moi, il ne fonctionne tout simplement pas pour des raisons différentes nommé questions ci-dessus. Encore toute aide est appréciée. Salutations, E. S.

OriginalL'auteur E.S. | 2012-05-21