Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Aide pour une =?iso-8859-1?q?strat=E9gie_de_programmation=2E?=

28 réponses
Avatar
bloiiing
Bonjour à toutes et à tous,



Je poste ce message car j'ai besoin d'aide pour définir une stratégie de programmation dans le cadre d'un programme que j'aimerais mettre au point en Java. Je précise que ce programme existe déjà dans un autre langage, le C++. C'est un logiciel libre sous license GNU, on peut donc l'adapter comme l'on veut.



Le logiciel en question s'appelle Plume Creator. Il sert à aider l'utilisateur à structurer ses idées pour en faire un livre, un article de presse ou de blog, un manuel d'utilisation, etc... Bref, c'est un logiciel qui sert à produire des textes. Son concept est excellent, c'est pourquoi je voudrais le reprogrammer en lui enlevant certaines options inutiles et éventuellement en en rajoutant d'autres.



La raison pour laquelle je voudrais porter ce programme de C++ à Java, c'est que le concept est en lui-même génial et fort bien pensé. Celui qui l'a écrit est lui-même écrivain, ça se devine. Mais la réalisation est inachevée et décevante à l'usage. Étant utilisateur de ce programme, je suis confronté à des pertes de données fort désagréables. Il est toujours décevant d'avoir perdu une ou deux heures de travail à cause d'un logiciel mal programmé...



