Stage Martin

Objectifs de Martin durant les semaines de vacances

Journal

Lundi 14/06 :

Tentative de création d’une règle de mesure

  • J’ai ajouté un simple bouton qui permet d’exécuter une fonction de dessin dans le but de tracer une règle
  • J’ai utilisé la librairie Graphics pour tracer un trait afin de représenter la règle
  • Le dessin se fait correctement dans le panel parent de JPanelImage mais pas au sein de lui-même

Cette approche ne fonctionnera pas car Graphics (2d units) dessine sur un panel; les plots sont gérés par JFreeChart qui réalise la mise en page et surtout fait la conversion data space <=> screen space, donc il faut utiliser / adapter cette librairie pour étendre / modifier l'aspect graphique.

  • Je crois avoir compris que cette image et les outils qui l’accompagnent comme la possibilité de zoomer proviennent d’un module différent de OImaging, mais je n’arrive pas à trouver lequel

-> FitsImagePanel est dans fr.jmmc.oiexplorer.core.gui (OIFitsExplorer-core) qui possède un chartPanel. Il est possible d'intercepter la souris via EnhancedChartPanel ... Pour dessiner, il faut ajouter un Overlay (à implémenter) sur chartPanel: cf PlotChartPanel.

Pour comprendre la conversion des distances dans JFreeChart, regarde PlotChartPanel.chartMouseClicked(): cela convertit la position de la souris sur le plot en coordonnées dans l'espace des données (axis conversions).

  • J’aimerais donc savoir si pour ajouter un outil de mesure, il vaut mieux
    • l’ajouter dans le module qui gère l’affichage de l’image (OUI, colocation is better)
    • ou ajouter un panel “transparent” par dessus l’image et y lier la règle = Un Overlay qui doit réagir / intercepter la souris, comme pour le CrossHair
  • J’ai aussi tenté d’exécuter l’affichage de la règle dans un autre thread pour qu’elle s’affiche dynamiquement et pas seulement lorsque l'utilisateur clique sur un point de départ et un point d’arrivée mais ça génère une exception que je n’ai pas encore résolue

Pas de nouveau thread, please: Swing requiert de respecter l'Event Dispatcher Thread (EDT) Je te recommande de comprendre le CrosshairOverlay du PlotChartPanel, ou bien le SelectionOverlay (non finalisé) à activer (qu'en dev) en changeant PlotChartPanel.USE_SELECTION_SUPPORT = true.

Tentative de création d’une fonctionnalité de tiling

  • Pour l’instant, j’ai juste fait deux panels pouvant chacun accueillir un FitsViewerPanel
  • Rien n’a changé pour le chargement d’un premier OIFits sur le premier panel
  • Pour en afficher un second, j’ai ajouté un JPopupMenu déclenché par un clic droit sur un des modèles déjà chargé dans jListResults
  • J’ai ajouté l’option “Compare” dans le JPopupMenu mais elle ne répond pas au clic de souris, la fonction MouseClicked générée automatiquement avec le menu des events ne semble pas fonctionner. D’après ce que j’ai vu sur Internet, il faut plutôt y ajouter manuellement un MouseListener
  • Si le clic fonctionnait, un second ViewerPanel s’afficherait à côté du premier avec un OIFits précédemment chargé

Il faut implementer actionPerformed ?

    menuItem = new JMenuItem("Test option");

                menuItem.addActionListener(new ActionListener() {

                    @Override

                    public void actionPerformed(final ActionEvent e) {

                        _logger.info("e = '" + e + "'");

                    }

                });

Mardi 15/06 :

Pour la règle :

  • J’ai créé une classe RulerOverlay de la même manière que sont créées SelectionOverlay et CombinedCrosshairOverlay
  • J’ai surchargé la méthode MouseClicked pour récupérer les positions de la règle. Je récupère x1 et y1 lors du premier clic et x2 et y2 lors du second :
