Package freegressi.graphics

Source Code of freegressi.graphics.JDialogEditCurves$DeleteCurveAction

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    Copyright (C) 2011-2013  Marchand Eric <ricoh51@free.fr>
   
    This file is part of Freegressi.

    Freegressi is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Freegressi is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Freegressi.  If not, see <http://www.gnu.org/licenses/>.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package freegressi.graphics;

import freegressi.tableur.Colonne;
import freegressi.tableur.SpreadSheets;
import freegressi.tableur.Tableur;
import freegressi.utils.Utils;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.TitledBorder;

/**
* La boite de dialogue qui permet d'éditer les courbes
* @author marchand
*/
public class JDialogEditCurves  extends JDialog implements ActionListener {
  /** Action d'ajouter une courbe */
  private AddCurveAction addCurveAction = new AddCurveAction(null,
          new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/Crystal_Clear_action_edit_add-48.png")),
          "Ajouter une courbe", 0);
  /** Action de supprimer une courbe */
  private DeleteCurveAction deleteCurveAction = new DeleteCurveAction(null,
          new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/Gnome-edit-delete-24.png")),
          "Supprimer cette courbe", 0);
 
  /** le bouton Ok de sortie du dialogue */
  private JButton jbOk;
  /** le bouton Annuler de sortie du dialogue */
  private JButton jbAnnuler;
  /** Flag qui permet de savoir si l'utilisateur est sorti par le bouton Ok */
  private boolean ok = false;
  /** Le JTabbedPane dans lequel on place différents les panneaux */
  private JTabbedPane jtp;
  /** Le tableau des images des styles de points */
  private ImageIcon[] iconPoints;
  /** Le tableau des textes associés aux images des styles de points */
  private String[] textPoints;
  /** Le tableau des images des styles de lignes */
  private ImageIcon[] iconLines;
  /** Le tableau des textes associés aux images des styles de lignes */
  private String[] textLines;
  /** Le panneau des réglages généraux */
  private JPanelGeneral jpgene;
  /** Le panneau de réglage de l'abscisse (unique) des courbes */
  private JPanelAbscissa abscissaPanel;
  /** Le panneau de la liste des courbes */
  private JPanel  curvesPanel;
  /** Le panneau de la liste des axes */
  private JPanel  axisPanel;
  /** Le panneau qui contient abscissaPanel curvesPanel et axisPanel */
  private JPanel  editCurvesPanel;
  /** La liste des panneaux de courbes */
  private List<JPanelCurve> panelCurves = new ArrayList<>();
  /** Les 4 panneaux d'axes */
  private JPanelAxis bottom, top, left, right;