Vous pouvez tester ce soft en le téléchargeant sur le site de l'auteur à http://plume-creator.eu/ . Sous Linux Ubuntu, il est installable depuis le centre d'installation des logiciels ( je ne sais pas comment ça s'appelle mais je pense que vous aurez compris ce de quoi je parle ).



Pourquoi en Java? Parceque c'est mon langage préféré et que je me sens capable de mener à bien ce projet dans ce langage.



Je voudrais dans un premier temps arriver à faire le minimum, c'est-à-dire un arbre à gauche avec l'arborescence du plan du document ( actes / chapitres que l'on doit pouvoir réordonner à volonté ), au milieu le texte proprement dit dans un JTextPane et à droite le synopsis et les notes de chaque chapitre chacun dans un JTextPane. J'aimerais de préférence arriver à faire ça sans pertes de données pour l'utilisateur. Ensuite, si je m'en suis sorti, je pourrais rajouter des options.



J'en viens donc à l'objet de ce message. J'aimerais avoir l'avis de programmeurs expérimentés en Java pour qu'on m'aide à définir une stratégie de programmation car je suis en train de m'embrouiller tout seul. J'ai des difficultés pour choisir une option de programmation.



J'ai utilisé des JTextPane pour les différents textes ( Notes, Synopsis et Corps du chapitre ). J'ai donc 3 JTextPane par chapitre. Est-ce que je dois les mettre dans un nouvel Object pour pouvoir les sauver en bloc et les restaurer à la demande? Est-ce que je peux mettre tous ces Object dans un Vector ( par exemple )? C'est le genre de questions que je me pose... Et avant de me lancer plus à fond j'aurais aimé qu'on me donne des idées pour réaliser ce programme ou du moins pour le démarrer. Je précise que je ne vais pas regarder comment ça a été programmé en C++ d'autant que je connais très mal ce langage. Je recommence de zero, from scratch... Le programme en lui-même est petit ce qui met sa réalisation à ma portée.



Je précise que le devellopement de Plume Creator s'est arëtté en 2013. C'est pourquoi je souhaite lui donner une seconde vie en Java.



Si vous avez des idées sur la façon de structurer et sauvegarder mes données, je suis preneur.



Merci d'avance.

10 réponses

1 2 3
Avatar
Yliur
Le 15 Nov 2017 03:48:52 GMT
bloiiing a écrit :
Yliur wrote:
(JTestPane) ((Chapter) (vector.getChapter())).getMainText() > >>>> jtextPane;

Là je ne vois pas bien ce que tu fais : la ligne ci-dessus ne
semble pas être du code qui fonctionne (tu ne peux pas affecter
jtextpane au résultat de getMainText()).

Si. Normalement ça doit marcher. La méthode getMainText() c'est moi
qui l'ai inventée. C'est celle qui renverra un JTextPane de l'objet
Chapter. La question que je me posais était de savoir si le fait de
mettre le symbole = permettait de faire le lien entre la
représentation graphique et le JTextPane dans le Chapter du Vector.
Je pense qque oui mais je n'en suis pas sûr. Sinon comment fait-on
pour dupliquer un objet déjà? On emploi la méthode clone()?

Non, ça ne peut pas marcher.
Une forme valable c'est ça (on associe une valeur à un nom) :
nomVariable = valeur ;
Une autre forme possible (on passe la valeur à une fonction ;
laquelle pourra faire elle-même une association pour stocker la
valeur quelque part) :
fonction (valeur) ;
par exemple :
chapter.setMainText (texte) ;
avec un corps de setMainText de cette forme :
this.mainText = texte ;
Par contre tu ne peux pas utiliser cette forme :
getMainText() = texte ;
parce que getMainText() renvoie une valeur et donc c'est de la forme
valeur = valeur ;
ce qui n'est pas possible.

Ça ne me renvoie pas une valeur mais un JTextPane. C'est pour ça que
je ne comprends pas pourquoi ce n'est pas possible. Mais bon, ce
n'est pas important. Quand je vais me lancer, je verrai bien si ça
marche ou pas...

Il vaut mieux avoir compris ce point avant de te lancer dans ton
programme java, ça va t'aider.
Dans mes explications ci-dessus, un JTextPane *est une valeur*. Si ça
te renvoie une valeur, ça ne peut pas se trouver à gauche d'un '='.
Il existe une opposition entre les variables (au sens large : variable
locale, attribut, voire paramètre de fonction), auxquelles on peut
associer des valeurs, et les valeurs elles-mêmes.
À gauche d'un symbole '=' tu peux avoir une variable/attribut/paramètre
(bien qu'on évite pour ce dernier cas, donc je l'ignore dans la suite) :
variable = ... ;
attribut = ... ;
Mais tu ne peux rien avoir d'autre à gauche d'un '='.
Donc
<un objet de type JTextPane> = ...
est une forme invalide.
De même que toute écriture de la forme
<expression renvoyant un objet> = ...
est invalide.
Donc par exemple
<appel de fonction> = ... ;
est invalide.
Je reprends le reste dans un second message.
Avatar
Samuel DEVULDER
Le 15/11/2017 à 04:48, bloiiing a écrit :
Je te comprends. Mais je compte stocker mes données dans des JTextPane
( du moins pour le texte principal ). Et j'ai envie de garder
l'interface avec une JTabbedPane qui contiendra tous les JTextPane en
cours d'édition.

Il n'est pas bon de mélanger données et composants graphiques. Que se
passera-t-il le jour où tu voudra faire passer ton appli sous Android
qui n'a pas ces JMachins ? Sans compter que tu peux être limité en
nombre de composants graphiques à disposition (penser à swt et les
handles sous windows.)
Avant de programmer quoi que ce soit, je te recommande d'étudier le
design-pattern MVC: Modèle (les données), Vue (ce qui est affiché à
l'écrann: les JMachin), et Contrôleur (la partie qui fait le lien entre
le modèle et la vue.) Maitriser le MVC est une base pour quiconque veut
faire des outils un peu gros avec une interface graphique. C'est une
façon de concevoir son programme qui est indépendant du langage. Ca
s'applique en java, en js, en C++ ou en tout ce que tu veux.
https://fr.wikipedia.org/wiki/Mod%C3%A8le-vue-contr%C3%B4leur
https://openclassrooms.com/courses/apprendre-asp-net-mvc/le-pattern-mvc
(c'est peut-être pas le meilleur cours... à toi de chercher sur internet
mieux si tu veux)
Autre remarque: dans ses déclarations de variables, toujours privilégier
l'interface la plus généraliste dont on a besoin, pas l'implémentation.
Si on veut manipuler des listes d'objets on n'écrit pas:
ArrayList<Truc> list = new ArrayList<>();
mais
List<Truc> list = new ArrayList<>();
var est déclaré comme une List, pas comme un ArrayList. On aura accès
qu'aux méthodes des listes ce qui est juste ce dont on a besoin. Ca
sépare ce qu'on veut (une liste), de son implémentation (une ArrayList,
un Vector ou que sais-je.) On utilise les fonctions d'une liste, mais on
se fiche de savoir comment c'est réalisé (avec un tableau en mémoire,
avec une base de donnée sur disk, peu importe).
Ca a plein d'avantages. Par exemple il se pourrait qu'en profilant le
code tu t’aperçoive que list.add() fini par prendre plein de temps
(normal c'est du O(n^2) ce truc). Alors tu peux remplacer les ArrayList
par un LinkedList qui fait un ajout en temps constant (O(1)) facilement:
List<Truc> list = new LinkedList<>();
Voila, et c'est tout! Pas besoin de tracer les variables du type
ArrayList dans le code pour changer leur type. Non tu y a pensé avant et
les a toutes déclarées avec l'interface la plus généraliste dont tu
avais besoin: ici une liste. Remarque: Si en fait dans le code tu
n'avais pas besoin de l'aspect ordonné des objets tu aurais utilisé une
Collectioon au lieu de List (rappel: le plus général). Si tu ne voulais
pas en plus avec deux fois le même objet dans la collection, tu aurais
utilisé un Set etc.
Bref: dans les déclarations (méthodes, variables, champs) il faut
toujours privilégier l' _interface_ la plus générale dont on ait besoin.
Ca facilite la maintenance du code en plus de montrer que tu sais ce que
tu fais quand tu programmes.
Enfin: laisse tomber les Vector, ce truc est vieux, obsolète et mal
conçu: Toutes les méthodes sont synchronisées ce qui te bouffe les perfs
pour rien. Utilises ArrayList<> à la place. Et si tu as vraiment besoin
d'accès synchronisés (ca m'étonnerait: tu ne fais pas du multithread) il
te suffit d’enrober la creation de l'ArrayList avec
https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
sam.
Avatar
Samuel DEVULDER
Le 15/11/2017 à 05:45, bloiiing a écrit :
ou des Vector<String>.

Non! Rpètes après moi "List<String>". Ce que tu veux c'est une liste pas
un truc lent, synchronisé avec des Enumeration au lieu d'Iterator
(ouais, une saleté de Vector).
Je serais chez Oracle que j'aurais fais un
# rm -f java/util/Vector.java
depuis longtemps.
Au diable la compatibilité du code source avec ce veau qu'est Vector.
L'interface ollection en java est un truc très puissant, très beau et
extrêmement bien conçu et qui existe depuis 20 ans au moins. Pourquoi
s'obstine t'on dans les cours à utiliser Vector qui n'avait qu'un seul
mérite: celui d'exister en java 1.0 alors qu'on en est au Java 8 à
présent ?!? Il faudrait que les profs d'info mettent à jours leur cours
franchement.
sam.
Avatar
Yliur
Le 15 Nov 2017 04:45:43 GMT
bloiiing a écrit :
Je viens de comprendre ce que tu veux dire par séparer les données de
l'inteface graphique. Ou du moins je pense avoir compris l'idée.
Comment t'y prendrais-tu pour sauver les textes? Dans des String, des
JTextArea, des Vector de String ou autres? Moi je les sauvegardais
dans des JTextPane mais je viens de comprendre que si je veux
effectuer un traitement sur ces données ce sera plus compliqué que
sur des String ou des Vector<String>.

C'est bien ça. Les JTextPane sont des objets graphiques, il vaut mieux
les utiliser pour les représentations graphiques mais pas pour du
stockage de données, ce sera plus simple et plus clair.
Je vais essayer de détailler/expliquer ce sur quoi j'étais parti au
début.
Il faut d'abord définir des classes permettant de stocker les données,
on ne s'intéresse pas à leur représentation graphique à ce niveau. Donc
on aurait par exemple une classe Chapitre définie comme ça (c'est
simplifié, tu auras sans doute plus d'éléments) :
public class Chapitre
{
private String titre ;
private String corps ;
}
Il doit y avoir d'autres concepts manipulés par ton programme, c'est le
moment d'en faire une liste (c'est toujours utile) : des personnages,
des lieux, ... ? Quelles sont les notions qui vont être manipulables ?
En as-tu une liste ?
Ensuite on va avoir une fenêtre pour représenter graphiquement une
liste de chapitres et un chapitre en cours d'édition. Ici aussi c'est
simplifié pour l'instant. La classe devrait ressembler à ça (pour les
composants graphiques, j'utilise une convention consistant à indiquer
leur type, puis un souligné puis leur nom ; pratique parce qu'il y a
deux informations importantes dans les composants graphiques) :
public class FenPrincipale extends JFrame
{
private JList liste_chapitres ;
private JTextField txt_titreChapitreEdite ;
private JTextPane zonetxt_corpsChapitreEdite ;
}
Note que JList est un composant graphique permettant de représenter une
liste visuellement et d'interagir avec elle, alors que plus haut
List<Chapitre> permet simplement de stocker des données (les
chapitres), sans se préoccuper de représentation visuelle.
Et pour lier le tout, on aura une classe référençant les éléments
principaux de l'application. Elle peut ressembler à ça :
public class Application
{
private List<Chapitre> chapitres ;
private FenPrincipale fenPrincipale ;
}
Note que les chapitres et autres données à venir pourraient être
regroupées dans une classe DonneesAppli, elle-même référencée dan
Application, mais on verra plus tard quand ça s'étoffera.
Côté fenêtre c'est pareil : on va sans doute avoir des panneaux et
autres, pas juste trois composants posés directement dedans, mais on
verra ça plus tard aussi, ce n'est pas nécessaire pour cette
explication .
Pour le rangement en revanche mieux vaut bien séparer les choses, ça
permet de mieux saisir leur rôle. Si src est le répertoire contenant
tes sources, ça peut se présenter comme ça :
src
donnees
Chapitre
interfacegraphique
FenPrincipale
traitements
... (ici les chargements/sauvegardes par exemple)
Application
Je te laisse nommer les choses à ta convenance, tout ça n'est qu'un
exemple.
Ça c'est pour la base de l'organisation des données, c'est très
important que ce soit clair.
Maintenant un aperçu du fonctionnement de l'ensemble, tu me diras
si c'est clair...
L'idée générale est celle-ci :
Fichier <- chargement/sauvegarde -> Données <- édition-> Fenêtre
Les étapes importantes :
- À partir d'un fichier on charge les données en mémoire (classe
Chapitre : il y aura un objet par chapitre).
La JList de la fenêtre est à ce moment remplie aussi avec les
chapitres (on verra plus tard comment la synchroniser avec la
liste de chapitres, je ne détaille pas ça pour l'instant).
=> Pour la réalisation de cette partie on verra plus tard.
- Quand on clique sur un chapitre dans la liste pour l'éditer, les
deux champs de saisie de la fenêtre vont être remplis avec les
textes issus du chapitre.
=> Il y aura quelque part (en réaction à un clic sur un élément
de la JList) un bout de code de la forme
fenPrincipale.txt_titreChapitreEdite.setText (chapitre.getTitre()) ;
fenPrincipale.zonetxt_corpsChapitreEdite.setText (chapitre.getCorps()) ;
- À ce moment l'utilisateur peut éditer les textes (ici titre et
corps) du chapitre dans les deux composants graphiques. Ces
textes sont édités uniquement dans le composant graphique, les
données du chapitre dans l'objet de la classe Chapitre ne sont
pas modifiées.
- À un moment ou un autre, les données éditées doivent être
envoyées dans l'objet Chapitre. Là c'est un choix d'ergonomie de
ta part : est-ce que l'édition de ces données doit être
annulable ? Est-ce que le texte d'un chapitre peut être visible à
différents endroits simultanément ? Est-ce qu'on peut faire des
recherches dans le texte des chapitres ? Suivant la réponse à
ces questions et quelques autres, le moment où la synchronisation
sera effectuée (l'événement qui la déclenchera) sera différent.
=> Dans les deux cas il y aura un bout de code ressemblant à ça :
chapitre.setTitre (fenPrincipale.txt_titreChapitreEdite.getText()) ;
chapitre.setCorps (fenPrincipale.zonetxt_corpsChapitreEdite.getText()) ;
- À un autre moment, à définir également, les données seront
sauvegardées dans le fichier.
=> Opération symétrique du chargement depuis le fichier, à voir
en même temps.
Est-ce plus clair comme ça ?
Pour avancer à partir de là, il faut d'une part définir les autres
données manipulées par l'application (personnages, ... ?), les
informations qui les composent (j'ai juste noté titre et corps dans
les chapitres, mais il y a sans doute d'autres choses) ; d'autre part
définir à quel moment les textes sont synchronisées entre les
composants graphiques et les données de l'application. Pour cette
deuxième partie, il y a plusieurs solutions possibles, à voir en
fonction de ce que fait le reste de l'appli ; pour l'instant on
pourrait se contenter de copier les données des composants graphiques
dans les données de l'appli quand on passe à un autre chapitre, c'est
simple à mettre en œuvre et c'est un bon exemple ; il sera toujours
temps de changer d'avis quand tu auras bien compris le principe de
fonctionnement.
Dis-moi si le fonctionnement général te paraît plus clair ou si tu
as des questions...
Avatar
bloiiing
Yliur wrote:
Il doit y avoir d'autres concepts manipulés par ton programme, c'est le
moment d'en faire une liste (c'est toujours utile) : des personnages,
des lieux, ... ? Quelles sont les notions qui vont être manipulables ?
En as-tu une liste ?

Non, pas encore mais j'ai mon idée. Et puis je pourrais en rajouter en
cours de dévellopement.
Ensuite on va avoir une fenêtre pour représenter graphiquement une
liste de chapitres et un chapitre en cours d'édition. Ici aussi c'est
simplifié pour l'instant. La classe devrait ressembler à ça (pour les
composants graphiques, j'utilise une convention consistant à indiquer
leur type, puis un souligné puis leur nom ; pratique parce qu'il y a
deux informations importantes dans les composants graphiques) :
public class FenPrincipale extends JFrame
{
private JList liste_chapitres ;
private JTextField txt_titreChapitreEdite ;
private JTextPane zonetxt_corpsChapitreEdite ;
}
Pour le rangement en revanche mieux vaut bien séparer les choses, ça
permet de mieux saisir leur rôle. Si src est le répertoire contenant
tes sources, ça peut se présenter comme ça :
src
donnees
Chapitre
interfacegraphique
FenPrincipale
traitements
... (ici les chargements/sauvegardes par exemple)
Application
Je te laisse nommer les choses à ta convenance, tout ça n'est qu'un
exemple.

Mais c'est un bon exemple. Je ne vois pas pourquoi je ferais autrement.
C'est clair.
L'idée générale est celle-ci :
Fichier <- chargement/sauvegarde -> Données <- édition-> Fenêtre

OK.
Les étapes importantes :
- À partir d'un fichier on charge les données en mémoire (classe
Chapitre : il y aura un objet par chapitre).
La JList de la fenêtre est à ce moment remplie aussi avec les
chapitres (on verra plus tard comment la synchroniser avec la
liste de chapitres, je ne détaille pas ça pour l'instant).

Les chapitres sont stockés dans une List<Chapitres>? Et la List affichée
dans une JList?
=> Pour la réalisation de cette partie on verra plus tard.
- Quand on clique sur un chapitre dans la liste pour l'éditer, les
deux champs de saisie de la fenêtre vont être remplis avec les
textes issus du chapitre.
=> Il y aura quelque part (en réaction à un clic sur un élément
de la JList) un bout de code de la forme
fenPrincipale.txt_titreChapitreEdite.setText (chapitre.getTitre()) ;
fenPrincipale.zonetxt_corpsChapitreEdite.setText (chapitre.getCorps()) ;
- À ce moment l'utilisateur peut éditer les textes (ici titre et
corps) du chapitre dans les deux composants graphiques. Ces
textes sont édités uniquement dans le composant graphique, les
données du chapitre dans l'objet de la classe Chapitre ne sont
pas modifiées.
- À un moment ou un autre, les données éditées doivent être
envoyées dans l'objet Chapitre. Là c'est un choix d'ergonomie de
ta part : est-ce que l'édition de ces données doit être
annulable ? Est-ce que le texte d'un chapitre peut être visible à
différents endroits simultanément ? Est-ce qu'on peut faire des
recherches dans le texte des chapitres ? Suivant la réponse à
ces questions et quelques autres, le moment où la synchronisation
sera effectuée (l'événement qui la déclenchera) sera différent.
=> Dans les deux cas il y aura un bout de code ressemblant à ça :
chapitre.setTitre (fenPrincipale.txt_titreChapitreEdite.getText()) ;
chapitre.setCorps (fenPrincipale.zonetxt_corpsChapitreEdite.getText()) ;
- À un autre moment, à définir également, les données seront
sauvegardées dans le fichier.
=> Opération symétrique du chargement depuis le fichier, à voir
en même temps.

Je pense qu'il faudra une action de l'utilisateur pour que les textes
des Chapitres soient sauvés dans les données et dans le fichier dans la
même opération. Je ne veux pas faire comme dans le logiciel que j'essaie
de porter en Java dans lequel la sauvegarde est automatique. Ça ce n'est
vraiment pas bon.
Est-ce plus clair comme ça ?

Oui.
Pour avancer à partir de là, il faut d'une part définir les autres
données manipulées par l'application (personnages, ... ?), les
informations qui les composent (j'ai juste noté titre et corps dans
les chapitres, mais il y a sans doute d'autres choses) ; d'autre part
définir à quel moment les textes sont synchronisées entre les
composants graphiques et les données de l'application. Pour cette
deuxième partie, il y a plusieurs solutions possibles, à voir en
fonction de ce que fait le reste de l'appli ; pour l'instant on
pourrait se contenter de copier les données des composants graphiques
dans les données de l'appli quand on passe à un autre chapitre, c'est
simple à mettre en ½uvre et c'est un bon exemple ; il sera toujours
temps de changer d'avis quand tu auras bien compris le principe de
fonctionnement.

On peut faire ça aussi, mais dans ce cas ça ne sert plus a rien d'avoir
plusieurs JTextPane ouverts en même temps. En fait je préfèrerais que ce
soit l'utilisateur qui décide de sauver et qu'il reçoive une
notification qui lui indique que le texte a été modifié quand il veut
quitter l'application seulement.
Dis-moi si le fonctionnement général te paraît plus clair ou si tu
as des questions...

Pour l'instant c'est clair. J'avais déjà commencé à programmer cette
appli, mais là je pense que je vais recommencer presque à partir de
zero. Mais je suis très content d'avoir posé cette question sur ce
groupe de discussion. En quelques jours j'ai économisé des semaines,
peut-être des mois d'errements et de prises de tête. Merci à toi.
Avatar
bloiiing
Samuel DEVULDER wrote:
Le 15/11/2017 à 05:45, bloiiing a écrit :
ou des Vector<String>.

Non! Rpètes après moi "List<String>". Ce que tu veux c'est une liste pas
un truc lent, synchronisé avec des Enumeration au lieu d'Iterator
(ouais, une saleté de Vector).

Oui, j'avais compris que les Vector sont mal vus des dévellopeurs Java.
Mais ils sont très pratiques. Toutefois, je vais essayer de m'en passer
pour cette appli.
Au diable la compatibilité du code source avec ce veau qu'est Vector.
L'interface ollection en java est un truc très puissant, très beau et
extrêmement bien conçu et qui existe depuis 20 ans au moins. Pourquoi
s'obstine t'on dans les cours à utiliser Vector qui n'avait qu'un seul
mérite: celui d'exister en java 1.0 alors qu'on en est au Java 8 à
présent ?!? Il faudrait que les profs d'info mettent à jours leur cours
franchement.

En fait, j'ai été formé il y a environ 15 ans et à cette époque on
utilisait les Vector malgré que c'était déjà mal vu. Du coup je n'ai
jamais utilisé autre chose dans les "moulinettes" que j'ai pu programmer
jusqu'à présent. C'est mon premier vrai programme. Je pense pouvoir y
arriver car il ne s'agit que de manipuler des blocs de textes. Ce n'est
pas horriblement compliqué.
Mais d'accord, exit les Vector.
Avatar
bloiiing
Samuel DEVULDER wrote:
Avant de programmer quoi que ce soit, je te recommande d'étudier le
design-pattern MVC: Modèle (les données), Vue (ce qui est affiché à
l'écrann: les JMachin), et Contrôleur (la partie qui fait le lien entre
le modèle et la vue.) Maitriser le MVC est une base pour quiconque veut
faire des outils un peu gros avec une interface graphique. C'est une
façon de concevoir son programme qui est indépendant du langage. Ca
s'applique en java, en js, en C++ ou en tout ce que tu veux.
https://fr.wikipedia.org/wiki/Mod%C3%A8le-vue-contr%C3%B4leur
https://openclassrooms.com/courses/apprendre-asp-net-mvc/le-pattern-mvc
(c'est peut-être pas le meilleur cours... à toi de chercher sur internet
mieux si tu veux)

Je vais me pencher sur ça aussi. Mais ça va me prendre du temps car je
ne fais pas ça à plein temps. Mais je vais quand-même voir.
Autre remarque: dans ses déclarations de variables, toujours privilégier
l'interface la plus généraliste dont on a besoin, pas l'implémentation.
Si on veut manipuler des listes d'objets on n'écrit pas:
ArrayList<Truc> list = new ArrayList<>();
mais
List<Truc> list = new ArrayList<>();
var est déclaré comme une List, pas comme un ArrayList. On aura accès
qu'aux méthodes des listes ce qui est juste ce dont on a besoin. Ca
sépare ce qu'on veut (une liste), de son implémentation (une ArrayList,
un Vector ou que sais-je.) On utilise les fonctions d'une liste, mais on
se fiche de savoir comment c'est réalisé (avec un tableau en mémoire,
avec une base de donnée sur disk, peu importe).

Ok. Je ne saisis pas encore très bien la nuance, mais c'est noté. Je
pense que je comprendrai à l'usage.
Ca a plein d'avantages. Par exemple il se pourrait qu'en profilant le
code tu t’aperçoive que list.add() fini par prendre plein de temps
(normal c'est du O(n^2) ce truc). Alors tu peux remplacer les ArrayList
par un LinkedList qui fait un ajout en temps constant (O(1)) facilement:
List<Truc> list = new LinkedList<>();
Voila, et c'est tout! Pas besoin de tracer les variables du type
ArrayList dans le code pour changer leur type. Non tu y a pensé avant et
les a toutes déclarées avec l'interface la plus généraliste dont tu
avais besoin: ici une liste. Remarque: Si en fait dans le code tu
n'avais pas besoin de l'aspect ordonné des objets tu aurais utilisé une
Collectioon au lieu de List (rappel: le plus général). Si tu ne voulais
pas en plus avec deux fois le même objet dans la collection, tu aurais
utilisé un Set etc.
Bref: dans les déclarations (méthodes, variables, champs) il faut
toujours privilégier l' _interface_ la plus générale dont on ait besoin.
Ca facilite la maintenance du code en plus de montrer que tu sais ce que
tu fais quand tu programmes.

Je n'avais jamais pensé à ça. Je pense avoir compris à quoi ça sert
de faire List<Truc> list = new ArrayList<>();
Enfin: laisse tomber les Vector, ce truc est vieux, obsolète et mal
conçu: Toutes les méthodes sont synchronisées ce qui te bouffe les perfs
pour rien. Utilises ArrayList<> à la place. Et si tu as vraiment besoin
d'accès synchronisés (ca m'étonnerait: tu ne fais pas du multithread) il
te suffit d’enrober la creation de l'ArrayList avec
https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

OK.
Avatar
Yliur
Le 17 Nov 2017 01:24:25 GMT
bloiiing a écrit :
Yliur wrote:
Les étapes importantes :
- À partir d'un fichier on charge les données en mémoire (classe
Chapitre : il y aura un objet par chapitre).
La JList de la fenêtre est à ce moment remplie aussi avec les
chapitres (on verra plus tard comment la synchroniser avec la
liste de chapitres, je ne détaille pas ça pour l'instant).

Les chapitres sont stockés dans une List<Chapitres>? Et la List
affichée dans une JList?

Oui.
Je pense qu'il faudra une action de l'utilisateur pour que les textes
des Chapitres soient sauvés dans les données et dans le fichier dans
la même opération. Je ne veux pas faire comme dans le logiciel que
j'essaie de porter en Java dans lequel la sauvegarde est automatique.
Ça ce n'est vraiment pas bon.

Attention, pour sauvegarder les données dans un fichier c'est comme tu
veux, mais quand tu passes de l'édition d'un chapitre à un autre les
données doivent être copiées de l'objet graphique aux données de la
classe Chapitre pour passer au suivant. Je ne vois pas de cas où
conserver une différence entre les données des Chapitre et celles de
l'objet graphique, en cours d'édition, serait intéressant.
Pour avancer à partir de là, il faut d'une part définir les autres
données manipulées par l'application (personnages, ... ?), les
informations qui les composent (j'ai juste noté titre et corps dans
les chapitres, mais il y a sans doute d'autres choses) ; d'autre
part définir à quel moment les textes sont synchronisées entre les
composants graphiques et les données de l'application. Pour cette
deuxième partie, il y a plusieurs solutions possibles, à voir en
fonction de ce que fait le reste de l'appli ; pour l'instant on
pourrait se contenter de copier les données des composants
graphiques dans les données de l'appli quand on passe à un autre
chapitre, c'est simple à mettre en œuvre et c'est un bon exemple ;
il sera toujours temps de changer d'avis quand tu auras bien
compris le principe de fonctionnement.

On peut faire ça aussi, mais dans ce cas ça ne sert plus a rien
d'avoir plusieurs JTextPane ouverts en même temps.

Il n'y a pas besoin d'avoir plusieurs JTextPane ouverts en même temps.
Sauf pour représenter plusieurs informations (texte et notes d'un
chapitre par exemple) ou si tu veux afficher plusieurs chapitres
simultanément (j'ai l'impression que le logiciel d'origine fait ça,
peut-être pour en garder plusieurs sous les yeux ?).
En fait je
préfèrerais que ce soit l'utilisateur qui décide de sauver et qu'il
reçoive une notification qui lui indique que le texte a été modifié
quand il veut quitter l'application seulement.

Oui mais ça ne concerne que la sauvegarde entre les données stockées en
mémoire (classe Chapitre) et le fichier.
Dis-moi si le fonctionnement général te paraît plus clair ou si tu
as des questions...

Pour l'instant c'est clair. J'avais déjà commencé à programmer cette
appli, mais là je pense que je vais recommencer presque à partir de
zero. Mais je suis très content d'avoir posé cette question sur ce
groupe de discussion. En quelques jours j'ai économisé des semaines,
peut-être des mois d'errements et de prises de tête. Merci à toi.

De rien :) .
N'hésite pas à commencer puis à revenir avec tes questions ou le début
de ton code.
Avatar
bloiiing
Yliur wrote:
Attention, pour sauvegarder les données dans un fichier c'est comme tu
veux, mais quand tu passes de l'édition d'un chapitre à un autre les
données doivent être copiées de l'objet graphique aux données de la
classe Chapitre pour passer au suivant. Je ne vois pas de cas où
conserver une différence entre les données des Chapitre et celles de
l'objet graphique, en cours d'édition, serait intéressant.

...
Il n'y a pas besoin d'avoir plusieurs JTextPane ouverts en même temps.
Sauf pour représenter plusieurs informations (texte et notes d'un
chapitre par exemple) ou si tu veux afficher plusieurs chapitres
simultanément (j'ai l'impression que le logiciel d'origine fait ça,
peut-être pour en garder plusieurs sous les yeux ?).

En fait, je préfererais garder l'ergonomie du logiciel d'origine sur ce
point là. Il y a 1 JTextPane par Chapitre. Le passage des données dans
la List<Chapter> se fera juste avant la sauvegarde dans un fichier. Il
faudra qu'il y ait une action de l'utilisateur pour que ça se fasse. Ça
ne sera pas automatique comme dans le logiciel d'origine.
N'hésite pas à commencer puis à revenir avec tes questions ou le début
de ton code.

Avec plaisir. Mais ça va me prendre un certain temps car je ne m'y met
pas à plein temps. Je fais ça à mes moments perdus. En tout cas un grand
merci pour ton aide et celle de Samuel. C'est exactement ce que
j'attendais lorsque j'ai posté mon premier message dans ce forum.
Maintenant j'y vois plus clair. Merci!
Avatar
Samuel DEVULDER
Le 19/11/2017 à 07:08, bloiiing a écrit :
Il
faudra qu'il y ait une action de l'utilisateur pour que ça se fasse. Ça
ne sera pas automatique comme dans le logiciel d'origine.

Quel est le problème avec la sauvegarde automatique ?
sam.
1 2 3