public void ChartMouseClicked(final ChartMouseEvent chartMouseEvent) {
    if (!isRulerActivated) {
        /* récupère les coordonnées de départ */
    else {
        /* Récupère les coordonnées d?arrivée */
        isRulerActivated = true;

Les commentaires en anglais si possible.

  • J’ai mis les fonctions de dessin dans la méthode surchargée paintOverlay avec une simple ligne pour commencer :
g2.drawLine(x1, y1, x2, y1);
  • Le problème est que je ne sais pas quand ni où appeler la fonction paintOverlay. Dans PlotChartPanel ou dans RulerOverlay ? Sachant que je veux attendre que l'utilisateur ait bien choisi les 2 points dont il veut mesurer la distance avant de dessiner.

Il faut surtout activer l'outil (toggle button ON/OFF) et ajouter ton overlay via chartPanel.addOverlay(o) et removeOverlay(o) pour afficher / cacher: c'est JFreeChart qui va faire le dessin (evenements internes), donc tu n'as pas à appeller paintOverlay() toi meme: Tu devrais télécharger le code source de JFreeChart et l'étudier pour voir quand il est appellé (ChartPanel / Overlay)... Lorsqu'un point est actif: tu peux le dessiner dans Overlay, puis la ligne quand il y en a 2: il faudrait afficher aussi la distance en texte (entre les 2)

  • J’ai essayé de la mettre après une boucle while qui attend que les deux points soient choisis mais je ne suis pas sûr que ce soit une bonne manière de faire

while(rulerOverlay.isRulerActivated)

Pour réchauffer la planete (while 1), c'est bien; mais jamais dans un code: si besoin, tu peux utiliser un java.swing.Timer (qq milliseconds) pour appeller une action de façon différée ou répétée.

Pour le tiling :

  • J’ai ajouté un ActionListener au MenuItem et ai surchargé sa méthode actionPerformed, cette fois l’ouverture d’un second panel fonctionne
  • Pour afficher l’OIFits, j’essaie de récupérer le component présent à l’endroit du clic (evt) et de l’ajouter à mon second ViewerPanel mais je ne pense pas que ce soit la bonne approche car le ViewerPanel est vide.

secondViewerPanel.add(jListResults.getComponentAt(evt.getPoint()));

jListResults contient des objets ServiceResult par exemple:

    @Override
    public void valueChanged(ListSelectionEvent e) {
...
        // This action only update GUI but not the model.
        if (e.getSource() == jListResults) {
            viewerPanel.displayResult((ServiceResult) jListResults.getSelectedValue());
            ...
        }

La méthode displayResult() te montre comment récupérer 1. OIFitsFile, puis 2. ses images (la première est affichée car OImaging ne supporte que des images 2D pour l'instant et non pas 1 cube d'images 3D):

                oifitsFile = result.getOifitsFile();
                // show first one :
                imageHdus = oifitsFile.getFitsImageHDUs();
                imageHduToShow = imageHdus.isEmpty() ? null : imageHdus.get(0);

Mercredi 16/06 :

Pour le tiling :

  • Désormais, l’affichage de l’image se fait correctement avec l’ajout de displayModel() et displayResult() cool

Dans tous les cas, il faudrait un manager (panel parent) pour gérer les 2 vues de manière cohérente (zoom, color scale, map ...) pour pouvoir comparer et pas seulement voir les images qui peuvent avoir des échelles / Fov différente... avez-vous réfléchi sur le papier comment cette ComparisonView doit se comporter ?

  • Comme l’image change lors de l’entrée dans ValueChanged (), je ne peux pas isoler le clic gauche pour afficher sur le premier ViewerPanel et le clic droit pour ouvrir mon JPopupMenu avec le MenuItem pour comparer.

C'est le principe de JList: il est possible de changer le selection mode to multiple pour avoir plusieurs elements selectionnés ou utiliser un CheckBoxList from JIDE pour avoir des cases à cocher en plus => si coché => plusieurs ResultSet actifs utiles pour la comparaison (2 premiers ou plus)

  • Est-ce possible de déplacer le code de ValueChanged () dans un MouseListener sur JListResults pour pouvoir faire telle action lors du clic gauche et telle action lors du clic droit ?*

bof, ça semble un peu tordu: essaye d'utiliser CheckBoxList ou alors il faudrait revoir ce composant (JTree ou autre ?)

Pour la règle :

  • J’ai ajouté un toggleButton pour activer ou désactiver la règle
  • Je fais addOverlay ou removeOverlay selon l’état du ToggleButton
  • Dans le paintOverlay, je vérifie d’abord si la mesure est complétée avant de tracer ma règle

if (isMesureCompleted) g2.drawLine(rulerX1, rulerY1, rulerX2, rulerY2);

  • Mon problème est que le CrosshairOverlay est toujours activé et semble prendre le dessus sur mon RulerOverlay car ce dernier ne s’affiche pas

Etrange, je ne vois pas un cross hair est activé (interne à JFreeChart). Tu peux essayer sur le plot:

        xyPlot.setDomainCrosshairVisible(false);
        xyPlot.setDomainCrosshairLockedOnData(false);
        xyPlot.setRangeCrosshairVisible(false);
        xyPlot.setRangeCrosshairLockedOnData(false);
        
        cf PlotChartPanel.configureCrosshair()
  • Faut-il faire chartPanel.removeOverlay(crosshairOverlay) ou y a-t-il une méthode dans ChartPanel permettant de donner la priorité à un Overlay par rapport à un autre ? non chaque Overlay est indépendant

Je ne vois pas pourquoi il y aurait plusieurs Overlay car seule l'image est affichée FitsImagePanel: malheureusement il n'y a pas de méthode getOverlays() ... par contre, tu peux utiliser un debugger pour voir ... (vide)

  • Quand je dis CrosshairOverlay, je veux parler de l'objet crosshairOverlay de type CombinedCrosshairOverlay. Je me trompe peut-être mais j'ai crois comprendre que c'est cette classe qui permet d'afficher un curseur pour sélectionner un point dont les coordonnées sur le plot seront affichées dans jPanelMouseInfo. C'est cet overlay dont je parle quand je dis qu'il a la priorité sur le rulerOverlay que j'essaie de mettre en place. Si ce n'est pas ça, j'ai dû mal comprendre certains points concernant le fonctionnement des overlays.

A priori, le CombinedCrosshairOverlay sert au PlotChartPanel (plot des données) alors que ton ruler doit s'afficher sur le FitsImagePanel qui n'a pas d'overlay: ton nouveau RulerOverlay doit gérer son affichage lui-meme et je ne vois pas pourquoi on aurait besoin des 2 en meme temps. Si besoin, ton RulerOverlay pourrait partager du code avec CombinedCrosshairOverlay dans une classe abstraite commune ou l'étendre ... mais c'est pas clair. Enfin, si tu veux afficher des informations issues du RulerOverlay (rulerX1, rulerY1, rulerX2, rulerY2) , il faudra gérer cela dans le panneau principal. Un Overlay correspond juste à un calque par dessus le plot pour dessiner, mais il est possible d'avoir des notifications aussi:

    public interface Overlay {
    public void paintOverlay(Graphics2D g2, ChartPanel chartPanel);

    public void addChangeListener(OverlayChangeListener listener);

    public void removeChangeListener(OverlayChangeListener listener);
}

Jeudi 17/06 :

  • Je m’étais en effet trompé sur la classe qui devait posséder la règle OK, ça explique tes problèmes.
  • J’ai donc mis un ToggleButton dans FitsImagePanel et gère ses actions avec une fonction ItemStateChanged ()
if (evt.getStateChange() == ItemEvent.SELECTED) {
            chartPanel.addOverlay(rulerOverlay);
        }
        else {
            chartPanel.removeOverlay(rulerOverlay);
        }

Donc cela permet de peindre par dessus le plot chart panel

  • Pour gérer les évènements qui arrivent dans rulerOverlay, j’ai surchargé certaines méthodes dans ma classe RulerOverlay
    • chartMouseClicked(...) qui récupère les coordonnées du premier et du second clic de souris pour définir les coordonnées de ma règle

Cette méthode est interessante mais n'est pas déclarée dans Overlay; donc jamais appellée par le framework JFreeChart: Overlay = calque pour dessiner seulement.

Pour vérifier qu'elle bien appellée: dessine un rectangle rouge (debug) dans paintOverlay() ... c'est surement lié aux coordonnées ou que les positions de la regle ne sont pas définies...

Actions: - Doc / outil diagrammes de classes - Codes sur github

Vendredi 18/06 :

  • L'overlay se met bien en place, j'ai essayé avec un rectangle rouge et il s'affiche correctement
  • J'ai ajouté un MouseListener et ma méthode surchargée chartMouseClicked répond bien
  • L'affichage de la règle se fait correctement, il faut désormais que j'arrive convertir ses coordonnées en coordonnées du plot

Excellent cf SelectionOverlay pour convertir screen (mouse or drawLine) <=> data units (ruleX, ruleY), cela permet d'avoir la règle affichée qqsoit le zoom appliqué

Lundi 21/06 :

  • La conversion des coordonnées se fait correctement, j'ai pu reporter la valeur de la mesure dans l'overlay

Mercredi 23/06 :

  • Création d'un dépôt distant sur le gitlab du CRAL (https://git-cral.univ-lyon1.fr/pratoussy/internship-project/)
  • Ajout de la mesure de l'angle avec la règle
  • J'essaie aussi de transformer le panneau des résultats en une JTable interactive en transformant JListResults en JtableResults mais il faut encore un peu de temps pour je comprenne comment fonctionne les tableaux avec Swing*

Jeudi 24/06 :

  • Voilà à quoi pourrait ressembler un tableau à la place d'une liste
Results table

Une telle table pourrait être interessante pour un affichage détaillé... colonnes à définir. Ou placer cette table dans l'interface (à gauche, c'est petit): en bas en pleine largeur, comme une table de données ?

LBO: peux-tu mettre des captures d'écrans de OImaging (complet) pour la règle, le tiling, la table ?

  • Fenêtre avec le tableau
Table

  • Fenêtre avec le tiling et la règle
Tiling+Ruler

Vendredi 25/06 :

  • J'ai ettofé ma classe ResultsTable en ajoutant un TableCellRenderer personnalisé qui permet d'ajouter des boutons (ou n'importe quel autre component) dans la table
  • Au lieu de convertir les éléments de la JList en lignes de tableau comme je pensais le faire au début, j'ai préféré essayer de récupérer l'index sélectionné dans le tableau et récupérer l'élément de la JList positionné au même index. Il faut encore que j'associe le tableau à la JList pour qu'une ligne de tableau soit créée quand on clique sur Run.

Beam

On pourrait afficher sur l'overlay une ellipse (aka le beam) dont la taille représente un élément de résolution de l'interferometre comme dans ce papier de Jacques:

A mettre en vis-a-vis de la couverture du plan (u,v):

Mardi 29/06 :

J'ai implémenté la conversion des données du plot en coordonnées à l'écran d'après le code que j'ai vu dans SelectionOverlay et CombinedCrosshairOverlay. La règle garde donc bien ses proportions lors du zoom.

Mercredi 30/06 :

  • J'ai modélisé une fenêtre qui permettrait une édition plus complète des résultats. Ce panel serait accessible via un bouton "Edit" ou "Advanced" placé à côté du tableau de résultat actuel. Ce n'est pas encore très complet mais est-ce que ça se rapproche du résultat recherché ?

  • Pour le slider ou l'animation qui permet de voir l'image à différentes longueurs d'onde, dans quelles classes de quels modules faut-il que je regarde pour comprendre comment fonctionne l'affichage multispectral ? Pour l'instant, j'ai trouvé quelques infos intéressantes dans la classe UVCoveragePanel de Aspro2.
    • effectivement les classes sont seulement dans Aspro2 : à reprendre pour généraliser et améliorer ? il faut aussi revoir la dépendance à la classe UserModel spécifique à Aspro2 ?
    • Dans Aspro2, plusieurs instances de UserModel (1 max par Target) peuvent être chargés (plusieurs cubes d'images sont référencés par leur nom de fichier), donc il faut gérer le contexte courant
    • La classe TargetModelForm implemente un UserModelAnimatorListener.perform(String userModelFile, int imageIndex) qui permet de traiter l'image indiquée par son index. Dans ce cas, l'image est changée par fitsImagePanel.setFitsImage(this.currentUserModel.getModelDataList().get(imageIndex).getFitsImage()), donc c'est externalisé du FitsImagePanel (gestion externe)
    • La classe UserModelAnimator gère l'animation, c'est à dire iterer sur les images avec un Timer régulier qui invoque les listeners (multiples dans ASPRO2) via notifyListeners() : il serait possible de gérer ici l'image courante et des actions prev/next ?
    • La classe AnimatorPanel représente le widget swing pour controler l'animation (On/off pour l'instant et réglage via slider de la vitesse d'animation)
    • Finalement, UVCoveragePanel implémente aussi UserModelAnimatorListener pour afficher de manière synchronisée la transformée de fourier de l'image dans le plot du plan UV complet.

Vendredi 02/07

  • Si j'ai bien compris, un fichier OIfits contient les données d'une observation interférométrique. Il doit comporter une seule et unique target observée dans une ou plusieurs longueurs d'onde comme dans cet exemple : http://oidb.jmmc.fr/search.html?perpage=25&public=yes&collection=~19f7e2cf-2a03-4bb2-b7e2-cf2a03bbb245&order=t_min&caliblevel=1%2C2%2C3
  • OIfits PI GRU
  • Comme il y a deux HDUs OI_WAVELENGTH, je suppose que l'observation s'est faite dans deux longueurs d'onde différentes.
  • Si c'est bien comme cela que ça fonctionne, comment faire une animation multispectrale ?
    • Reconstruire plusieurs OIfits de la même étoile où chaque OIfits est une observation de cette étoile à une longueur d'onde spécifique ?
    • Ne rendre l'animation possible que lorsque l'OIfits contient plusieurs OI_WAVELENGTH et donc l'animation ne se ferrait qu'au sein de la reconstruction d'image d'un OIfits unique ?
  • J'ai trouvé ce document sur la structure d'un OIfits : https://arxiv.org/pdf/1510.04556.pdf. Mais je n'arrive pas encore bien à comprendre la nature de chaque champ.
    • OI_TARGET : coordonnées et informations sur la cible je suppose ?
    • OI_ARRAY : informations du/des téléscope(s) ?
    • OI_WAVELENGTH : caractéristiques du détecteur ? Longueur d'onde à laquelle il capte la lumière ?
    • OI_VIS et OI_VIS2 : amplitude et phase des ondes captées ?
    • OI_T3 : quelque chose de similaire à OI_VIS et OI_VIS2 ?
    • et d'autres tables optionnelles (OI_FLUX, OI_CORR, OI_INSPOL)
  • Que font les algorithmes avec ces données ? Quel est la différence entre WISARD, MIRA, BSMEM et SPARCO ?
  • Aucun rapport mais j'ai rajouté la possibilité de déplacer manuellement les points de la règle en (j'ai implémenté une méthode mouseDragged), il y a encore quelques petits bugs mais ils seront vite réglés.

Github: dépot créés et synchronisés sur https://github.com/JMMC-OpenDev/

Le projet jmmc-java-build permet de récupérer tous les modules (java) nécessaires afin de reconstruire tous les logiciels Java.

Voir https://github.com/JMMC-OpenDev/jmmc-java-build/blob/main/get_modules.sh

Martin, il faudrait que tu essayes de cloner les dépots à modifier afin de proposer des Pull Requests depuis ton fork -> JMMC-OpenDev.

Lundi 05/07

  • J'ai créé une première Pull request pour voir si ça marche bien. J'ai juste ajouté la règle pour l'instant, elle ne devrait pas poser de problème au reste du code.
  • En voyant les remarques de Laurent, je me rend compte que je n'ai pas mis la bonne version de mon code dans la Pull request. J'ai déjà corrigé certains de ces problèmes. Je vais revoir mon code et refaire une Pull request.

Mardi 06/07

  • J'ai refait une Pull request avec la dernière version de mon code.

Mercredi 07/07

  • J'ai ajouté le slider qui permet de parcourir un cube d'image dans FitsImagePanel. Cependant, je ne suis pas convaincu par la conception de mon code.
    • A chaque fois que le slider change de valeur je vais rechercher dans l'image actuelle le FitsImageHDU qui contient les FitsImages
private void jSliderFitsCubeStateChanged(javax.swing.event.ChangeEvent evt) {
this.setFitsImage(
this.fitsImage.getFitsImageHDU().getFitsImages().get(jSliderFitsCube.getValue())
);
}

    • Une fois dans la méthode setFitsImage, je redéfini la taille du slider et le réaffiche
public void setFitsImage(final FitsImage image) {
this.fitsImage = image;
if (fitsImage = null && fitsImage.getImageCount() > 1) {
jSliderFitsCube.setVisible(true);
jSliderFitsCube.setMaximum(fitsImage.getImageCount() - 1);
}
else jSliderFitsCube.setVisible(false);
refreshPlot();
}

  • J'aimerais ne pas avoir à redéfinir le slider à chaque fois qu'il change de valeur et ne pas avoir aller chercher getFitsImageHDU().getFitsImages() à chaque fois qu'il change d'état.
C'est pas si génant. Tu veux dire qu'il manque un moyen de voir si le FitsImageHDU (parent du FitsImage) a changé pour rafraichir le slider ?

Le FitsImagePanel sert à afficher 1 image (FitsImage) à la fois (zoomer ...), pour être utilisé plusieurs fois pour montrer plusieurs images en meme temps. Si chaque panel a son slider, cela va devenir compliqué => c'etait externalisé dans Aspro2 avec les classes Animator ... pour synchroniser les différents panneaux d'affichage (TargetModelForm et UVCoveragePanel).

Si tu veux gérer l'iterateur / état, il faudrait le faire en dehors çàd quand le FitsImageHDU change => ViewerPanel (Oimaging).

Tu peux ajouter un JPanel optionnel (slider ?) à afficher, par ex: this.fitsImagePanel.addOptionPanel(this.animatorPanel);

  • Or, je crois avoir compris que FitsImagePanel ne charge qu'une seule image et qu'il n'existe pas d'attribut possédant l'intégralité des images du fits chargé dans cette même classe.
fitsImage.getFitsImageHDU() est juste un getter, donc tu peux l'utiliser pour connaitre si l'image courante fait partie d'un cube ...

  • Je vois deux solutions au problème :
    • Soit j'accède au slider directement depuis le Viewerpanel en implémentant un getter GetSliderValue() dans FitsImagePanel. Comme l'attribut FitsImageHDU est présent, ça éviterait d'avoir à aller le chercher depuis l'image chargée. Je ferais une méthode similaire à displaySelection() qui permettrait l'affichage de plusieurs images.
Tout est préchargé en mémoire => objets FitsImageHDU avec 1..n FitsImage.

Est-ce que ton slider pourrait être inclus dans AnimatorPanel ou reprendre cette approche à généraliser dans oiexplorer-core (refactoring de code dans Aspro2) ?

    • Soit je crée une nouvelle classe FitsImageCubePanel dérivée de FitsImagePanel qui serait faite uniquement pour les fits avec plusieurs images et qui intégrerait un attribut FitsImageHDU.
Pas compris: fitsImage.getFitsImageHDU() est fait pour cela, pas besoin d'une classe pour cela ?

Regarde aussi le code Aspro2, expliqué avant pour voir les similitudes / différences:

Le fond du problème est de trouver où gérer l'état métier / itérateur (FitsImageHDU, position)

Lundi 12/07

Lundi 23/08

  • Pour le tableau, au lieu de récupérer les valeurs directement depuis les objets ServiceResult, je vais les chercher dans les objets HeaderCard (ServiceResult.getOifitsFile().getImageOiData().getOutputParam().getHeaderCards()).
  • Pour pouvoir afficher tous les paramètres de toutes les reconstructions, j'essaie de faire une liste qui rassemble tous les headers présents dans les HeaderCard de chaque reconstruction.
  • Les cellules présentes dans les colonnes qui ne seront pas communes seront grisées si le paramètre n'existe pas.
  • Je créerai aussi un bouton qui ouvrira une nouvelle fenêtre dans laquelle on pourra paramétrer l'affichage du tableau.
  • Comme on en avait parlé jeudi, j'ai aussi fait en sorte que si on clique sur Compare alors qu'aucune ligne n'est sélectionnée, tous les résultats sont ajoutés à la comparaison

Vendredi 27/08

  • Pour afficher et cacher mes colonnes, je n'ai trouvé d'autres solutions que de redéfinir la taillle de la colonne.
LBO: j'ai regardé dans SearchCal: c'est son TableSorter (dont dérive BasicTableSorter dans jmcs) qui a role de filtrer les colonnes dans le model (voir méthode computeColumnsIndirectionArray); il faudrait généraliser cette approche dans le BasicTableSorter: en lui donnant une List<String> correspondant aux identifiants de colonnes; il faut alors re-générer le mapping _viewIndex (int <-> int) qui donne l'index de colonne en sortie vs l'index de colonne du TableModel originel... à regarder et demande si c'est pas clair; ensuite le mapping des colonnes est utilisé quand on veut récupérer la valeur d'une cellule, voir: TableSorter.getValueAt()

  • J'ai déplacé la méthode d'affichage de l'éditeur du tableau de MainPanel vers TablePanel. J'ai voulu faire de même pour certains autres éléments mais ils agissent sur des objets externes à TablePanel.
    • J'ai essayé d'utiliser le singleton MainPanel directement depuis TablePanel mais pour récupérer les valeurs dont j'ai besoin, il faut mettre des getters.
    • Je ne sais donc pas s'il vaut mieux laisser le code dans MainPanel ou le déplacer dans TablePanel tout en créant des getters.
LBO: il est toujours préférable d'encapsuler... si besoin, il faut ajouter des méthodes métier dans MainPanel ...

Peux-tu détailler les objets et méthodes dont tu as besoin pour tes boutons ?

  • Pour le bouton de comparaison, j'ai besoin d'accéder à mon modèle de table pour récupérer les index des valeurs affichées, le MainPanel pour récupérer les valeurs de la liste de ServiceResult associés à ces index et au ViewerPanel là où je souhaite afficher mes images.
  • Voilà le code :
List<ServiceResult> resultsToCompare = new ArrayList<>();
if (jTablePanel.getTable().getSelectedRows().length == 0) {
resultsToCompare.addAll(resultSetList);
}
else {
for (Integer index : jTablePanel.getTable().getSelectedRows()) {
resultsToCompare.add(resultSetList.get(index));
}
}
viewerPanel.displayGrid(resultsToCompare);

  • Je remarque déjà que je pourrais récupérer directement les ServiceResult depuis le modèle au lieu de ne récupérer que les index pour les associer ensuite avec la liste du MainPanel. Ca enlèverait déjà au MainPanel une responsabilité non nécessaire.
  • Il y a toujours ce soucis de resultsetlist dont je n'ai aucune idée de comment elle est remplie.
  • Pour le bouton de suppression, j'utilise le même procédé pour récupérer les ServiceResult : je prends les index dans le modèle et je trouve le ServiceResult associé dans le MainPanel. Là encore, je pourrais récupérer les valeurs directement depuis le modèle. Et je supprime enfin la valeur sélectionnée dans le currentModel.
JTable table = jTablePanel.getTable();

if (table.getSelectedRowCount() = 0) {
List<Integer> rowsToDelete = Arrays.stream(table.getSelectedRows()).boxed().collect(Collectors.toList());
Collections.reverse(rowsToDelete);
rowsToDelete.forEach((Integer index) -> {
BasicTableSorter sorterModel = (BasicTableSorter) jTablePanel.getTable().getModel();
currentModel.removeServiceResult(resultSetList.get(sorterModel.modelIndex(index)));
});
}

LBO: J'ai corrigé toute l'encapsulation OO et la gestion de la selection (get / set all usages):
Voir mon patch: https://github.com/JMMC-OpenDev/oimaging/pull/2/commits/8dc14f9b06523c899fd8eb11bb0928aded64dd06

Edit | Attach | Watch | Print version | History: r30 < r29 < r28 < r27 < r26 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r30 - 2021-08-27 - LaurentBourges
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback