0
votes

Omis de généraliser des codes communs pour TableMECOLUMN de JAVAFX

in Cet exemple pour la View de JavaFX , le 3 instances de TableColumn font la plupart du temps la même chose. Ainsi, je voudrais écrire une nouvelle classe Supercolumn étend la tableenne pour gérer le processus de routine de TableyColumn . Par conséquent, j'ai essayé de mettre les codes communs au constructeur comme ci-dessous: xxx

dans ce qui précède, je veux setemail pour dépendre de variablenew . C'est-à-dire que si variablenew est "setemail" , nous appellerons donc setemail (t.getnewvalue ()) . Si variablenew est "setfirstname" , alors nous appellerons setfirstName (t.getNewValue ()) .

Comment peut-on J'atteins cela?

Même pour le code ci-dessus, j'ai eu un message d'erreur "La méthode setemail (V) est indéfinie pour la personne de type".


1 commentaires

Cet exemple est (et était toujours) de la merde - expose les propriétés, vous n'avez pas besoin de modifier les gestionnaires de modification. Quoi qu'il en soit, les mandats de base OO à pas étendre pour des raisons de configuration - vous êtes dans la mauvaise piste


3 Réponses :


0
votes
SuperColumn<Person, String> column = new SuperColumn<>("Email", 100, "email");

0 commentaires

1
votes

Juste en termes de style de programmation général, il n'est pas particulièrement pratique de sous-classer une classe uniquement dans le but de configurer les instances créées, à moins que vous fournissez des fonctionnalités supplémentaires qui ne soient fournies par la classe de base. Si la sous-classe ne fait rien d'autre qu'un constructeur, il s'agit d'un indicateur particulier de cet anti-motif. Une meilleure approche, que je vais montrer ici, est d'utiliser une sorte de motif créé, qui peut être aussi simple que certaines méthodes statiques qui créent des instances pour vous. (Des implémentations plus avancées utiliseraient divers modèles d'usine.)

Quoi qu'il en soit, une version de ce que vous essayez de faire, ce qui ne repose pas sur la réflexion (je vais expliquer plus tard pourquoi je n'aime pas l'approche réflexive) aurait besoin que vous puissiez passer dans une sorte de fonction qui traite la nouvelle valeur (éditée) pour une instance personne particulière. < Code> biconsumer fonctionne bien pour cela: xxx

que vous créeriez avec xxx < / Pré>

Notez que l'exemple que vous avez lié n'est pas particulièrement bon (même si c'est le "officiel" d'Oracle: c'est vraiment très vieux). Une classe de modèle ( personne ) qui utilise des propriétés JavaFX devrait vraiment fournir des méthodes "accesseur de propriété": xxx

Utilisation de cette version de la personne classe, votre colonne de table doit simplement accéder à la propriété spécifique pour obtenir la valeur (dans le CellValueFactory ) et pour définir la valeur (dans le gestionnaire ONEDITCOMMIT ). Ainsi, tout ce dont vous avez besoin est une fonction qui fournit la propriété pour une instance personne donnée. Vous pouvez également généraliser facilement cela à une valeur de ligne paramétrée de type S : xxx

et maintenant vous faites xxx < / PRE>

Cette approche évite à la fois à l'aide de la réflexion directement et à l'aide du héritage PropertyValueFactory (qui utilise une approche similaire à base de réflexion sous la hotte). Le principal avantage est que le compilateur vérifiera maintenant que les méthodes appropriées existent et toutes les erreurs sont capturées lors de la compilation. (En revanche, lors de la spécification du nom de la méthode à l'aide de la réflexion ou du nom de la propriété dans le PropertyValueFactory , les erreurs ne peuvent pas être prises par le compilateur et échoueront simplement au moment de l'exécution, soit silencieusement (aucune donnée ne figure) ni avec une exception.)

juste pour l'exhaustivité, si vous voulez vraiment utiliser une sous-classe pour cela, cela ressemblerait à xxx

mais je Devrait souligner que cela n'est pas un bon usage de l'héritage, et vous devriez préférer l'approche basée sur les méthodes (ou en usine).


8 commentaires

Voulez-vous envisager de supprimer (ou de passer à la fin avec un gros no-no-pas) l'option d'extension? ACK complet avec le reste, alors voudriez-vous uppoter :)


@ Kleopatra ouais, toujours légèrement déchiré entre répondre à la question posée, ou descendre sur quelque chose d'une tangente en termes de "meilleur design" ...


@James_d, merci beaucoup pour votre réponse. Si je ne suis pas autorisé à modifier la bibliothèque d'origine qui stocke "Tableaux", est-il toujours possible pour moi d'ajouter la méthode Créer ? Il semble que si je crée un nouveau fichier pour nappolumns , je vais écraser la définition initiale.


@ H42 Je ne comprends pas ce que tu veux dire. Tableaux est juste le nom de la classe que j'ai choisi.


@James_d, merci, j'ai déjà mélangé TAPOOLUMNS et TableColumn et maintenant je l'ai enfin obtenu. Mais cela ne fonctionne toujours pas lorsque j'ai essayé votre code, j'ai eu "la méthode consommation (personne V) n'est indéfinie pour le type Biconsumer " (bien que j'ai déjà ajouté les méthodes "Accessores de propriété" à Personne ). Avez-vous une idée de la façon de résoudre?


Désolé, devrait être accepter , pas consommer . Va réparer quand je suis de retour sur un ordinateur


C'est bon à "cacher" l'approche de sous-classement :) Quoi qu'il en soit, ne comprenez toujours pas bien l'exigence (et la solution): la principale chose qui est faite est d'installer un gestionnaire de validation personnalisé .. Ce qui n'est pas nécessaire lors de l'exposition d'une propriété. Qu'est-ce que je néglige?


@ Kleopatra Comme je le comprends, l'OP ne veut que demander "comment puis-je éviter la répétition de code".



0
votes

Enfin, j'ai réussi à combiner les idées de Lêch Hoñg Dá »¯ng (c'est-à-dire à utiliser fonction > ) et james_d (c.-à-d. Utilisation de TableyColumns. Créer () ), et j'ai eu: xxx


0 commentaires