Comment créer un jtree modifiable et varié avec des nœuds de catégorie arbitraires / génériques?


12

Remarque: je ne veux pas d'aide sur le codage ici, je suis allumé Programmerspour une raison. Je veux améliorer mes compétences en planification / rédaction de programmes et non (seulement) ma compréhension de Java .

J'essaie de comprendre comment créer un arbre qui a un système de catégories arbitraire, basé sur les compétences répertoriées pour ce jeu LARP ici . Ma tentative précédente avait un bool pour savoir si une compétence était également une catégorie. Essayer de coder autour de ça était compliqué. En dessinant mon arbre, j'ai remarqué que seules mes «feuilles» étaient des compétences et j'avais étiqueté les autres comme des catégories.

Ce que je recherche, c'est un moyen de créer un arbre qui tente de séparer le modèle et la vue, et de permettre l'ajout d'un type arbitraire de nœud enfant (avec une manière distincte d'être édité / rendu) à un parent arbitraire.

Un arbre répertoriant diverses compétences à partir du lien ci-dessus

NB Tout ici est acheté comme une compétence, même si cela ressemble à une propriété. Les utilisateurs finaux verront cela comme des compétences d'achat (ce qu'ils font sur papier) et devraient donc être présentés comme tels, tous sur la même page.

Explication de l'arbre: L'arbre est «né» avec un ensemble de catégories de plus haut niveau codées en dur ( armes, physique et mental, médical et plus etc.). À partir de cela, l'utilisateur doit pouvoir ajouter une compétence. En fin de compte, ils veulent ajouter la compétence `` Spécialisation de l'épée à une main '' ( pas l' objet) par exemple. Pour ce faire, vous devriez idéalement cliquer sur `` ajouter '' avec la Weaponssélection, puis sélectionner One-handeddans un nœud de zone de liste déroulante qui apparaît sur cet enfant, puis cliquer à nouveau sur et entrer un nom dans un champ de texte sur ce nœud enfant qui apparaît. Cliquez ensuite sur ajouter pour ajouter / spécifier un «niveau» ou un «niveau» pour cette feuille; première compétence, puis spécialisation (par exemple).

Bien sûr, si vous voulez acheter une compétence différente, c'est un chemin complètement différent vers la feuille. Vous n'avez peut-être pas besoin d'une zone de liste déroulante au même niveau dans l'arbre que vous l'avez fait avec l'exemple de l'arme, et vous avez également besoin d'une autre logique. C'est ce que j'ai du mal à comprendre et encore moins à programmer; comment créer un ensemble de classes et ne pas spécifier dans quel ordre les attacher ensemble, mais toujours les adapter.

Quel est un bon système pour décrire ce type d'arbre dans le code? Tous les autres exemples de JTree que j'ai vus ont un schéma prévisible , et le mien ne l'est pas . Je ne veux pas avoir à coder tout cela en «littéraux», avec de longues listes de quel type (zone de liste déroulante, champ de texte, etc.) de nœud enfant devrait être autorisé sur quel parent. Dois-je utiliser des classes abstraites? Des interfaces?

Comment puis-je rendre ce type de cluster d'objets extensible lorsque j'ajoute d'autres compétences non répertoriées ci-dessus qui se comportent différemment?

S'il n'y a pas un bon système à utiliser, y a-t-il un bon processus pour savoir comment faire ce genre de chose?

Les engrenages dans ma tête tournent:

J'ai toujours besoin de:

  • Vérifiez le parent
  • Fournir des options basées sur le parent

Je commence à penser à cause de cette communauté, j'ai besoin d'une sorte de skillclasse abstraite / interface qui définit / décrit les méthodes communes de compétence et de catégorie. Je peux (espérons-le) mettre des règles et des options dans une base de données et lire à partir de là. Je pense que la question est maintenant, entre une méthode abstraite ou d'interface et comment la mettre en œuvre.


J'ai commencé (après avoir parlé à un ami) hachant une classe abstraite pour les composants de compétence dans les données, puis spécifiant les cas individuels en étendant la classe de base. L'arbre regardera simplement les données et se dessinera de manière appropriée. Je répondrai si ça marche.
Pureferret

Question: La vie est une compétence avec une propriété de "niveau" qui peut être incrémentée. Est-ce unique à Life, ou d'autres compétences peuvent-elles également être augmentées de niveau? Je peux imaginer une combinaison d'une classe abstraite et de plusieurs interfaces dans votre solution, comme une classe abstraite "Skill" ou "Category" ou "SkillNode" afin de construire votre arbre, avec un certain nombre d'interfaces, telles que "Specializable "ou" Levelable ", pour mélanger diverses fonctionnalités qui ne sont pas nécessaires pour l'arborescence. Commenter juste pour le plaisir ... j'espère que vous trouverez ce que vous cherchez!
David Kaczynski

Vous spécifiez jTree dans la question. Vous demandez comment obtenir des champs de texte et des zones de liste déroulante sous forme de nœuds, ou vous recherchez une conception non spécifique à Java?
psr

@DavidKaczynski vous avez frappé le clou sur la tête. Je vais commencer à mettre en œuvre ce genre de chose dès que possible.
Pureferret

@psr J'essaie de voir s'il existe un modèle codifié (pas nécessairement un «modèle de conception») de classes, ou sinon de le baser. DavidKaczynski est très proche de cela.
Pureferret

Réponses:


3

Exemple simple de JTree modifiable

entrez la description de l'image ici

Code (conforme et testé avec Java 7 pour créer l'image ci-dessus):

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class SimpleTree extends JFrame {
    public static void main(String[] args) {
        new SimpleTree();
    }

    public SimpleTree() {
        super("Mutable Varied JTree");
        Container content = getContentPane();
        N root = new N("Root");

        N weapons = new N("Weapons").add(
            new N("One-handed").add(
                new N("Sword").add("Proficiency", "Specialization"), 
                new N("Mace").add("Proficiency")),
            new N("Bow").add("Proficiency"));
        root.add(weapons);

        N phys = new N("Physical & Mental").add(
            new N("Life"),
            new N("Strength").add(
                "Double", "Triple", "Quadruple"));

        root.add(phys);
        N med = new N("Medical");
        med.add(new N("Bind Wounds"));
        med.add(new N("Set Broken Bones"));
        root.add(med);

        JTree tree = new JTree(root);
        content.add(new JScrollPane(tree), BorderLayout.CENTER);
        setSize(275, 300);
        setVisible(true);
    }

    private class N extends DefaultMutableTreeNode {
        public N(String s) { super(s); }
        public N add(String... strs) {
            for (String s : strs) {
                super.add(new N(s));
            }
            return this;
        }
        public N add(N... ns) {
            for (N n : ns) {
                super.add(n);
            }
            return this;
        }
    }
}

Remerciements particuliers à ce tutoriel JTree

Mise à jour: discussion des solutions possibles

Il y a un tutoriel sur la création d'un arbre dynamique , en utilisant des boutons en bas du cadre pour ajouter / supprimer / effacer des nœuds.

Pour les zones de liste déroulante et autres, vous voulez prendre des objets de la classe swing appropriée et les faire ressembler à une JComboBox qui implémente java.swing.tree.MutableTreeNode. Le Tutoriel Java Swing a une liste de contrôles .

Vous devez toujours créer un élément d'interface utilisateur pour permettre aux utilisateurs de choisir le type de nœud à ajouter et de modifier le nœud. S'ils ajoutent une zone de liste déroulante, ils devront être en mesure de définir les choix que la boîte rendra disponibles.

Vous avez besoin d'un modèle de données sous-jacent pour enregistrer vos données. Vous pouvez utiliser le schéma de sérialisation par défaut intégré à tous les objets Java, mais c'est uniquement pour le prototypage - il se cassera si vous changez un jour le code de votre programme. Vous devrez soit utiliser une base de données avec JDBC ou JPA ou vous devrez écrire vos propres routines de sérialisation (ou utiliser une bibliothèque qui gère la sérialisation pour vous) en utilisant quelque chose comme JSON ou XML comme format de stockage.

Mise à jour: solution proposée avec aperçu du projet

La solution la plus simple pourrait être d'oublier les bases de données et de trouver d'abord l'expression XML des données, puis d'éditer le fichier XML et d'afficher simplement les résultats sous la forme d'un JTree sans zones de liste déroulante spéciales ou quoi que ce soit. Je pense que c'est ce que Chibueze Opata suggérait dans sa réponse. Une représentation XML partielle de cet arbre pourrait ressembler à ceci:

<folder name="Physical &amp; Mental">
    <int name="Life">12</int>
    <drop-down name="Strength">
        <option name="Single" />
        <option name="Double" />
        <option name="Triple" />
        <option name="Quadruple" />
    </drop-down>
</folder>
<folder name="Medical">
    <text name="Bind Wounds" />
    <text name="Set Broken Bones" />
</folder>

Voici quelques jalons potentiels pour vous:

  • Créez un format de données XML ou JSON, puis écrivez un programme qui lit un fichier de ce format et l'affiche en tant que JTree sans aucune liste déroulante, juste des dossiers et des fichiers.
  • Ajoutez des commandes de swing à l'affichage JTree
  • Développez votre programme pour écrire ce même fichier
  • Créer une interface utilisateur pour que l'utilisateur puisse ajouter et modifier des nœuds à l'aide de l'interface graphique

Assurez-vous d'enregistrer une sauvegarde de votre programme chaque fois qu'il fonctionne à la fin de chaque jalon. Un système de contrôle de source installé sur une autre machine est idéal pour cela. Vous pouvez utiliser github, ou sourceforge, ou un autre contrôle de source public si cela ne vous dérange pas de partager votre code et que vous ne souhaitez pas configurer un serveur avec le contrôle de source dessus.

Chacune de ces solutions représente beaucoup de travail et est certainement plus importante qu'un projet débutant. Cela signifie que vous passerez beaucoup plus de temps à apprendre Java Swing et XML ou JSON qu'à jouer à votre LARP, c'est pourquoi j'ai d'abord exploré les options pour faire avec les outils existants. Mais la meilleure façon d'apprendre quoi que ce soit est la façon dont vous êtes le plus motivé à apprendre. Cela peut donc être un projet parfait pour vous.

J'espère que ça aide.


Salut, je suis juste sur mon téléphone, donc je ne peux pas entièrement examiner cela, mais cela ressemble à ce que je recherche, mais comme je le dis dans ma question, je dois pouvoir échanger différents types de nœuds. +1 pour être sur la bonne voie!
Pureferret

1
"DefaultMutableTreeNode fournit des opérations pour examiner et modifier le parent et les enfants d'un nœud:" docs.oracle.com/javase/7/docs/api/javax/swing/tree/…
GlenPeterson

Mon problème avec cela, Glen, est que même si cela représente un arbre potentiel, cela pourrait ne pas représenter les compétences d'un personnage. Ils doivent être en mesure de saisir le type d'arme dans un champ de texte et de sélectionner certaines options dans une zone de liste déroulante, par exemple. En ce sens, il est modifiable et autorise les enfants arbitraires . Vous avez un seul type de nœud enfant ici, N . De plus, je ne suis pas vraiment après le code (comme un bon exemple), plus un modèle de conception général pour ce genre de chose / arbre / modèle de données .
Pureferret

1
OK, donc vous voulez un programme qui permet aux gens de créer des arbres - comme un contour. Il existe déjà une vue Structure dans Microsoft Word. OpenOffice / LibreOffice Write a des fonctionnalités similaires. De quoi d'autres avez-vous besoin?
GlenPeterson

1
Je sais que je peux frotter les gens dans le mauvais sens avec toutes mes questions et je m'en excuse. Mais je dois le faire pour comprendre le problème. J'ai mis à jour la fin de ma solution ci-dessus (sous la grande rubrique "Mise à jour") avec ce que je pense être les réponses à vos questions, ou au moins des conseils sur la façon d'y répondre vous-même. J'espère que ça aide.
GlenPeterson

2

Je ne pense pas que JTree soit la bonne représentation du problème que vous essayez de résoudre. J'ai regardé votre site Web et je vois des listes de choses. C'est un bon début, mais je pense qu'il existe une conception de données sous-jacente, mais je ne vois pas.

La vie et la force me ressemblent. Double, triple et quadruple ressemblent à des valeurs pour l'attribut Force. Ensuite, je vois des compétences divisées en armes et médicales. Je considère les armes comme des possessions (que vous pouvez acheter, trouver ou déposer), et je suppose que la compétence est ce qui vous permet d'être efficace avec une arme donnée. Mais à mon avis, les armes et les médicaments n'ont pas de compétences, le personnage en a. En fait, je soupçonne fortement que le personnage est la figure centrale de votre conception de données.

Voici trois objets de données qui se distinguent jusqu'à présent de votre conception:

Character:
    Life (a value: e.g. 12)
    Strength (a value: e.g. double, triple, quadruple)
    Skills (list or set of weapon-skills, healing-skills)
    Possessions (list of weapons, armor and other possessions)
    WornArmor (maybe only wear one you possess at a time?)
    WieldedWeapon (one or two of your posessions)

Skill:
    Skill-Type (healing, manufacture, or weapon)
    RelevantWeapon (for this skill)

Weapon:
    IsOneHanded (boolean)
    IsBow (boolean)

Maintenant, un personnage peut avoir des armes et des compétences, mais pour une très bonne attaque, il a besoin d'une compétence spécifique à l'arme qu'il utilise. Dans tous les cas, il existe des relations un-à-plusieurs ici (un personnage peut avoir de nombreuses compétences). Mais je ne vois pas encore d'arbres.

Prenez un bloc de papier et sur la première page, placez le personnage au milieu de la page et listez les 5 à 10 objets les plus importants du monde du jeu qui l'entourent. Découvrez quelles données ne sont qu'un attribut d'un autre objet (comme la vie et la force étant des parties inséparables du personnage) et quelles sont les relations les plus importantes entre les objets, sans penser aux arbres ou aux champs de texte ou aux zones de liste déroulante. Tracez des lignes entre les objets pour représenter les relations. Ensuite, déterminez quelles relations sont 1: 1, qui sont 1: plusieurs et qui sont plusieurs: plusieurs et étiquetez-les. Il peut également y avoir des relations «a-a» et «est-a» et d'autres types de relations.

Vous pouvez décider que vous avez besoin de représentations distinctes pour un WeaponSkill contre HealingSkill contre ManufactureSkill. Ou vous pouvez décider qu'ils sont si similaires qu'ils appartiennent à une table de compétences (dans mon exemple ci-dessus) avec un champ déterminant de quel type de compétence il s'agit.

C'est un bon signe que vous n'êtes pas satisfait de vos tentatives jusqu'à présent - cela signifie que vous êtes prêt à envisager de nombreuses possibilités avant d'en choisir une. Plus vous envisagez de croquis, meilleure sera votre conception finale. Finalement, le meilleur deviendra votre diagramme de données. Lorsque cela est assez bien réglé, vous pouvez revenir à la réflexion sur les "zones de liste déroulante" ou les "champs de texte", mais je laisserais les décisions d'interface utilisateur à la fin.

Plutôt que de regarder JTrees, je vous suggère de vous pencher sur les sujets de structures de données, de conception de base de données et peut-être de modélisation de données. EDIT-> Ou mieux encore des diagrammes de cartographie des relations d'entité comme l'a suggéré David Kaczynski! <-EDIT Si vous obtenez la bonne conception des données, le Java et l'interface utilisateur en découleront évidemment et naturellement. Mais si vous vous trompez, aucune quantité de Java-kung-fu ou UI-beauty ne le réparera.

Bonne chance!


2

Je vais me concentrer sur le modèle objet.

Je pense que pour la flexibilité que vous voulez, vous voulez probablement séparer vos classes en une couche de connaissances (peut-être "définition" est un meilleur mot dans ce cas) et une couche de transaction. Par "calque", je veux vraiment dire les séparer logiquement dans votre tête. La couche de connaissances contient votre définition de la disposition de l'arborescence et les données qu'elle contient proviennent d'un concepteur de jeu et la couche de données stocke des choix particuliers pour un personnage particulier.

Votre niveau de connaissance sera au moins légèrement désordonné, car vous essayez de faire un jeu cool plutôt qu'un modèle mathématiquement propre.

En essayant d'organiser ce que vous avez jusqu'à présent, je pense que vous avez une classe SkillDefinition a une propriété Parent de type SkillDefinition. Vous avez également des sous-classes de SkillDefinition (qui peuvent devenir des entrées dans une table DEF_SkillType de la base de données) pour couvrir quelques cas.

"Armes", "Physique et mental" et "Médical" semblent n'avoir qu'un titre (et des compétences enfantines).

"One Handed", "Strength" et "Bind Wounds" semblent avoir une zone de liste déroulante associée (ce qui signifie quelque chose comme une table DEF_SkillChoice sur la base de données avec une clé étrangère à DEF_Skill). Sword et Bow semblent être une chaîne définie par l'utilisateur (donc pas de table associée au niveau des connaissances, mais les données seront stockées dans la couche de transaction).

"La vie" semble avoir un entier qui lui est associé. Il ne sera peut-être pas en mesure de partager cette classe avec des caractéristiques futures qui utilisent un entier, car il existe un comportement implicite sur la façon dont l'entier est incrémenté. Dans tous les cas, il a actuellement besoin de sa propre classe.

"Épée", "Arc", "Force" et "Lier les blessures" semblent tous avoir des niveaux de compétence progressive associés en dessous d'eux dans l'arbre. Dans le cas de "Sword" et "Bow", ces niveaux sont vraiment associés à leurs compétences parentales. Je pense que vous avez besoin d'une classe ProgressiveSkillDefinition avec une collection ordonnée de valeurs légales (table DEF_SkillLevel avec clé étrangère vers DEF_Skill. Au niveau de la connaissance, il n'est pas clair quelles règles vous modélisez. Si "compétence" et "spécialisation" sont toujours disponibles pour toutes les armes, vous pouvez avoir une table DEF_SkillLevel avec les enregistrements "compétence" et "spécialisation" ayant des clés étrangères à l'enregistrement "Armes".

Cela couvre ce que vous savez au niveau des connaissances. Le niveau de transaction (peut-être "niveau de caractère" serait un meilleur nom?) Indique simplement le niveau de connaissance approprié. Donc, dans votre exemple, vous auriez un objet Personnage avec un objet Compétences qui possède une collection de compétences - juste celles qu'il possède réellement.

Ainsi, le personnage aurait une compétence "Compétence" dont le parent est la compétence "épée" et dont le type est Skill_Level. Dans la base de données, l'enregistrement TRANS_SkillDefinition a une clé étrangère vers l'enregistrement de compétence transactionnelle "épée" et l'enregistrement DEF_SkillLevel de niveau de connaissance avec le nom "Proficiency".

La compétence de compétence aurait un objet parent de la compétence "épée", de type Skill_UserNamed. Dans la base de données, cela n'aurait pas de clé étrangère au niveau de connaissance, car il n'y a rien de spécial défini pour "épée" (c'est le nom de l'utilisateur). Cependant, il possède également une clé étrangère pour l'enregistrement transactionnel parent, donc plus d'informations sont disponibles via celui-ci.

L'objet de compétence "épée" a un objet parent "à une main", car l'utilisateur a choisi de mettre "épée" dans la catégorie "à une main". Il s'agit d'un objet de type SkillCategory. Dans la base de données, il possède une clé étrangère vers la table DEF_SkillChoice pour l'enregistrement "à une main", et aucun parent transactionnel car toutes les données supplémentaires pour cette compétence sont stockées au niveau des connaissances.

Lors de la construction de l'arborescence initiale d'un nouveau personnage, seul le niveau de connaissance doit être interrogé. Pour remplir les choix effectués pour un personnage, il faut le niveau transactionnel.

Vous aurez besoin de code pour traduire le modèle d'objet en arborescence, et inversement. J'espère que ce que vous devez faire doit être clair - chaque type de la couche de connaissances aura un ensemble de contrôles associé sur l'arborescence, qui obtient des données appropriées pour ce type.

Plus tard, vous voudrez peut-être des classes pour chaque choix dans les enregistrements SkillCategory, (si "Specialization" a un comportement associé, le code doit aller quelque part), mais vous n'en avez pas encore besoin pour cet arbre, et cette conception sera compatible avec ça. Il vous suffira d'avoir une usine qui utilise les informations du niveau de connaissance pour construire le bon objet.


Si cela n'est pas clair ou ne répond pas à la question, faites-le moi savoir. C'est un gros sujet et à un moment donné j'ai dû m'arrêter.
psr

C'est en fait la réponse la plus proche de ce que je veux, de ce qui me semble naturel de coder pour le système que j'émule et de ce qui pourrait fonctionner. En ce moment, mes compétences dérivent toutes d'un SkillComponent abstrait (AbSkillComponent, car je ne trouve pas de bonne convention de dénomination pour les classes abstraites), et j'ai un RootSkillComponent, SkillComponent et quelques interfaces pour faire la liste déroulante et la partie UserNamed. Je dois vous remercier d'avoir ajouté comment cela se rapporte à la base de données, quelque chose que je remets pour l'instant, mais qui mérite réflexion. Cette réponse est très bonne, et certainement une bouffée d'air frais.
Pureferret

@Pureferret - Je suppose que je vais laisser la réponse telle quelle alors - je n'étais pas sûr de savoir ce que vous cherchiez.
psr

1

Après tout, nous finissons toujours par gérer des structures hiérarchiques - que ce soit une hiérarchie de classes d'un programme, ou le programme lui-même construit à partir de différents modules vous connectant à un "monde interne" (GUI, connexion DB, logique métier liée aux données, etc.) . Mais c'est de la philosophie, comment cela devrait-il fonctionner dans votre cas?

Vous avez des nœuds dans cette arborescence, chaque élément est une "instance d'objet"; tandis que leur comportement (où vous pouvez les placer, la liste des nœuds enfants autorisés, etc.) est commun à certains ensembles, comme les "classes". Oui, c'est comme un code de programme. Si vous connaissez suffisamment la réflexion Java, vous pouvez même utiliser des classes POJO et une hiérarchie d'héritage pour créer ce composant, avec un conteneur IoC ou un mécanisme d'usine pour construire les instances réelles. Mais je pense que vous ne voulez pas cela, car c'est un hacking de langage lourd, alors ...

Créez d'abord un objet "classe" qui décrira le comportement des éléments. Celui-ci contient l'identifiant de classe, les noms de "champ" et les types et le nombre d'articles autorisés, etc. Exemple: la classe "racine" est "Propriétés du joueur", possède le champ "Physique / Mental", "Médical", "Armes". Ce type est "final": pour le moment, vous ne voulez pas avoir différents types de joueurs. Astuce: plus tard, vous pouvez le faire, en utilisant les mêmes outils pour gérer les "monstres non humains" ... :-)

Le champ "Médical" est

  • "singleton": le joueur ne peut pas avoir plusieurs informations "médicales"
  • le type enfant est fixe, seul un objet de type "Médical" peut être utilisé ici
  • obligatoire: lorsque vous créez un joueur, il doit avoir un champ "Médical"

Contrairement: un membre d'armes n'est pas requis, il doit être créé lorsque la première arme est ajoutée à votre joueur. Cela signifie: lorsque vous "éditez" votre "objet" (maintenant le joueur), et que vous souhaitez autoriser l'ajout d'un nouvel élément à celui-ci, vous ne devez pas limiter la sélection par les propriétés réelles de l'instance (qui ne contient désormais plus "d'armes"). "), mais affiche tous les champs de la définition de classe et crée paresseusement le nouveau champ (nœud enfant) lors de sa première utilisation. Cela créera un environnement extensible. Plus tard, vous pouvez ajouter le champ "Amis" avec plusieurs références de joueur ... euh ... (voir plus loin).

Suivez le processus avec les «classes» réelles. Cela vous aidera à affiner vos idées, comme: il semble préférable de séparer les types d'armes (épées, poignards, arcs, ...), à manipuler les munitions d'une manière ou d'une autre (sachant que peut-être le joueur n'a pas d'arc mais peut collecter des flèches, mais en utilisant certaines armes nécessitent et décrémentent des munitions, certaines peuvent être trouvées, d'autres sont perdues ...) sous la classe "Armes": il est plus facile de sonder, et aussi de montrer si votre joueur ne porte que cet objet ou peut l'utiliser aussi ( a les compétences). D'un autre côté: vous allez sûrement changer cette structure plus tard, au fur et à mesure que vous développez votre jeu.

