/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Copyright (C) 2011-2012 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.main;
import freegressi.graphics.JPanelGraphics;
import freegressi.main.MainModel.ApplicationSeFermeEvent;
import freegressi.main.MainModel.FichierOuvertEvent;
import freegressi.main.MainModel.MainListener;
import freegressi.main.MainModel.NouveauExperienceEvent;
import freegressi.main.MainModel.SaveEvent;
import freegressi.main.UndoRedo.UndoRedoEvent;
import freegressi.main.UndoRedo.UndoRedoListener;
import freegressi.tableur.*;
import freegressi.tableur.SpreadSheets.ActiveSheetChangedEvent;
import freegressi.tableur.SpreadSheets.SheetAddedEvent;
import freegressi.tableur.SpreadSheets.SheetDeletedEvent;
import freegressi.tableur.SpreadSheets.SheetDescriptionChangedEvent;
import freegressi.tableur.SpreadSheets.SheetsAngleChangedEvent;
import freegressi.tableur.SpreadSheets.SheetsCSChangedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnAddedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnDeletedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnModifiedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnMovedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnSortedEvent;
import freegressi.tableur.SpreadSheets.SheetsColumnsEditedEvent;
import freegressi.tableur.SpreadSheets.SheetsRenamedEvent;
import freegressi.fit.JPanelFits;
import freegressi.fit.FitModel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author marchand
*/
public class JMainFrame extends JFrame implements MainListener,
UndoRedoListener, ChangeListener, SpreadSheets.SheetsListener {
private MainModel mainModel = MainModel.getInstance();
/** L'action de quitter l'application */
private CloseAction closeAction = new CloseAction("Quitter",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/Crystal_Clear_action_exit-24.png")),
"Quitter l'application", 0);
/** L'action de créer un nouveau document */
protected NewAction newAction = new NewAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/inserttable_26x26.png")),
"Créer un nouveau document ou une nouvelle feuille", 0);
/** L'action de créer un nouveau document */
private PrintAction printAction = new PrintAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/print_26x26.png")),
"Imprimer ce document", 0);
/** L'action de créer un nouveau document à partir de données dans le presse papier */
protected NewDatasClipboardAction newDatasClipboardAction =
new NewDatasClipboardAction("Données collées à partir du presse papier",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/paste_26x26.png")),
"Créer un nouveau document à partir du presse-papier", 0);
/** L'action d'enregistrer le document */
private SaveAction enregistrerAction = new SaveAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/save_26x26.png")),
"Enregistrer ce document", 0);
/** L'action de données un nom et d'enregistrer le document */
private SaveAsAction enregistrerSousAction = new SaveAsAction("Enregistrer sous ...",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/saveas_26x26.png")),
"Enregistrer ce document sous un nouveau nom", 0);
/** L'action d'ouvrir un nouveau document frg */
protected OpenAction ouvrirAction = new OpenAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/openfolder_26x26.png")),
"Ouvrir un document", 0);
/** */
private UndoAction undoAction = new UndoAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/undo_26x26.png")),
"Undo", 0);
/** */
private RedoAction redoAction = new RedoAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/redo_26x26.png")),
"Redo", 0);
/** */
private GarbageAction garbageAction = new GarbageAction("",
new javax.swing.ImageIcon(getClass().getResource("/freegressi/img/Gnome-edit-delete-24.png")),
"Garbage Collector", 0);
/** Le splitpane qui contient les séries à gauche et le graphique à droite */
private JSplitPane jspH, jspV;
private JPanelFits jpFits;
private JButton undo, redo, save;
private JPanel mainPanel;
private JPanelGraphics jpg;
private JTabbedPane jtpTools;
private JPanelSheets jpSheets;
private JSpinner js;
/** Flag indiquant si c'est l'utilisateur qui change le CS ou le SpreadSheets */
private boolean flagCS = true;
private FreegressiFilter openFilter, saveFilter;
//private String nomDernierRepertoire = ".";
private Preferences pref = new Preferences(false);
public JMainFrame() {
super();
pref.loadProperties();
createUI();
//setExtendedState(MAXIMIZED_BOTH);
}
/* **********************************************************************
*
* Interface Graphique
*
*********************************************************************** */
/**
* Crée l'interface graphique de la fenetre principale
*/
private void createUI() {
setTitle(mainModel.getApplicationName());
setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/freegressi/img/logo.png")));
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(800, 600));
createFreegressiFilters();
createMainPanel();
createToolBar();
createSplitPanes();
createUISheets();
createUITools();
createUIGraphics();
pack();
setLocationRelativeTo(null);
placeSplitPanes();
setVisible(true);
}
private void createFreegressiFilters(){
saveFilter = new FreegressiFilter(
new String[]{"frg"},
"les fichiers freegressi (*.frg)"
);
openFilter = new FreegressiFilter(
new String[]{"frg","rw3"},
"les fichiers freegressi (*.frg, *.rw3)"
);
}
/**
* Panneau principal, création de la barre d'outils, des splitpanes,
* et du panneau "Tools"
*/
private void createMainPanel() {
mainPanel = new JPanel(new BorderLayout());
add(mainPanel);
}
private void createToolBar(){
JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL);
toolbar.add(newAction);
toolbar.add(newDatasClipboardAction);
toolbar.add(ouvrirAction);
save = new JButton(enregistrerAction);
toolbar.add(save);
toolbar.add(enregistrerSousAction);
toolbar.add(printAction);
toolbar.addSeparator();
undo = new JButton(undoAction);
toolbar.add(undo);
redo = new JButton(redoAction);
toolbar.add(redo);
toolbar.addSeparator();
toolbar.add(garbageAction);
js = new JSpinner(new SpinnerNumberModel(3, 1, 5, 1));
JFormattedTextField tf = ((JSpinner.DefaultEditor)js.getEditor()).getTextField();
tf.setEditable(false);
js.addChangeListener(this);
js.setToolTipText("<html>Changer les <strong>C</strong>hiffres <strong>S</strong>ignificatifs</html>");
js.setSize(40, 30);
js.setMaximumSize(new Dimension(45, 30));
toolbar.add(new JLabel("CS "));
toolbar.add(js);
toolbar.add(closeAction);
mainPanel.add(toolbar, BorderLayout.NORTH);
}
/**
* Ajoute le panneau qui contient les outils (Fits, Calculette, stats ...)
*/
private void createUITools() {
jtpTools = new JTabbedPane();
jpFits = new JPanelFits(null);
FitModel.getInstance().addTendanceListener(jpFits);
SpreadSheets.getInstance().addSheetsListener(jpFits);
jtpTools.addTab("Modèles", jpFits);
JPanelCalc jpcalc = new JPanelCalc();
SpreadSheets.getInstance().addSheetsListener(jpcalc);
jtpTools.addTab("Calculette", jpcalc);
// jtpTools.setSelectedIndex(1);
jspV.setBottomComponent(jtpTools);
}
private void createUISheets(){
jpSheets = new JPanelSheets();
SpreadSheets.getInstance().addSheetsListener(jpSheets);
jspV.setTopComponent(jpSheets);
}
private void placeSplitPanes(){
jspH.setDividerLocation((int) (getWidth() / 2));
jspV.setDividerLocation((int) (getHeight() * 0.6));
}
public void nothing() {
enregistrerAction.setEnabled(false);
enregistrerSousAction.setEnabled(false);
printAction.setEnabled(false);
undoAction.setEnabled(false);
redoAction.setEnabled(false);
}
private void createUIGraphics(){
jpg = new JPanelGraphics();
//GraphiqueModel.getInstance().addGraphiqueListener(jpg.getPanelGraphique());
jspH.setRightComponent(jpg);
}
// private void createUIGraphs(Tableur tableur, List<JPanelGraphique> listeGraphiques) {
// Graphique graphique = null;
// GraphicStyle gs = null;
// // Créer un graphique par défaut s'il n'y en a pas
// if (listeGraphiques == null || listeGraphiques.isEmpty()) {
// if (tableur.getColumnCount() > 2) {
// graphique = new Graphique();
// graphique.setTableur(tableur);
// graphique.setColonneX(tableur.getListeColonnes().get(0));
// List<Colonne> listeY = new ArrayList<Colonne>();
// listeY.add(tableur.getListeColonnes().get(1));
//
// graphique.setListeColonneY(listeY);
//
// String nameX = tableur.getColumnName(1);
// String nameY = tableur.getColumnName(2);
// gs = new GraphicStyle(nameX, nameY);
//
//
// }
// }
// jpg = new JPanelGraphiques(graphique, gs);
// GraphiqueModel.getInstance().addGraphiqueListener(jpg.getPanelGraphique());
// jspH.setRightComponent(jpg);
// //jspH.setVisible(true);
// }
private void createSplitPanes() {
jspH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
jspH.setOneTouchExpandable(true);
//jspH.setDividerLocation((int) (getWidth() / 2));
jspH.setContinuousLayout(false);
mainPanel.add(jspH, BorderLayout.CENTER);
jspV = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
jspV.setOneTouchExpandable(true);
jspH.setLeftComponent(jspV);
//jspV.setDividerLocation((int) (getHeight() * 0.6));
jspV.setContinuousLayout(false);
}
/* **********************************************************************
*
* Fermeture Enregistrement
*
*********************************************************************** */
@Override
public void applicationFermee(ApplicationSeFermeEvent event) {
System.exit(0);
}
@Override
public void mainSave(SaveEvent event) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void stateChanged(ChangeEvent e) {
// L'utilisateur a modifié le jspinner des chiffres significatifs
if (!flagCS){
return;
}
SpinnerModel sm = js.getModel();
if (sm instanceof SpinnerNumberModel) {
int CS = ((SpinnerNumberModel)sm).getNumber().intValue();
SpreadSheets.getInstance().notifySheetsCSChanged(CS, true);
}
}
@Override
public void activeSheetChanged(ActiveSheetChangedEvent event) {
}
@Override
public void sheetAdded(SheetAddedEvent event) {
}
@Override
public void sheetDeleted(SheetDeletedEvent event) {
}
@Override
public void sheetRenamed(SheetsRenamedEvent event) {
}
@Override
public void columnAdded(SheetsColumnAddedEvent event) {
}
@Override
public void columnDeleted(SheetsColumnDeletedEvent event) {
}
@Override
public void angleChanged(SheetsAngleChangedEvent event) {
}
@Override
public void columnModified(SheetsColumnModifiedEvent event) {
}
@Override
public void columnMoved(SheetsColumnMovedEvent event) {
}
@Override
public void columnSorted(SheetsColumnSortedEvent event) {
}
@Override
public void columnsEdited(SheetsColumnsEditedEvent event) {
}
@Override
public void sheetDescriptionChanged(SheetDescriptionChangedEvent event) {
}
@Override
public void sheetsCSChanged(SheetsCSChangedEvent event) {
flagCS = false;
js.setValue(new Integer(event.getNewCS()));
flagCS =true;
}
private class CloseAction extends AbstractAction {
public CloseAction(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) {
pref.saveProperties();
mainModel.notifyFermerApplication();
}
}
/**
* Action d'enregistrer le fichier sur le disque
*/
private class SaveAction extends AbstractAction {
public SaveAction(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) {
mainModel.notifySaveDocument();
}
}
private class SaveAsAction extends AbstractAction {
public SaveAsAction(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) {
JFileChooser filechoose = new JFileChooser();
filechoose.addChoosableFileFilter(saveFilter);
filechoose.setFileFilter(saveFilter);
filechoose.setCurrentDirectory(new File(MainModel.getInstance().getLastDir()));
String approve = "Enregistrer";
filechoose.setSelectedFile(mainModel.getFile());
int resultatEnregistrer = filechoose.showDialog(null, approve);
if (resultatEnregistrer == JFileChooser.APPROVE_OPTION) {
mainModel.notifySaveAsDocument(filechoose.getSelectedFile());
}
}
}
/* **********************************************************************
*
* Undo Redo
*
*********************************************************************** */
private class UndoAction extends AbstractAction {
public UndoAction(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) {
UndoRedo.getInstance().undo();
}
}
private class RedoAction extends AbstractAction {
public RedoAction(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) {
UndoRedo.getInstance().redo();
}
}
@Override
public void undoredoChange(UndoRedoEvent event) {
if (event.isUndoPossible()) {
undo.setToolTipText("Défaire : " + event.getTexteNextUndo());
undoAction.setEnabled(true);
} else {
undo.setToolTipText("Rien à défaire");
undoAction.setEnabled(false);
}
if (event.isRedoPossible()) {
redo.setToolTipText("Refaire : " + event.getTexteNextRedo());
redoAction.setEnabled(true);
} else {
redo.setToolTipText("Rien à refaire");
redoAction.setEnabled(false);
}
if (event.isFileSaved()) {
enregistrerAction.setEnabled(false);
setTitle(mainModel.getApplicationName() + " [" + mainModel.getShortFileName() + "]");
} else {
enregistrerAction.setEnabled(mainModel.getFile() != null);
setTitle(mainModel.getApplicationName() + " [" + mainModel.getShortFileName() + "*]");
}
}
/* **********************************************************************
*
* Ouverture ou création de document
*
*********************************************************************** */
public class OpenAction extends AbstractAction {
public OpenAction(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) {
JFileChooser filechoose = new JFileChooser();
filechoose.addChoosableFileFilter(openFilter);
filechoose.setFileFilter(openFilter);
filechoose.setCurrentDirectory(new File(pref.lastDir));
//filechoose.setCurrentDirectory(new File(MainModel.getInstance().getLastDir()));
String approve = "Ouvrir";
int resultatOuvrir = filechoose.showDialog(null, approve);
if (resultatOuvrir == JFileChooser.APPROVE_OPTION) {
// String nomFichierTemp = filechoose.getSelectedFile().toString();
//nomDernierRepertoire = filechoose.getSelectedFile().getParent();
// //System.out.println("repertoire : " + nomRepertoire);
// File fichier = new File(nomFichierTemp);
// mainModel.notifyOuvrirFichier(fichier);
mainModel.notifyOuvrirFichier(filechoose.getSelectedFile());
pref.lastDir = filechoose.getCurrentDirectory().toString();
}
}
}
/**
* Action de coller les données du presse papier et d'en récupérer les séries
*/
public class NewDatasClipboardAction extends AbstractAction {
public NewDatasClipboardAction(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) {
//
JDialogClipboard jdc = new JDialogClipboard(null, JDialogClipboard.JDialogClipboardType.FROMCLIPBOARD, "");
jdc.setVisible(true);
if (jdc.isOk()) {
mainModel.notifyDocumentFromClipboard(jdc.getText());
}
jdc.dispose();
}
}
public class NewAction extends AbstractAction {
public NewAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
private void showNewVarExp() {
JDialogVarExp jdnve = new JDialogVarExp(null);
jdnve.setVisible(true);
if (jdnve.isOk()) {
ArrayList<String> listeNoms = jdnve.getListeNoms();
ArrayList<String> listeUnites = jdnve.getListeUnites();
mainModel.notifyNouveauExperience(listeNoms, listeUnites);
}
jdnve.dispose();
}
@Override
public void actionPerformed(ActionEvent e) {
if (SpreadSheets.getInstance().getActiveSheet() != null) {
JDialogNewSheetOrDocument jdn = new JDialogNewSheetOrDocument(null);
jdn.setVisible(true);
if (jdn.isOk()) {
if (jdn.isNewDocument()) {
showNewVarExp();
} else { // nouvelle feuille
mainModel.notifyNewSheet();
}
}
jdn.dispose();
} else {
showNewVarExp();
}
}
}
@Override
public void fichierOuvert(FichierOuvertEvent event) {
setTitle(mainModel.getApplicationName() + " [" + event.getNomFichier() + "]");
enregistrerSousAction.setEnabled(true);
printAction.setEnabled(true);
this.pack();
this.validate();
}
@Override
public void nouveauExperience(NouveauExperienceEvent event) {
System.out.println("Sheets : " + SpreadSheets.getInstance().getList().size());
setTitle(mainModel.getApplicationName() + " [Sans nom]");
enregistrerAction.setEnabled(false);
enregistrerSousAction.setEnabled(true);
printAction.setEnabled(true);
this.pack();
this.validate();
}
/* **********************************************************************
*
* Vrac
*
*********************************************************************** */
private class PrintAction extends AbstractAction {
public PrintAction(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) {
// JDialogPrint.PrintType printType = new JDialogPrint.PrintType(true, false, false, false, false, false);
// JDialogPrint jdp = new JDialogPrint(null, printType);
// jdp.setVisible(true);
// if (jdp.isOk()) {
// PrinterJob pj = PrinterJob.getPrinterJob();
// HashPrintRequestAttributeSet prs = new HashPrintRequestAttributeSet();
// prs.add(DialogTypeSelection.COMMON);
//// PageFormat pf = new PageFormat();
//// pf = pj.pageDialog(pf);
//// if (pf != null) {
// if (pj.printDialog(prs)) {
// //PageFormat pf = pj.pageDialog(pj.defaultPage());
// PageFormat pf = pj.getPageFormat(prs);
// Print print = new Print(printType, jps.getTable(), jpg.getPanelGraphique(), jpt.getListTendances());
// try {
// //PageFormat pf = pj.defaultPage();
//
// pj.setPrintable(print, pf);
//
// pj.print();
// } catch (PrinterException exc) {
// System.out.println(exc);
// }
// }
// }
// jdp.dispose();
}
}
private class GarbageAction extends AbstractAction {
public GarbageAction(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) {
Runtime rt = Runtime.getRuntime();
long totalMemory = rt.totalMemory();
long freeMemory = rt.freeMemory();
long usedMemory = totalMemory - freeMemory;
System.err.println("**************** Garbage Collector *******************");
System.err.println("Used : " + usedMemory + " / " + totalMemory + " octets");
System.gc();
System.runFinalization();
System.err.println("Used : " + usedMemory + " / " + totalMemory + " octets");
}
}
}