/* This file is part of Wattzap Community Edition. * * Wattzap Community Edtion 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. * * Wattzap Community Edition 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 Wattzap. If not, see <http://www.gnu.org/licenses/>. */ package com.wattzap.view.prefs; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; import java.util.MissingResourceException; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JTextField; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import net.miginfocom.swing.MigLayout; import com.wattzap.controller.MessageBus; import com.wattzap.controller.MessageCallback; import com.wattzap.controller.Messages; import com.wattzap.model.UserPreferences; import com.wattzap.model.power.Power; import com.wattzap.model.power.PowerProfiles; /* * Preferences main panel * * @author David George (c) Copyright 2013-2015 * @date 19 June 2013 */ //TODO: Add video directory location public class Preferences extends JFrame implements ActionListener, MessageCallback { private static final long serialVersionUID = 2396482595423749504L; // personal data JTextField weight; JTextField bikeWeight; JTextField wheelSize; JTextField maxHR; JTextField maxPwr; JCheckBox units; JCheckBox screenshot; JButton saveButton; JButton cancelButton; JTabbedPane jtp; JLabel wheelLabel; JLabel weightLabel; JLabel bikeWeightLabel; JLabel hrLabel; JLabel pwrLabel; JLabel langLabel; private final JComboBox languageList = new JComboBox(); // Supported languages for dropdown TODO make this dynamic private final Locale[] locales = { new Locale("cs"), new Locale("nl"), new Locale("en"), new Locale("fr"), new Locale("de"), new Locale("hu"), new Locale("it"), new Locale("es") }; private final TurboPanel trainerPanel; private AntPanel antPanel = null; private final SocialPanel socialPanel; private final UserPreferences userPrefs = UserPreferences.INSTANCE; private static Logger logger = LogManager.getLogger("Preferences"); public Preferences() { ImageIcon img = new ImageIcon("icons/preferences.jpg"); setIconImage(img.getImage()); jtp = new JTabbedPane(); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(jtp, BorderLayout.CENTER); contentPane.setBackground(Color.lightGray); // Personal Data JPanel userPanel = new JPanel(); userdata(userPanel); // Trainer Profiles trainerPanel = new TurboPanel(); // TAB-0 Personal Data jtp.addTab(null, userPanel); jtp.addTab("Trainer", trainerPanel); if (userPrefs.isAntEnabled()) { // ANT+ Pairing antPanel = new AntPanel(); jtp.addTab("ANT+", antPanel); } // Social Sharing socialPanel = new SocialPanel(); jtp.addTab("Social", socialPanel); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout()); saveButton = new JButton(); saveButton.setPreferredSize(new Dimension(150, 30)); saveButton.setActionCommand("save"); saveButton.addActionListener(this); buttonPanel.add(saveButton); cancelButton = new JButton(); cancelButton.setPreferredSize(new Dimension(120, 30)); cancelButton.setActionCommand("cancel"); cancelButton.addActionListener(this); buttonPanel.add(cancelButton); contentPane.add(buttonPanel, BorderLayout.SOUTH); pack(); // position centered above main window Rectangle bounds = this.getBounds(); Rectangle mainBounds = UserPreferences.INSTANCE.getMainBounds(); this.setBounds(mainBounds.x + ((mainBounds.width - bounds.width) / 2), mainBounds.y + ((mainBounds.height - bounds.height) / 2), bounds.width, bounds.height); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.setSize(450, 350); doText(); MessageBus.INSTANCE.register(Messages.LOCALE, this); } private void userdata(JPanel tab) { MigLayout layout = new MigLayout(); tab.setLayout(layout); // User Weight weightLabel = new JLabel(); weight = new JTextField(20); // Bike weight bikeWeightLabel = new JLabel(); bikeWeight = new JTextField(20); if (userPrefs.isMetric()) { weight.setText(String.format("%.1f", userPrefs.getWeight())); bikeWeight .setText(String.format("%.1f", userPrefs.getBikeWeight())); } else { weight.setText(String.format("%.0f", userPrefs.getWeight())); bikeWeight.setText("" + userPrefs.getBikeWeight()); } tab.add(weightLabel); tab.add(weight, "span"); tab.add(bikeWeightLabel); tab.add(bikeWeight, "span"); wheelLabel = new JLabel(); tab.add(wheelLabel); wheelSize = new JTextField(20); wheelSize.setText("" + userPrefs.getWheelsize()); tab.add(wheelSize, "span"); hrLabel = new JLabel(); tab.add(hrLabel); maxHR = new JTextField(20); maxHR.setText("" + userPrefs.getMaxHR()); tab.add(maxHR, "span"); pwrLabel = new JLabel(); tab.add(pwrLabel); maxPwr = new JTextField(20); maxPwr.setText("" + userPrefs.getMaxPower()); tab.add(maxPwr, "span"); units = new JCheckBox("Metric"); units.setSelected(userPrefs.isMetric()); units.setActionCommand("units"); units.addActionListener(this); tab.add(units); langLabel = new JLabel(); tab.add(langLabel); int index = 0; String lang = "eng"; // default try { lang = userPrefs.getLocale().getISO3Language(); } catch (MissingResourceException e) { // do nothing logger.error("missing resource " + e); } for (Locale locale : locales) { languageList.addItem(locale.getDisplayLanguage()); if (lang.equals(locale.getISO3Language())) { languageList.setSelectedIndex(index); } index++; } tab.add(languageList, "span"); screenshot = new JCheckBox("Auto Screenshot"); screenshot.setSelected(userPrefs.isScreenshot()); screenshot.setActionCommand("screenshot"); screenshot.addActionListener(this); tab.add(screenshot); } @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if ("save".equals(command)) { updatePreferences(); setVisible(false); // you can't see me! dispose(); // Destroy the JFrame object return; } else if ("units".equals(command)) { if (units.isSelected()) { weightLabel.setText(UserPreferences.INSTANCE .getString("your_weight") + " (kg) "); bikeWeightLabel.setText(UserPreferences.INSTANCE .getString("bike_weight") + " (kg) "); userPrefs.setUnits(true); weight.setText(String.format("%.1f", userPrefs.getWeight())); bikeWeight.setText(String.format("%.1f", userPrefs.getBikeWeight())); } else { weightLabel.setText(UserPreferences.INSTANCE .getString("your_weight") + " (lbs)"); bikeWeightLabel.setText(UserPreferences.INSTANCE .getString("bike_weight") + " (lbs)"); userPrefs.setUnits(false); weight.setText(String.format("%.1f", userPrefs.getWeight())); bikeWeight.setText(String.format("%.1f", userPrefs.getBikeWeight())); } } else if ("screenshot".equals(command)) { if (screenshot.isSelected()) { userPrefs.setScreenshot(true); } else { userPrefs.setScreenshot(false); } } else if ("cancel".equals(command)) { setVisible(false); // you can't see me! dispose(); // Destroy the JFrame object return; } setVisible(true); } public void updatePreferences() { // Number number = format.parse("1,234"); // double d = number.doubleValue(); userPrefs.setVirtualPower(trainerPanel.isVirtualPower()); int lang = languageList.getSelectedIndex(); Locale locale = locales[lang]; userPrefs.setLocale(locale.toString()); NumberFormat format = NumberFormat .getInstance(/* userPrefs.getLocale() */); try { Number number = format.parse(weight.getText()); userPrefs.setWeight(number.doubleValue()); number = format.parse(bikeWeight.getText()); userPrefs.setBikeWeight(number.doubleValue()); } catch (ParseException pe) { JOptionPane.showMessageDialog(this, pe.getMessage(), "Weight format error: ", JOptionPane.ERROR_MESSAGE); } try { Number number = format.parse(wheelSize.getText()); userPrefs.setWheelsize(number.intValue()); } catch (ParseException pe) { JOptionPane .showMessageDialog( this, pe.getMessage(), "Wheelsize format error, should be a whole number of millimeters: ", JOptionPane.ERROR_MESSAGE); } try { userPrefs.setMaxHR(Integer.parseInt(maxHR.getText())); } catch (NumberFormatException nfe) { JOptionPane .showMessageDialog( this, nfe.getMessage(), "HR format error, should be an integer between 100-220 bpm: ", JOptionPane.ERROR_MESSAGE); } try { userPrefs.setMaxPower(Integer.parseInt(maxPwr.getText())); } catch (NumberFormatException nfe) { JOptionPane.showMessageDialog(this, nfe.getMessage(), "Power format error: ", JOptionPane.ERROR_MESSAGE); } // set trainer String profile = trainerPanel.getProfileDescription(); PowerProfiles pp = PowerProfiles.INSTANCE; Power p = pp.getProfile(profile); userPrefs.setPowerProfile(profile); if (p.getResitanceLevels() > 1) { int level = trainerPanel.getResistanceLevel(); userPrefs.setResistance(level); } else { userPrefs.setResistance(1); } if (antPanel != null) { // check something is selected! if (!antPanel.scCheckBox.isSelected()) { if (!antPanel.hrmCheckBox.isSelected()) { if (!antPanel.speedCheckBox.isSelected()) { if (!antPanel.powCheckBox.isSelected()) { if (!antPanel.cadCheckBox.isSelected()) { JOptionPane.showMessageDialog(this, "No Ant Device Selected", userPrefs.getString("warning"), JOptionPane.WARNING_MESSAGE); } } } } } userPrefs.setSCId(antPanel.getSCId()); userPrefs.setSpeedId(antPanel.getSpeedId()); userPrefs.setCadenceId(antPanel.getCadenceId()); userPrefs.setHRMId(antPanel.getHRMId()); userPrefs.setPowerId(antPanel.getPwrId()); userPrefs.setPowerSmooth(antPanel.getSmoothing()); antPanel.close(); } // Social Panel userPrefs.setSLUser(socialPanel.getSLUser()); userPrefs.setSLPass(socialPanel.getSLPass()); } /** * Change text language if we get a LOCALE message */ @Override public void callback(Messages message, Object o) { switch (message) { case LOCALE: doText(); break; } } /* * Setup menubar text, makes it easy to update menu if locale is changed */ private void doText() { this.setTitle(UserPreferences.INSTANCE .getString("preferences")); saveButton.setText(UserPreferences.INSTANCE .getString("saveclose")); cancelButton.setText(UserPreferences.INSTANCE .getString("cancel")); jtp.setTitleAt(0, UserPreferences.INSTANCE.getString("personal_data")); if (userPrefs.isMetric()) { weightLabel.setText(UserPreferences.INSTANCE .getString("your_weight") + " (kg) "); bikeWeightLabel.setText(UserPreferences.INSTANCE .getString("bike_weight") + " (kg) "); } else { weightLabel.setText(UserPreferences.INSTANCE .getString("your_weight") + " (lbs)"); bikeWeightLabel.setText(UserPreferences.INSTANCE .getString("bike_weight") + " (lbs)"); } wheelLabel.setText(UserPreferences.INSTANCE .getString("wheel_size") + " (mm)"); hrLabel.setText("FT Heart Rate"); pwrLabel.setText(UserPreferences.INSTANCE.getString("ftp")); langLabel.setText(UserPreferences.INSTANCE .getString("selectLanguage")); } }