Package eva.gui

Source Code of eva.gui.MainFrame

/**
*
*/
package eva.gui;

import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.imageio.ImageIO;
import javax.mail.MessagingException;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileFilter;

import org.joda.time.*;
import org.joda.time.format.PeriodFormat;
import org.joda.time.format.PeriodFormatter;

import eva.gui.mvc.*;
import eva.gui.mvc.ParentsEveningTreeModel.ModelMode;
import eva.schedule.*;
import eva.tools.StringEscapeUtils;
import eva.io.*;
import eva.algorithms.*;

/**
* @author SimonWagner
* @version 0.2
*
*/
public class MainFrame extends JFrame {
 
  private EVAApplication application;
 
  private JSplitPane splitPane;
  private JTree parentsTree;
  private JTree teachersTree;
  private ParentsEveningTreeModel parentsTreeModell;
  private ParentsEveningTreeModel teachersTreeModell;
  private JTable appointmentsTable;
  private AppointmentsTabelModel appointmentsTabelModel;
  private JStatusBar statusBar = new JStatusBar();
 
  private EveningSchedule eveningSchedule;
 
  private Duration maxMaxWaitTime;
  private Duration maxAvgWaitTime;
 
  private URL exchangeWishesUrl;
  private URL exchangeScheduleUrl;
 
  private String password;
 
  public MainFrame() {
    application = EVAApplication.getApplication();
    loadProperties();
    initGUI();
  }

  private void loadProperties() {   
    Properties properties = application.getProperties();
   
    maxMaxWaitTime = new Duration(Integer.parseInt(properties.getProperty("eva.optimization.maxmaxwaittime")));
    maxAvgWaitTime = new Duration(Integer.parseInt(properties.getProperty("eva.optimization.maxavgwaittime")));
 
    try {
      exchangeWishesUrl = new URL(properties
          .getProperty("eva.web.wishes-url"));
      exchangeScheduleUrl = new URL(properties
          .getProperty("eva.web.schedule-url"));
    } catch (MalformedURLException e) {
      showErrorMessageDialog("Fehlerhafte URLs in Einstellungen", "Fehler");
    }
   
    password = properties.getProperty("eva.web.password");
  }

  private void initGUI() {
   
    initMenu();   
    initImages();
   
    initTrees();
    initTable();
   
    splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);   
    getContentPane().add(splitPane);
   
   
    JTabbedPane treeTabs = new JTabbedPane();
    treeTabs.add("Eltern", new JScrollPane(parentsTree));
    treeTabs.add("Lehrer", new JScrollPane(teachersTree));
   
    splitPane.setLeftComponent(treeTabs);
    splitPane.setRightComponent(new JScrollPane(appointmentsTable));
    splitPane.setDividerLocation(150);
   
    //status bar
    add(statusBar, BorderLayout.SOUTH);
   