Créez un «magasin de classe» disponible à l'échelle mondiale que vous initialisez au démarrage de votre jeu et servez les définitions de classe lorsque quelqu'un se réfère à son nom. Les objets de la classe def doivent être immuables dans ce cas.

Les "objets" sont plus faciles: ils peuvent être dérivés de la même classe racine qui contient une référence à la définition de classe et un accès générique aux champs également. Utilisez peut-être un HashMap pour contenir ces enfants, identifiés par le nom du champ. N'oubliez pas: certains de ces champs contiennent un seul objet, d'autres un ensemble d'objets. Ces instances sont bien sûr mutables.

Maintenant pour l'interface. Tout d'abord, vous devriez vérifier le tutoriel JTree ... , et cela devrait maintenant être évident. Chaque "objet" peut être représenté par un DefaultMutableTreeNode, le "userObject" du nœud devrait être votre objet (je pense que le toString () de ce nœud est affiché comme l'étiquette du nœud, mais vous pouvez créer un formateur de cellule personnalisé). Chaque fois que vous ouvrez un nœud, vous parcourez les champs de l'objet et créez des nœuds enfants sous le parent (si vous voulez le faire dynamiquement) - ou parcourez l'arborescence entière et créez la structure TreeNode lorsque vous affichez le JTree (indice: là est un constructeur JTree avec un paramètre TreeNode).

Lorsque vous sélectionnez un nœud dans l'arborescence, vous disposez de l'instance d'objet. Par sa classe, vous pouvez afficher un panneau d'éditeur approprié ou générique généré par la définition de classe (comme: des onglets avec les champs, des éditeurs pour le champ réel par la déclaration de champ: un bouton qui crée un enfant du type approprié vous permet de sélectionner l'une des classes disponibles et les champs de l'éditeur pour cette instance, comme les propriétés de l'arme). Après avoir modifié la structure, vous devez actualiser l'arbre lui-même - le TreeModel et ses fonctions de changement de feu ... sont vos amis.

À l'air cool? Ou trop complexe? Eh bien, c'est une petite fraction de l'histoire. Je n'ai pas parlé

  • la hiérarchie / ou la catégorisation de la définition de classe. Vous feriez mieux d'utiliser l'un d'eux lorsque vous soutiendrez l'ajout de différentes classes au même champ (comme différents types d'épées). Un pro pour la catégorisation: une classe peut avoir plusieurs catégories, pas un arbre d'héritage fixe, une bonne chose quand vous voulez collecter "toutes les compétences" d'un joueur lors de la dépense d'XP pour l'amélioration des compétences ... :-)
  • prise en charge de la persistance: vous devez créer une solution générique pour stocker la hiérarchie des objets en externe, comme dans un fichier de propriétés ou JSON. Utilisez un format lisible par l'homme, PAS de sérialisation binaire, si vous voulez garder votre cerveau en bonne forme.
  • stockage d'instance: vous vous rendrez vite compte que le "monde" de votre jeu est préférable d'être conservé au même endroit. Une certaine épée n'est PAS une propriété de votre joueur, mais une entité dans le monde dans votre jeu (le joueur peut la perdre, quelqu'un peut la trouver, etc.), donc beaucoup de ces "objets" dans votre arbre sont en fait des RÉFÉRENCES à des entités (tandis que d'autres, comme la santé du joueur, ne sont vraiment que des attributs). Vous devrez séparer les deux types, disposer d'un stockage global pour les instances pouvant résoudre les références. Cela vous épargnera également lors de la sérialisation de l'état du jeu, et plusieurs entités se réfèrent à la même autre entité (comme «l'emplacement» de plusieurs joueurs dans le même temple).
  • (et pour mentionner le véritable cerveau: la similitude du stockage de classe et du stockage d'instance; le fait que la déclaration de type peut être des instances d'objet elles-mêmes de la même manière que les composants de votre programme, les fenêtres actives, les sessions utilisateur, etc.) des maniaques comme moi.)

Quoi qu'il en soit, j'espère que vous pourrez utiliser quelque chose de cette session d'échauffement.


1

Je ne vais pas vous donner une longue réponse, mais j'ai fait face à ce genre de situation avant et franchement, j'ai renoncé à essayer d'utiliser toute structure de données existante. J'ai simplement créé mon propre objet qui pouvait accepter de nouveaux parents et enfants similaires à un nœud XML.

Dans votre cas cependant, je pense que l'utilisation d'une classe Xml vous aidera. Vous pouvez ensuite avoir des propriétés pour chaque nœud qui peuvent vous dire si une classe est une compétence et vous pouvez facilement obtenir les parents et les enfants de n'importe quel nœud que vous souhaitez utiliser dans une zone de liste déroulante ou autrement.

De plus, je voudrais ajouter que vous ne devriez pas partir de l'idée d'avoir beaucoup de textes / chaînes. Les jeux impliquent généralement l'IA, et l'IA implique généralement beaucoup de textes.


Ce jeu n'est pas joué via le programme, il présente simplement des données persistantes et une certaine logique. Je vais certainement regarder dans XML. Merci!
Pureferret
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.