  /**
   * Constructeur
   * @param parent la frame appelante
   * @param graphicStyle le GraphicStyle qui permet d'initialiser les
   * champs du dialogue
   */
  public JDialogEditCurves(JFrame parent, GraphicStyle graphicStyle) {
    super(parent, true);
    setTitle("Éditer les courbes");
    createUI(graphicStyle);
    setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);
    pack();
    setLocationRelativeTo(null);
    jtp.setSelectedIndex(1);
  }

  /**
   * Crée le panneau réglant les différents courbes
   * @param graphicStyle
   */
  private void createCurvesPanel(GraphicStyle graphicStyle){
    curvesPanel = new JPanel();
    curvesPanel.setLayout(new BoxLayout(curvesPanel, BoxLayout.Y_AXIS));
    for( Curve curve : graphicStyle.getCurves()){
      addCurvePanel(curve);
    }
    curvesPanel.setBorder(new TitledBorder("Courbes"));
    curvesPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
  }
 
  /**
   * Crée le panneau réglant l'abscisse du graphique
   * @param graphicStyle
   */
  private void createAbscissaPanel(GraphicStyle graphicStyle){
    abscissaPanel = new JPanelAbscissa(this, graphicStyle);
    abscissaPanel.setBorder(new TitledBorder("Abscisse"));
    abscissaPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
  }
 
  /**
   * Crée une liste de noms de variables dont l'axe est à la position
   * "position"
   * @param position la position de l'axe
   * @return la liste des noms de variable
   */
  private List<String> getNamesAtPosition(Position position){
    List<String> names = new ArrayList<>();
    if (abscissaPanel.getAbscissaPosition() == position){
      names.add(abscissaPanel.getAbscissaName());
    }
    for (JPanelCurve jpc : panelCurves){
      if (jpc.getPosition() == position){
        names.add(jpc.getCurveName());
      }
    }
    return names;
  }
 
 
  /**
   * Affecte de nouvelles valeurs au min et max d'un axe. Les valeurs sont
   * formattées en fonction du nombre de chiffres significatifs
   * @param jpa l'axe à modifier
   * @param min la nouvelle valeur du min
   * @param max la nouvelle valeur du max
   */
  private void changeMinMax(JPanelAxis jpa, double min, double max){
    // Pas moyen de formatter le min lorsqu'il n'y a aucun point, le min
    // vaut Double.MAX_VALUE et est arrondi à ∞ qui provoque une exception!
    // idem pour le max
    int CS = SpreadSheets.getInstance().getCS();
    String minStr = Utils.formatteNombre(min, CS);
    minStr = Utils.replaceVirguleToPoint(minStr);
    try{
      Double.parseDouble(minStr);
      jpa.setMin(minStr);
    } catch (NumberFormatException e){
      jpa.setMin(Double.toString(min));
    }
    String maxStr = Utils.formatteNombre(max, CS);
    maxStr = Utils.replaceVirguleToPoint(maxStr);
    try{
      Double.parseDouble(maxStr);
      jpa.setMax(maxStr);
    } catch (NumberFormatException e){
      jpa.setMax(Double.toString(max));
    }    
  }
 
  /**
   * Un nom (d'abscisse ou de courbe) vient de changer
   * @param newName le nouveau nom
   * @param position la position de l'axe correspondant
   */
  public void notifyNameChanged(String newName, Position position){
    Tableur sheet = SpreadSheets.getInstance().getActiveSheet();
    Colonne col = sheet.donneColonne(newName);
    double min = col.getMin();
    double max = col.getMax();
    JPanelAxis jpa = bottom;
    switch (position){
      case BOTTOM : jpa = bottom; break;
      case TOP : jpa = top; break;
      case LEFT : jpa = left; break;
      case RIGHT : jpa = right; break;
    }
    changeMinMax(jpa, min, max);
    jpa.setScaleAuto(true);
  }
 
  /**
   *
   * @param pos
   * @return
   */
  private String createAxisText(Position pos){
    String str = "";
    for (JPanelCurve jpc : panelCurves){
      if (jpc.getPosition() == pos){
        if (!str.equals("")){
          str += ", ";
        }
        str += jpc.getCurveName();
      }
    }
    return str;
  }
 
  /**
   * Trouve le JPanelAxis correspondant à la position
   * @param pos la position
   * @return le JPanelAxis
   */
  private JPanelAxis getJPanelAxis(Position pos){
    switch (pos){
      case BOTTOM : return bottom;
      case TOP : return top;
      case LEFT : return left;
      case RIGHT : return right;
    }
    return bottom;
  }
 
  /**
   * Donne la position d'un JPanelAxis
   * @param jpa
   * @return
   */
  private Position getPosition(JPanelAxis jpa){
    Position position = Position.BOTTOM;
    if (jpa == bottom){
      position = Position.BOTTOM; 
    } else if (jpa == top){
      position = Position.TOP;
    } else if (jpa == left){
      position = Position.LEFT;
    } else if (jpa == right){
      position = Position.RIGHT;
    }
    return position;
  }
 
 
  /**
   * La position de l'abscisse a changé, il faut rendre visible le
   * nouvel axe et cacher l'ancien.
   * @param pos
   */
  public void notifyAbscissaPositionChanged(Position pos){
    bottom.setVisible(pos == Position.BOTTOM);
    top.setVisible(pos == Position.TOP);   
    double min, max;
    boolean auto;
    String title;
    if (pos == Position.BOTTOM){
      min = top.getMin();
      max = top.getMax();
      auto = top.isScaleAuto();
      title = top.getText();
      bottom.setAll(min, max, auto, title);
    } else {
      min = bottom.getMin();
      max = bottom.getMax();
      auto = bottom.isScaleAuto();
      title = bottom.getText();
      top.setAll(min, max, auto, title);     
    }
    pack();
  }
 
  public void update(){
    reCalculateAbscissaAxis();
    reCalculateCurvesAxis();
    notifyMinMaxChanged();

  }
 
  private void reCalculateAbscissaAxis(){
    String name = abscissaPanel.getAbscissaName();
    Tableur sheet = SpreadSheets.getInstance().getActiveSheet();
    Colonne col = sheet.donneColonne(name);
   
   
    if (bottom.isVisible()){
      if (bottom.isScaleAuto()){
        changeMinMax(bottom, col.getMin(), col.getMax());
      }
    }
    if (top.isVisible()){
      if (top.isScaleAuto()){
        changeMinMax(top, col.getMin(), col.getMax());
      }     
    }
  }
 
  /**
   * Quelquechose a changé, il faut mettre à jour les axes left et right.
   *
   */
  private void reCalculateCurvesAxis(){
    boolean l = false, r = false;
    double minL = Double.MAX_VALUE, maxL = Double.MIN_VALUE, min;
    double minR = Double.MAX_VALUE, maxR = Double.MIN_VALUE, max;
    String name;
    Colonne col;
    Tableur sheet = SpreadSheets.getInstance().getActiveSheet();
    boolean leftWasVisible = left.isVisible(), rightWasVisible = right.isVisible();
    boolean changeLeftMinMax = true, changeRightMinMax = true;
    for (JPanelCurve jpc : panelCurves){
      name = jpc.getCurveName();
      col = sheet.donneColonne(name);
      min = col.getMin();
      max = col.getMax();
      if (jpc.getPosition() == Position.LEFT){ // Axe de gauche
        l = true;
        if (!leftWasVisible){
          left.setScaleAuto(true);
          leftWasVisible = true;
        }
        if (left.isScaleAuto()){
          if (min < minL){ minL = min; }
          if (max > maxL){ maxL = max; }         
        } else {
          if (leftWasVisible){ // laisse les min et max sans les toucher
            changeLeftMinMax = false;
          }
        }
       
      } else if (jpc.getPosition() == Position.RIGHT){ // Axe de droite
        r = true;
        if (!rightWasVisible){
          right.setScaleAuto(true);
          rightWasVisible = true;
        }       
        if (right.isScaleAuto()){
          if (min < minR){ minR = min; }
          if (max > maxR){ maxR = max; }         
        } else {
          if (rightWasVisible){ // laisse les min et max sans les toucher
            changeRightMinMax = false;
          }
        }
      }
    }
    left.setVisible(l);
    right.setVisible(r);
    if (l && changeLeftMinMax){
      changeMinMax(left, minL, maxL);
      left.setText(createAxisText(Position.LEFT));
    }
    if (r && changeRightMinMax){
      changeMinMax(right, minR, maxR);
      right.setText(createAxisText(Position.RIGHT));
    }
  }
 
  private void createAxisPanel(GraphicStyle gs){
    axisPanel = new JPanel();
    axisPanel.setBorder(new TitledBorder("Axes"));
    axisPanel.setAlignmentX(Component.LEFT_ALIGNMENT)
    axisPanel.setLayout(new BoxLayout(axisPanel, BoxLayout.Y_AXIS));
    JPanelAxis jpa;
    bottom = new JPanelAxis(this, "Bas", 0.0, 0.0, true, "");
    axisPanel.add(bottom);
    top = new JPanelAxis(this, "Haut", 0.0, 0.0, true, "");
    axisPanel.add(top);
    left = new JPanelAxis(this, "Gauche", 0.0, 0.0, true, "");
    axisPanel.add(left);
    right = new JPanelAxis(this, "Droite", 0.0, 0.0, true, "");
    axisPanel.add(right);
   
    if (gs.getAbscissaPosition() == Position.BOTTOM){
      top.setVisible(false);
      bottom.setAll(gs.getaX1().getMin(), gs.getaX1().getMax(),
              gs.getaX1().isAutoScale(), gs.getaX1().getTitle());
    } else {
      bottom.setVisible(false);
      top.setAll(gs.getaX2().getMin(), gs.getaX2().getMax(),
              gs.getaX2().isAutoScale(), gs.getaX2().getTitle());     
    }
  }

  /**
   * Crée toute l'interface graphique du dialogue
   * @param graphicStyle
   */
  private void createUI(GraphicStyle graphicStyle){
    loadImages();
    JToolBar toolbar = new JToolBar();
    toolbar.setFloatable(false); // toolbar fixe
    toolbar.add(addCurveAction);
    add(toolbar, BorderLayout.PAGE_START);
    jtp = new JTabbedPane();
    add(jtp);

    jpgene = new JPanelGeneral();
    jpgene.setGrid(graphicStyle.isDrawGrid());
    jtp.addTab("Général", jpgene);
   
    editCurvesPanel = new JPanel();
    editCurvesPanel.setLayout(new BoxLayout(editCurvesPanel, BoxLayout.Y_AXIS));
    jtp.addTab("Courbes", editCurvesPanel);
   
    createAbscissaPanel(graphicStyle);
    editCurvesPanel.add(abscissaPanel);
    createCurvesPanel(graphicStyle);
    editCurvesPanel.add(curvesPanel);
    createAxisPanel(graphicStyle)
    editCurvesPanel.add(axisPanel);
   
    reCalculateCurvesAxis();
   
    jbOk = new JButton("Ok", new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/Crystal_Clear_app_clean-24.png")));
    jbOk.addActionListener(this);
    jbAnnuler = new JButton("Annuler", new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/Crystal_Clear_action_button_cancel-24.png")));
    jbAnnuler.addActionListener(this);
    JPanel jpBoutons = new JPanel();
    FlowLayout layout2 = new FlowLayout();
    jpBoutons.setLayout(layout2);
    layout2.setAlignment(FlowLayout.RIGHT);
    jpBoutons.add(jbAnnuler);
    jpBoutons.add(jbOk);
    add(jpBoutons, BorderLayout.PAGE_END);
  }
 
  /**
   * Charge les images et les textes qui iront dans les JComboBox
   */
  private void loadImages() {
    // Les images de type de points
    int numberIcons = 5;
    iconPoints = new ImageIcon[numberIcons];
    textPoints = new String[numberIcons];
    iconPoints[0] = null;
    iconPoints[1] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/point_rond-30.png"));
    iconPoints[2] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/point_carre-30.png"));
    iconPoints[3] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/point_croix-30.png"));
    iconPoints[4] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/point_croix_oblique-30.png"));
    textPoints[0] = PointStyle.NONE.getLabel();
    textPoints[1] = PointStyle.CIRCLE.getLabel();
    textPoints[2] = PointStyle.SQUARE.getLabel();
    textPoints[3] = PointStyle.CROSS.getLabel();
    textPoints[4] = PointStyle.OBLIQUE_CROSS.getLabel();

    // Les images de type de lignes
    numberIcons = 4;
    iconLines = new ImageIcon[numberIcons];
    textLines = new String[numberIcons];
    iconLines[0] = null;
    iconLines[1] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/ligne_continue_30x24.png"));
    iconLines[2] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/ligne_brisee_30x24.png"));
    iconLines[3] = new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/ligne_points_30x24.png"));
    textLines[0] = LineStyle.NONE.getLabel();
    textLines[1] = LineStyle.CONTINUE.getLabel();
    textLines[2] = LineStyle.BROKEN.getLabel();
    textLines[3] = LineStyle.DOTTED.getLabel();
  }

  /**
   * Répond au clic sur les boutons Ok et Annuler
   * @param e
   */
  @Override
  public void actionPerformed(ActionEvent e) {
    if (e.getSource().equals(jbOk)) {
      ok = true;
    }
    setVisible(false);
  }
 
  /**
   *
   * @return true si le dialog s'est terminé avec Ok false sinon
   */
  public boolean isOk() {
    return ok;
  }
 
  /**
   * Un min ou un max d'échelle d'axe vient d'être modifié par l'utilisateur.
   * On vérifie que ce sont bien des doubles et on désactive le bouton Ok
   * si ce n'est pas le cas.
   */
  public void notifyMinMaxChanged(){
   
    jbOk.setEnabled(verifyMinMax(bottom) && verifyMinMax(top)
            && verifyMinMax(left) && verifyMinMax(right));
    System.out.println("notifyMinMaxChanged");
  }
 
  /**
   * Vérifie qu'il n'y a pas d'erreur dans les min et max d'un axe
   * @param jpa le JPanelAxis à vérifier
   * @return true si les deux min et max de l'axe sont bien des doubles
   */
  private boolean verifyMinMax(JPanelAxis jpa){
    return jpa == null? true: jpa.goodMinMax();
  }
 
  /**
   * Remplit les champs min max auto et text d'un GraphicStyle. Utilisé
   * dans getNewGraphicStyle
   * @param jpa
   * @param as
   */
  private void fillAxis(JPanelAxis jpa, AxisStyle as){
    if (/*jpa == null*/!jpa.isVisible()){
      as.setMin(0);
      as.setMax(0);
      as.setAutoScale(true);
      as.setText("");
    } else {
      as.setMin(jpa.getMin());
      as.setMax(jpa.getMax());
      as.setAutoScale(jpa.isScaleAuto());
      as.setText(jpa.getText());     
    }
  }
 
  private String getAbscissaText(){
    String text;
    if (bottom.isVisible()){
      text = bottom.getText();
    } else{
      text = top.getText();
    }
    return text;
  }
 
  /**
   * Permet de récupérer le GraphicStyle définit par l'utilisateur une
   * fois que celui-ci a cliqué sur le bouton Ok
   * @return le GraphicStyle réglé par l'utilisateur
   */
  public GraphicStyle getNewGraphicStyle(){
    GraphicStyle gs = new GraphicStyle();
    Axis abscissa;
    Position abscissaPosition = abscissaPanel.getAbscissaPosition();
    String abscissaName = abscissaPanel.getAbscissaName();
    switch(abscissaPosition){
      case BOTTOM:
        abscissa = gs.getaX1();
        break;
      case TOP:
        abscissa = gs.getaX2();
        break;
      default:
        throw new RuntimeException("Bad Location : Abscissa");
    }
    gs.setDrawGrid(jpgene.getGrid());
    gs.setAbscissa(abscissaName);
    gs.setAbscissaPosition(abscissaPosition);
    //abscissa.getAxisStyle().setName(abscissaName);
    abscissa.getAxisStyle().setText(getAbscissaText());
   
    fillAxis(bottom, gs.getaX1().getAxisStyle());
    fillAxis(top, gs.getaX2().getAxisStyle());
    fillAxis(left, gs.getaY1().getAxisStyle());
    fillAxis(right, gs.getaY2().getAxisStyle());
   
    List<Curve> curves = new ArrayList<>();
    for (JPanelCurve jpc : panelCurves){
      PointLineStyle pls = jpc.getPointLineStyle();
      Position pos = jpc.getPosition();
      Axis axis;
      switch(pos){
        case LEFT:
          axis = gs.getaY1();
          break;
        case RIGHT:
          axis = gs.getaY2();
          break;
        default:
          throw new RuntimeException("Bad Location : Curve");
      }
//      axis.getAxisStyle().setName(jpc.getCurveName());
//      axis.getAxisStyle().setText(jpc.getCurveName());
      Curve curve = new Curve(abscissaName, jpc.getCurveName(), abscissa, axis, pls);
      curves.add(curve);
    }
    gs.setCurves(curves);
   
    return gs;
  }
 
  /**
   * Ajoute un panneau correspondant à une nouvelle courbe.
   * @param curve
   */
  private void addCurvePanel(Curve curve){
    JPanelCurve jpc = new JPanelCurve(this, curve, iconPoints, textPoints, iconLines, textLines);
    curvesPanel.add(jpc);
    panelCurves.add(jpc);
    jpc.getRemoveButton().setAction(deleteCurveAction);
    //setMinMaxAtPosition(jpc.getPosition());
  }
 
  /**
   * La classe qui permet d'ajouter une courbe
   */
  class AddCurveAction extends AbstractAction {

    public AddCurveAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
      super(text, icon);
      putValue(SHORT_DESCRIPTION, desc);
      putValue(MNEMONIC_KEY, mnemonic);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      addCurvePanel(null);
      //notifyPositionChanged();
      pack();
    }
  }
  /**
   * La classe qui permet de supprimer une courbe
   */
  class DeleteCurveAction extends AbstractAction {

    public DeleteCurveAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
      super(text, icon);
      putValue(SHORT_DESCRIPTION, desc);
      putValue(MNEMONIC_KEY, mnemonic);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      JButton jb = (JButton) e.getSource();
      JPanelCurve jpc = (JPanelCurve) jb.getParent();
      curvesPanel.remove(jpc);
      panelCurves.remove(jpc);
      //notifyPositionChanged();
      pack();
    }
  }

}
TOP

Related Classes of freegressi.graphics.JDialogEditCurves$DeleteCurveAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.