    initListeners()
  }
 
  private void initTrees() {
   
    //set up tree model
    parentsTreeModell = new ParentsEveningTreeModel(ModelMode.PARENTS_TREE);
    teachersTreeModell = new ParentsEveningTreeModel(ModelMode.TEACHERS_TREE);
   
    //create checkers
    ParentsEveningTreeModel.AppointableChecker conflictChecker =
      new ParentsEveningTreeModel.AppointableChecker() {
        @Override
        public boolean check(Appointable appointable) {
          return appointable.isConflicting() || !appointable.getSchedule().getVisitsChecklist().allVisitsDone();
        }         
      };
     
    ParentsEveningTreeModel.AppointableChecker warningsChecker =
      new ParentsEveningTreeModel.AppointableChecker() {
        /* note: this checker checks ONLY parents */
        @Override
        public boolean check(Appointable appointable) {
          if(maxMaxWaitTime != null && maxAvgWaitTime != null && appointable instanceof Parent) {
            Schedule schedule = appointable.getSchedule();
            /*Parent parent = (Parent) appointable;
            if(parent.getFirstName() == "Anke") {
              System.out.println("STOP");
            }*/
            return schedule.getAvgWaitTime().isLongerThan(maxAvgWaitTime) ||
              schedule.getMaxWaitTime().isLongerThan(maxMaxWaitTime);
          }
          else {
            return false;
          }
        }         
      };
     
    //set checkers     
    parentsTreeModell.setConflictChecker(conflictChecker);
    parentsTreeModell.setWarningsChecker(warningsChecker);
    teachersTreeModell.setConflictChecker(conflictChecker);
    teachersTreeModell.setWarningsChecker(warningsChecker);
   
   
    //create renderer   
    ParentsEveningTreeCellRenderer treeRenderer = new ParentsEveningTreeCellRenderer();
    //set conflict and warning icons
    treeRenderer.setConflictIcon(new ImageIcon(getClass().getResource("/eva/gui/images/conflict.png")));
    treeRenderer.setWarningIcon(new ImageIcon(getClass().getResource("/eva/gui/images/warning.png")));
   
    //set up trees
    parentsTree = new JTree(parentsTreeModell);
    parentsTree.setCellRenderer(treeRenderer);
    parentsTree.setEditable(false);
    teachersTree = new JTree(teachersTreeModell);
    teachersTree.setCellRenderer(treeRenderer);
    teachersTree.setEditable(false);
  }
 
  private void initTable() {
   
    appointmentsTabelModel = new AppointmentsTabelModel();
    appointmentsTable = new JTable(appointmentsTabelModel);
  }
 
  private void initListeners() {
   
    //listener for changes of the selected tree node
   
    TreeSelectionListener treeSelectionListener =
      new TreeSelectionListener() {
      @Override
      public void valueChanged(TreeSelectionEvent e) {
        Object source = e.getPath().getLastPathComponent();
        if(source instanceof Appointable) {
          Appointable appointable = (Appointable) source;
          appointmentsTabelModel.setAppointable(appointable);
         
          PeriodFormatter periodFormatter = PeriodFormat.getDefault();
         
          String statusMessage =
            "Wartezeit: " + periodFormatter.print(appointable.getSchedule().getWaitTime().toPeriod());
         
          statusBar.setMessage(statusMessage);
        }
      }     
    };
   
    parentsTree.addTreeSelectionListener(treeSelectionListener);   
    teachersTree.addTreeSelectionListener(treeSelectionListener);
  }

 

  @SuppressWarnings("serial")
  private void initMenu() {
    JMenuBar menuBar = new JMenuBar();
   
    //file menu
    JMenu fileMenu = new JMenu("Datei");
   
    //file > open wishes
    Action openWishes = new AbstractAction("Wünsche öffnen...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        openWishesFile();
      }     
    };
   
    //file > save schedule
    Action saveSchedule = new AbstractAction("Zeitplan speichern...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        saveSchedule();
      }     
    };
   
    //file > exit
    Action exitAction = new AbstractAction("Beenden") {
      @Override
      public void actionPerformed(ActionEvent e) {
        dispose();
      }     
    };
   
    fileMenu.add(openWishes);
    fileMenu.add(saveSchedule);
    fileMenu.addSeparator();
    fileMenu.add(exitAction);
   
    //schedule menu
    JMenu scheduleMenu = new JMenu("Zeitplan");
   
    //schedule > set optimization options
    Action askOptimizationSettings = new AbstractAction("Optimierungs-Parameter festlegen...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        askOptimizationSettings();
      }     
    };
   
    //schedule > calculate schedule
    Action calculateSchedule = new AbstractAction("Zeitplan berechnen...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        calculateSchedule();
      }     
    };
   
    scheduleMenu.add(askOptimizationSettings);
    scheduleMenu.add(calculateSchedule);
   
    //web interface menu
    JMenu webinterfaceMenu = new JMenu("Webinterface");
   
    //web interface > download wishes
    Action downloadWishes = new AbstractAction("Wünsche herunterladen...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        downloadWishes();
      }           
    };
   
   
    //web interface > upload schedule
    Action uploadSchedule = new AbstractAction("Zeitplan hochladen...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        uploadSchedule();
      }     
    };
   
    //web interface > send e-mails
    Action sendEMails = new AbstractAction("E-Mails mit Benachrichtigung senden...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        sendEMails();
      }     
    };
   
    webinterfaceMenu.add(downloadWishes);
    webinterfaceMenu.add(uploadSchedule);
    webinterfaceMenu.add(sendEMails);
   
    //options menu
    JMenu optionsMenu = new JMenu("Optionen");
    //options > settings
    Action askSettings = new AbstractAction("Einstellungen...") {
      @Override
      public void actionPerformed(ActionEvent e) {
        askSettings();
      }
    };
   
    optionsMenu.add(askSettings);
   
   
    menuBar.add(fileMenu);
    menuBar.add(scheduleMenu);
    menuBar.add(webinterfaceMenu);
    menuBar.add(optionsMenu);
   
   
    setJMenuBar(menuBar);
  }
 
  private void initImages() {
    //load the application icon
    try {
      String iconsResourcePath = "/eva/gui/images/";
      String iconNames[] = {
        "eva-icon_16x16.png",
        "eva-icon_32x32.png",
        "eva-icon_64x64.png",
        "eva-icon_128x128.png"
      };
      List<Image> icons = new ArrayList<Image>();
     
      for(String iconName : iconNames) {
        Image icon = ImageIO.read(getClass().getResource(iconsResourcePath + iconName));
        icons.add(icon);
      }
      setIconImages(icons);
    } catch (Exception e) {
      System.err.println("could not read application icons: " + e.getMessage());
      e.printStackTrace();
    }   
  }
 
 
  private void openWishesFile() {
    JFileChooser fileChooser = new JFileChooser();
    fileChooser.setFileFilter( new FileFilter() {

      @Override
      public boolean accept(File file) {
        return file.isDirectory() ||
          file.getName().toLowerCase().endsWith( ".xml" );
      }

      @Override
      public String getDescription() {       
        return "Wünsche-Datei (*.xml)";
      }
     
    });
   
    int state = fileChooser.showOpenDialog(this);
   
    if(state == JFileChooser.APPROVE_OPTION) {
      File file = fileChooser.getSelectedFile();
     
      try {
        WishesReader wishesReader = new WishesReader(new FileInputStream(file));
        wishesReader.read();
       
        eveningSchedule = wishesReader.getEveningSchedule();
        parentsTreeModell.setEveningSchedule(eveningSchedule);
        teachersTreeModell.setEveningSchedule(eveningSchedule);
        splitPane.resetToPreferredSizes();
       
      } catch (FileNotFoundException e) {
        showErrorMessageDialog("Datei konnte nicht gefunden werden!\n" + e.getLocalizedMessage(), "Fehler beim Lesen");
      } catch (InvalidWishesFile e) {
        showErrorMessageDialog("Ungültige Datei!\n" + e.getMessage(), "Fehler beim Lesen");
      }
    }   
  }
 
  private void saveSchedule() {
    JFileChooser fileChooser = new JFileChooser();
    fileChooser.setFileFilter( new FileFilter() {

      @Override
      public boolean accept(File file) {
        return file.isDirectory() ||
          file.getName().toLowerCase().endsWith( ".xml" );
      }

      @Override
      public String getDescription() {       
        return "Zeitplan-Datei (*.xml)";
      }
     
    });
   
    int state = fileChooser.showSaveDialog(this);
   
    if(state == JFileChooser.APPROVE_OPTION) {
      File file = fileChooser.getSelectedFile();
     
      try {
        EveningScheduleWriter writer = new EveningScheduleWriter(eveningSchedule, new FileOutputStream(file));
       
        writer.write();
      } catch (FileNotFoundException e) {
        showErrorMessageDialog("Datei konnte nicht gefunden werden!\n" + e.getLocalizedMessage(), "Fehler beim Speichern");
      } catch (IOException e) {
        showErrorMessageDialog("Fehler beim schreiben!\n" + e.getMessage(), "Fehler beim Speichern");
      }
    } 
  }
 
  private void calculateSchedule() {
   
    if(!Evening.isEveningAvailable() || eveningSchedule == null) {
      showErrorMessageDialog("Keine Wünsche vorhanden.", "Fehler - Zeitplan berechnen");
      return;
    }
   
    eveningSchedule.clearSchedules();
   
    GreedyScheduleGenerator generator = new GreedyScheduleGenerator(eveningSchedule);
    try {
      generator.run();
    } catch (ImpossibleScheduleException e) {
      showErrorMessageDialog("Zeitplan konnte nicht vollständig erstellt werden", "Unvollständiger Zeitplan");
      return;
    }
   
    Collection <Parent> parents = eveningSchedule.getParents();   
   
    final int OPTIMIZER_RUNS = 10;
    int optimizationDifferences = 0;
    int oldWaitingTime;
   
    for(int i = 1; i <= OPTIMIZER_RUNS; i++) {
     
      optimizationDifferences = 0;
     
      for(Parent parent : parents) {
       
        oldWaitingTime = parent.getSchedule().getWaitingTimeInSlots();
        LocalSearch optimizer = new LocalSearch(parent.getSchedule(), maxMaxWaitTime, maxAvgWaitTime);
        try {
          optimizer.run();
        } catch (ImpossibleScheduleException e) {
          showErrorMessageDialog("Zeitplan konnte nicht vollständig optimiert werden", "Unvollständiger Zeitplan");
          break;
        }
       
        optimizationDifferences += oldWaitingTime - parent.getSchedule().getWaitingTimeInSlots();       
       
      }     
     
      System.out.println("completed optimizer run nr. " + i);
      System.out.println("optimization difference: " + optimizationDifferences);
     
      if(optimizationDifferences <= 0) {
        break;
      }
    }
   
    parentsTree.updateUI();
    teachersTree.updateUI();
  }
 
  private void sendEMails() {   
   
    SendEMailsTask sendEMailsTask = new SendEMailsTask();
    ProgressDialog dlg = new ProgressDialog(this, sendEMailsTask);
   
    dlg.setTitle("E-Mails senden...");
    dlg.setMessage("{1} von {2} Mails verschickt...");
    sendEMailsTask.setProgressDialog(dlg);
   
    dlg.showDialog();   
  }
 
  private class SendEMailsTask implements Runnable {
    ProgressDialog progressDialog;
   
    @Override
    public void run() {
      sendEMailsThread();       
    }
   
    public void setProgressDialog(ProgressDialog progressDialog) {
      this.progressDialog = progressDialog;
    }
   
    private void sendEMailsThread() {
      Properties properties = application.getProperties();
     
      String address = properties.getProperty("eva.web.mail.address");
      String host = properties.getProperty("eva.web.mail.host");
      String user = properties.getProperty("eva.web.mail.user");
      String password = properties.getProperty("eva.web.mail.password");
     
      String parentsScheduleURL = properties.getProperty("eva.web.parent-schedule-url");
      String parentsScheduleLink = StringEscapeUtils.escapeHtml(parentsScheduleURL);
     
      if(eveningSchedule != null) {
        Collection<Parent> parents = eveningSchedule.getParents();
        ParentsNotificationMailer mailer = new ParentsNotificationMailer(host, user, password);
       
        //set progress dialog
        mailer.addProgressListener(progressDialog);
        //set message
        mailer.setMailInfo(address, properties.getProperty("eva.web.mail.msg.subject"));
        mailer.setMessageTextPlain(properties.getProperty("eva.web.mail.msg.text"));
        mailer.setMessageTextHtml(properties.getProperty("eva.web.mail.msg.html"));
       
        //set magic words for the mailer
        mailer.setMagicWord("PARENT_SCHEDULE_URL", parentsScheduleURL);
        mailer.setMagicWord("PARENT_SCHEDULE_LINK", parentsScheduleLink);
       
        //send mail
        try {
          mailer.connectMailServer();
        } catch (MessagingException e) {
          e.printStackTrace();
          showErrorMessageDialog("Kann nicht zum Mail-Server verbinden\n" + e.getMessage(), "Mail senden fehlgeschlagen");
          return;
        }
       
        int failCount = mailer.sendEMails(parents);
        if(failCount > 0) {
          showErrorMessageDialog(failCount + "Eltern konnte die Mail nicht zugestellt werden", "Mail senden fehlgeschlagen!");
        }
      }
    }
  }
 
 

  private void uploadSchedule() { 
    File file = null;
   
    //save the schedule in a temporary file
    try {
      file = File.createTempFile("schedule.xml", ".temp");
      EveningScheduleWriter writer = new EveningScheduleWriter(eveningSchedule, new FileOutputStream(file));
     
      writer.write();   
    } catch (IOException e) {
      e.printStackTrace();
      showErrorMessageDialog("Fehler beim Schreiben der tempor�ren Datei!\n" + e.getMessage(), "Fehler beim Upload");
      return;
    }
    catch (Exception e) {
      e.printStackTrace();
      showErrorMessageDialog("Ein unerwarteter Fehler ist aufgetreten!\n" + e.getLocalizedMessage(), "Fehler - Download des Zeitplans");
      return;
    }
   
    //upload the file
    try {
      HttpPostUpload uploader = new HttpPostUpload(exchangeScheduleUrl);
     
      uploader.addUploadFile(new UploadFile("schedule", file, "text/xml"));
      uploader.addFormField(new FormField("password", password));
     
      uploader.upload();
    } catch (UploadException e) {
      e.printStackTrace();
      showErrorMessageDialog("Fehler beim schreiben!\n" + e.getMessage(), "Fehler beim Upload");
      return;
    }
    catch (Exception e) {
      e.printStackTrace();
      showErrorMessageDialog("Ein unerwarteter Fehler ist aufgetreten!\n" + e.getLocalizedMessage(), "Fehler - Download des Zeitplans");
      return;
    }
   
  }

  private void downloadWishes() {
    try {
      URLConnection connection = exchangeWishesUrl.openConnection();
     
      connection.setDoInput(true);
      InputStream stream = connection.getInputStream();
     
      WishesReader wishesReader = new WishesReader(stream);
      try {
        wishesReader.read();
      } catch (InvalidWishesFile e) {
        e.printStackTrace();
        showErrorMessageDialog("Ungültige Wünsche-Datei!", "Fehler - Download des Zeitplans");
        return;
      }
     
      eveningSchedule = wishesReader.getEveningSchedule();
      parentsTreeModell.setEveningSchedule(eveningSchedule);
      teachersTreeModell.setEveningSchedule(eveningSchedule);
      splitPane.resetToPreferredSizes();
    }
    catch (FileNotFoundException e) {
      e.printStackTrace();
      showErrorMessageDialog("Konnte angegebene Seite nicht finden!\n" + e.getLocalizedMessage(), "Fehler - Download des Zeitplans");
      return;
    }   
    catch (IOException e) {
      e.printStackTrace();
      showErrorMessageDialog("Konnte Zeitplan nicht herunterladen!\n" + e.getLocalizedMessage(), "Fehler - Download des Zeitplans");
      return;
    }   
    catch (Exception e) {
      e.printStackTrace();
      showErrorMessageDialog("Ein unerwarteter Fehler ist aufgetreten!\n" + e.getLocalizedMessage(), "Fehler - Download des Zeitplans");
      return;
    }   
  }
 
  private void askOptimizationSettings() {
    Properties properties = application.getProperties();
    OptimizationSettingsDialog dlg = new OptimizationSettingsDialog(this);
   
    dlg.setMaxMaxWaitTime(maxMaxWaitTime);
    dlg.setMaxAvgWaitTime(maxAvgWaitTime);
   
    if(dlg.showDialog()) {
      maxMaxWaitTime = dlg.getMaxMaxWaitTime();
      maxAvgWaitTime = dlg.getMaxAvgWaitTime();
     
      properties.setProperty("eva.optimization.maxmaxwaittime", String.valueOf(maxMaxWaitTime.getMillis()));
      properties.setProperty("eva.optimization.maxavgwaittime", String.valueOf(maxAvgWaitTime.getMillis()));
   
  }
 
  private void askSettings() {
    SettingsDialog dlg = new SettingsDialog(this);
    /*
     * use a clone of the application settings, because we don't want to
     * keep the old settings if Cancel is pressed
     */
    Properties properties = (Properties) application.getProperties().clone();
   
    dlg.setSettings(properties);
   
    if(dlg.showDialog()) {
      Properties newProperties = dlg.getSettings();
      application.setProperties(newProperties);
      loadProperties(); //update properties reference of this frame
    }
  }
 
  private void showErrorMessageDialog(String msg, String title) {
    JOptionPane.showMessageDialog(this, msg, title, JOptionPane.ERROR_MESSAGE);
  }

}
TOP

Related Classes of eva.gui.MainFrame

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.