IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

TableCell éditer cellules


Sujet :

JavaFX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de scorbo
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 176
    Par défaut TableCell éditer cellules
    Bonjour,

    J'aimerai pouvoir éditer certaines cellules d'un tableau que j'ai rempli avec une WebView. Mon idée est d'écrire une factory qui me permet de renvoyer un textarea lorsqu'on est en mode édition et une WebView lorsqu'on sort du mode édition (c'est la même idée qui existe déjà avec un textfield). Ça marchote un peu...
    Premier souci : au moment de récupérer la position de la cellule lorsqu'on clique dessus, je ne récupère que "0, null". J'ai du appliquer "setDisable(true)" à la cellule dans la factory pour obtenir la bonne position. J'ai l'impression que la WebView consomme le clic (même comportement avec un textarea) ou quelque chose dans le genre... mais si c'est le cas comment le handler d'évènement souris du tableau peut-il voir l'évènement ? Qu'en est-il vraiment ?
    Deuxième souci : sachant que le renderer de la cellule dépend du type de l'élément (tous les éléments héritent de la même classe mère), comment le convertisseur utilisé par la factory peut-il renvoyer le bon type d'objet ? Autrement dit, comment recréé le même type d'objet qu'il y avait avant d'entrée en mode édition ?


    Merci d'avance

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Ceci devrait faire un bon point de depart :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextArea;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.control.cell.TextFieldTableCell;
    import javafx.scene.layout.StackPane;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    import javafx.util.StringConverter;
     
    public final class Main extends Application {
     
        @Override
        public void start(Stage primaryStage) {
            final TableView<Foo> tableView = new TableView<>();
            tableView.setEditable(true);
            tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
            final TableColumn<Foo, Number> idColumn = new TableColumn<>("id");
            idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
            final TableColumn<Foo, String> comment1Column = new TableColumn<>("comment #1");
            comment1Column.setCellValueFactory(new PropertyValueFactory<>("comment"));
            comment1Column.setEditable(true);
            comment1Column.setCellFactory(column -> new FooCommentTableCell());
            final TableColumn<Foo, String> comment2Column = new TableColumn<>("comment #2");
            comment2Column.setCellValueFactory(new PropertyValueFactory<>("comment"));
            comment2Column.setCellFactory(TextFieldTableCell.forTableColumn());
            comment2Column.setEditable(true);
            tableView.getColumns().setAll(idColumn, comment1Column, comment2Column);
            tableView.getItems().setAll(new Foo(), new Foo());
            final StackPane root = new StackPane();
            root.getChildren().add(tableView);
            final Scene scene = new Scene(root, 500, 500);
            primaryStage.setTitle("Test");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
     
        public static final class Foo {
     
            private static int ID = 0;
            private final int id = ID++;
            private final StringProperty comment = new SimpleStringProperty("<html><body>Lorem ipsum dolor sit amet, <b>consectetur adipiscing elit</b>. Mauris vestibulum <i>faucibus faucibus</i>. Aliquam blandit mauris vel gravida mattis. Duis porta elementum consequat. Phasellus porttitor porta leo id sodales. Pellentesque dictum dui vel bibendum vulputate. Vestibulum congue ultricies augue, at auctor risus congue sed. Nam fringilla dolor ac rhoncus dapibus. Morbi posuere, ante suscipit viverra suscipit, turpis eros convallis nibh, at eleifend mi turpis a quam.\n"
                    + "\n"
                    + "Morbi dui metus, molestie eu justo ac, tristique volutpat felis. Cras pretium diam ex, non aliquet urna pretium sit amet. Phasellus ornare erat at vulputate sodales. Aenean ullamcorper efficitur cursus. Sed sed eleifend metus, vitae laoreet turpis. Suspendisse suscipit tellus sit amet posuere tristique. In imperdiet pharetra ante a volutpat. In hac habitasse platea dictumst. Cras nec dolor consequat, feugiat nibh a, eleifend nisl. Proin efficitur tristique mauris consectetur varius. Fusce rhoncus scelerisque velit, a vulputate neque semper vel. Pellentesque ultricies ligula eu sodales lacinia. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla eu neque odio. Aliquam id sapien in mi interdum maximus. Fusce a purus vel diam tincidunt congue ut eu ante.</body></body>");
     
            public int getId() {
                return id;
            }
     
            public String getComment() {
                return comment.get();
            }
     
            public void setComment(final String value) {
                comment.set(value);
            }
     
            public StringProperty commentProperty() {
                return comment;
            }
        }
     
        private static final class FooCommentTableCell extends TableCell<Foo, String> {
     
            private final StringConverter<String> converter = new StringConverter<String>() {
                @Override
                public String toString(String object) {
                    String result = "";
                    if (object != null) {
                        result = object.replaceAll("<html><body>", "");
                        result = result.replaceAll("</body></html>", "");
                    }
                    return result;
                }
     
                @Override
                public String fromString(String string) {
                    String result = (string == null) ? "" : string.trim();
                    result = String.format("<html><body>%s</body></html>", result);
                    return result;
                }
            };
            private WebView reader;
            private TextArea editor;
     
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                Node graphic = null;
                if (!empty && item != null) {
                    if (reader == null) {
                        reader = new WebView();
                        reader.setPrefHeight(50);
                        reader.setOnMouseClicked(event -> getTableView().edit(getTableRow().getIndex(), getTableColumn()));
                    }
                    reader.getEngine().loadContent(item);
                    graphic = reader;
                }
                setGraphic(graphic);
                setText(null);
            }
     
            @Override
            public void startEdit() {
                if (!isEditable()
                        || !getTableView().isEditable()
                        || !getTableColumn().isEditable()) {
                    return;
                }
                super.startEdit();
                if (isEditing()) {
                    setupEditor();
                }
            }
     
            @Override
            public void cancelEdit() {
                super.cancelEdit();
                removeEditor();
            }
     
            private void setupEditor() {
                if (editor == null) {
                    editor = new TextArea();
                    editor.focusedProperty().addListener((observable, oldValue, newValue) -> {
                        if (!newValue) {
                            cancelEdit();
                        }
                    });
                    editor.setOnKeyReleased(event -> {
                        switch (event.getCode()) {
                            case ENTER: {
                                System.out.println(getTableView().getEditingCell());
                                event.consume();
                                final String text = converter.fromString(editor.getText());
                                commitEdit(text);
                            }
                            break;
                            case ESCAPE: {
                                event.consume();
                                cancelEdit();
                            }
                            break;
                            default:
                        }
                    });
                }
                final String text = converter.toString(getItem());
                editor.setText(text);
                setGraphic(editor);
                editor.requestFocus();
            }
     
            private void removeEditor() {
                setGraphic(reader);
            }
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre confirmé Avatar de scorbo
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 176
    Par défaut
    En effet cet exemple est plus simple que celui que j'avais qui comprenait de la généricité de partout... Je comprends mieux le fonctionnement. Merci !

    En réfléchissant à mon besoin, je ne suis plus très sûr que partir sur un tableau soit la bonne idée. En fait, j'aurai besoin de faire une mise en page de plusieurs WebView dans un gridpane car j'ai besoin de la fonction "colspan". Exemple de mise en page :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ----------------------------------
    |    Webview      |      Webview |
    |               WebView          |
    |  Webview | Webview  | WebView  |
    ----------------------------------
    Quel serait le mieux :
    - utiliser une ListView d'éléments de type HBox qui contiendrait la ou les WebView
    - essayer de créer un GridPaneView contenant des élément de type héritant de Cell (si j'en crois la doc, ça conviendrait: A "Control" is a node in the scene graph which can be manipulated by the user. Mais pourquoi ça n'existe pas déjà dans l'API ?)
    - faire un GridPane contenant des éléments supportant un mode édition (et donc changer de représentation tout comme le permet les éléments Cell) et dans ce cas, comment rafraichir les éléments lorsque lors représentation graphique change (WebView <-> TextArea) ?

    Qu'apporterait la 2ème solution par rapport à la 3ème ? En d'autres termes, qu'apporterait l'utilisation du type Cell (j'ai lu son API mais j'ai du mal à voir ce qu'elle apporte réellement) ? Est-ce que le type Cell permet de rendre plus facile le rafraichissement graphique de l'élément lorsque l'on passe en mode édition (et inversement) ?


    Merci

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    On parle bien ici de ton UI dans le cas ou tu laisses tomber la table, et non pas juste du contenu de la cellule de la table ?

    Perso, dans la mesure du possible je préfère ne pas trop empiler de contrôles (#1) les uns dans les autres et avoir juste une mise en page simple (#3). Cependant il faut savoir contrebalancer le fait qu'avoir des layout imbriqués (#1) permet parfois d'arriver plus rapidement a la solution qu'on veut sans se prendre le choux (#3 GridPane se montrant parfois euh... rétif).

    #1 pourrait aussi se faire avec un BorderPane ayant une HBox dans son top et une autre dans son bottom
    Ou une VBox... bref ce n'est pas vraiment besoin d'utiliser ListView en fait.

    Utiliser des cellules ici je n'en vois pas le besoin (même si tu pourras réutiliser une partie du code pour te créer un nouveau composants si les 6 parties doivent être éditables). L'API Cell est surtout utile pour tous les composants dits "virtualisés" (ComboBox -sa liste deroulante-, ListView, TableView, TreeView, TreeTableView) qui permettent d'afficher plein de lignes tout en utilisant un nombre minimal de cellules. Une bonne partie du code des cellules est donc consacre a la gestion des mises a jour du contenu lorsqu'on réutilise la même cellule ailleurs par exemple lors d'un défilement rapide.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre confirmé Avatar de scorbo
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 176
    Par défaut
    Oui, on parle bien de l'UI dans le cas où j'oublie la table.

    Je me rends compte que je t'ai induit en erreur. Je n'aurai pas du fermer le bas de l'UI par des tirets. L'UI est constituée de toute une liste de WebView dont chaque ligne est composée de 1, 2, 3 WebView (voir d'autres types). D'où l'idée d'une liste ou d'utiliser l'API Cell.
    Actuellement, je suis parti sur une solution plutôt (très) moche de layout imbriqués (pour l'instant l'idée est d'avancer et de faire une maquette) : j'ai une liste principale dont chaque ligne contient un Gridpane. Chaque élément à l'intérieur du Gridpane est une liste de 1 cellule avec la WebView.
    Le Gridpane me permet de faire la mise en page souhaité et les listes à l'intérieur me permettent d'utiliser l'API Cell pour passer d'un mode édition à visualisation et vice versa.

    Je me heurte à deux soucis :
    - comment régler la hauteur de la liste à la hauteur de la WebView ? Comment spécifier que la liste ne contient qu'une seule ligne ?
    - la cellule passe correctement en mode édition avec un textarea mais bizarrement, lors de la validation je sors du mode édition, mais la représentation est celle d'un simple texte (pourtant getGraphic() retourne bien un élement de type WebView). Le principe fonctionne bien avec un tableau mais pas avec la liste...

Discussions similaires

  1. TDBGRID - Couleur de fond d'une seule cellule
    Par cgo dans le forum Bases de données
    Réponses: 5
    Dernier message: 11/09/2009, 10h16
  2. Impossible d'éditer une cellule
    Par ekke dans le forum Développement
    Réponses: 2
    Dernier message: 21/05/2008, 09h45
  3. [VBA-E] Fonction sum() dans une cellule
    Par Gonzo dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 16/12/2002, 10h18
  4. [] [Excel] Fusionner des cellules
    Par SamyD dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 13/12/2002, 18h37
  5. [VBA-E] [Excel] Protection d'une plage de cellules
    Par fikou dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 20/11/2002, 11h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo