package com.dreikraft.axbo; import com.dreikraft.axbo.controller.AxboFrameController; import com.dreikraft.axbo.controller.PreferencesController; import com.dreikraft.events.ApplicationEventDispatcher; import com.dreikraft.events.ApplicationEventEnabled; import com.dreikraft.events.ApplicationInitialize; import com.dreikraft.axbo.data.DeviceContext; import com.dreikraft.axbo.data.DeviceType; import com.dreikraft.axbo.data.SleepData; import com.dreikraft.axbo.model.ChartType; import com.dreikraft.axbo.model.SupportedLanguage; import com.dreikraft.axbo.sound.SoundPackage; import java.io.File; import java.io.FilenameFilter; import java.util.Locale; import java.util.prefs.Preferences; import java.util.regex.Pattern; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import org.apache.commons.logging.*; import org.jdesktop.swingx.JXHeader; import org.jdesktop.swingx.JXHyperlink; import org.jdesktop.swingx.JXMonthView; import org.jdesktop.swingx.plaf.basic.BasicHeaderUI; import org.jdesktop.swingx.plaf.basic.BasicHyperlinkUI; import org.jdesktop.swingx.plaf.basic.BasicMonthViewUI; /** * aXbo startup class. * * @author jan.illetschko@3kraft.com */ public final class Axbo implements ApplicationEventEnabled { public static final Log log = LogFactory.getLog(Axbo.class); // default dirs public static final String APPLICATION_DIR = "aXbo"; public static final String PROJECT_DIR_DEFAULT = System.getProperty( "user.home") + System.getProperty("file.separator") + Axbo.APPLICATION_DIR + System.getProperty("file.separator") + "projects"; public static final String SOUND_PACKAGES_DIR = System .getProperty("user.home") + System.getProperty("file.separator") + Axbo.APPLICATION_DIR + System.getProperty("file.separator") + "sounds"; // file constants public static final String SOUND_DATA_FILE_EXT = ".axs"; // images and icons public static final String BACKGROUND_IMAGE_DEFAULT = "/resources/images/background_soft.jpg"; public static final String ICON_IMAGE_DEFAULT = "/resources/images/32x32px_researchicon.png"; public static final String INTERNAL_ICON_IMAGE_DEFAULT = "/resources/images/32x32px_researchicon.png"; // sleep data constants public static final int MAX_MOVEMENTS_DEFAULT = 100; public static final long CLEANER_INTERVAL_DEFAULT = 3 * 60 * 60 * 1000; public static final float AVERAGE_MOVEMENTS_THRESHOLD = 10; public static final long MINIMUM_SLEEP_DURATION = 30 * 60 * 1000; public static final int MINIMUM_MOVEMENTS = 100; public static final int MAXIMUM_SLEEP_DURATION = 14 * 60 * 60 * 1000;; // === preferences === // serial port prefs public static final String SERIAL_PORT_NAME_PREF = "serialPort.name"; // language prefs public static final String LANGUAGE_PREF = "language"; // diagramm prefs public static final String TIME_PERIOD_CLASS_PREF = "timePeriodClass"; public static final String TIME_PERIOD_CLASS_DEFAULT = "org.jfree.data.time.Minute"; // deviceType pref public static final String DEVICE_TYPE_PREF = "deviceType"; public static final String DEVICE_TYPE_DEFAULT = "AXBO"; public static final int COMPARE_OFFSET = 12; public static final String STANDALONE_UPDATER_ID = "349"; public static final String SILENT_UPDATER_ID = "389"; // chart type public static final String CHART_TYPE_PREF = "chartType"; // === members === /** * Application singleton. */ private static final Axbo CONTROLLER = new Axbo(); public static void main(final String[] args) { Axbo controller = getApplicationController(); controller.init(); } public static Axbo getApplicationController() { return Axbo.CONTROLLER; } public static Preferences getApplicationPreferences() { return Preferences.userNodeForPackage(Axbo.class); } /** * Returns the currently configured chart type. * * @return the configured chart type */ public static ChartType getChartType() { return ChartType.valueOf(Axbo.getApplicationPreferences().get( Axbo.CHART_TYPE_PREF, ChartType.BAR.name())); } public static String getPortName() { return getApplicationPreferences().get(DeviceContext.getDeviceType() + "." + Axbo.SERIAL_PORT_NAME_PREF, OS.get().getDefaultPort()); } private Axbo() { super(); } @SuppressWarnings("ResultOfObjectAllocationIgnored") public void init() { // disable the security manager System.setSecurityManager(null); // register shutdown hook Runtime.getRuntime().addShutdownHook(new AxboShutdownHook()); // set desired locale try { final String langPref = getApplicationPreferences().get(LANGUAGE_PREF, Locale.getDefault().getLanguage()); final SupportedLanguage lang = SupportedLanguage.valueOf(langPref); Locale.setDefault(Locale.forLanguageTag(lang.name())); } catch (IllegalArgumentException ex) { Locale.setDefault(Locale.ENGLISH); log.warn(ex.getMessage(), ex); } if (log.isDebugEnabled()) log.debug("configured application locale: " + Locale.getDefault()); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { log.warn("failed to set system look & feel", ex); } // OSX laf System.setProperty("apple.laf.useScreenMenuBar", "true"); System.setProperty("apple.awt.brushMetalLook", "true"); // fix missing laf ui classes for used jx components UIManager.put(JXMonthView.uiClassID, BasicMonthViewUI.class.getName()); UIManager.put(JXHyperlink.uiClassID, BasicHyperlinkUI.class.getName()); UIManager.put(JXHeader.uiClassID, BasicHeaderUI.class.getName()); // create the application and project dir File appDir = new File(Axbo.PROJECT_DIR_DEFAULT); if (appDir.mkdirs()) log.warn("successfully created project dir: " + appDir.getAbsolutePath()); // create sound package dir File soundDir = new File(Axbo.SOUND_PACKAGES_DIR); if (soundDir.mkdirs()) log.info("successfully created sound dir: " + soundDir.getAbsolutePath()); // create view and model new AxboFrameController(); new PreferencesController(); // set the device type to aXbo (currently the only supported) DeviceContext.setDeviceType(DeviceType.AXBO); //initial ApplicationEventDispatcher.getInstance().dispatchGUIEvent( new ApplicationInitialize( this)); } public static class SPWFilenameFilter implements FilenameFilter { @Override public boolean accept(File dir, String name) { return Pattern.compile(SleepData.SLEEP_DATA_FILE_EXT_PATTERN, Pattern.CASE_INSENSITIVE).matcher(name).matches(); } }; public static class AXSFilenameFilter implements FilenameFilter { @Override public boolean accept(File dir, String name) { return Pattern.compile(SoundPackage.FILE_PATTERN, Pattern.CASE_INSENSITIVE).matcher(name).matches(); } }; } class AxboShutdownHook extends Thread { @Override public void run() { Preferences prefs = Preferences.userNodeForPackage(this.getClass()); try { System.out.println("cleaning up resources ..."); prefs.flush(); System.out.println("shutting down aXbo research"); } catch (Exception ex) { ex.printStackTrace(System.err); } } }