/**
  * Saves the current chart as an image in png format. The user can select the filename, and is
  * asked to confirm the overwrite of an existing file.
  */
 public void saveImage() {
   JFileChooser fc = new JFileChooser();
   if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
     File f = fc.getSelectedFile();
     if (f.exists()) {
       int ok =
           JOptionPane.showConfirmDialog(
               this,
               KstatResources.getString("SAVEAS.OVERWRITE.TEXT") + " " + f.toString(),
               KstatResources.getString("SAVEAS.CONFIRM.TEXT"),
               JOptionPane.YES_NO_OPTION);
       if (ok != JOptionPane.YES_OPTION) {
         return;
       }
     }
     BufferedImage bi = kbc.getChart().createBufferedImage(500, 300);
     try {
       ImageIO.write(bi, "png", f);
       /*
        * According to the API docs this should throw an IOException
        * on error, but this doesn't seem to be the case. As a result
        * it's necessary to catch exceptions more generally. Even this
        * doesn't work properly, but at least we manage to convey the
        * message to the user that the write failed, even if the
        * error itself isn't handled.
        */
     } catch (Exception ioe) {
       JOptionPane.showMessageDialog(
           this,
           ioe.toString(),
           KstatResources.getString("SAVEAS.ERROR.TEXT"),
           JOptionPane.ERROR_MESSAGE);
     }
   }
 }
  /**
   * Create the File... Menu.
   *
   * @return the File Menu
   */
  protected JMenu fileMenu() {
    JMenu jme = new JMenu(KstatResources.getString("FILE.TEXT"));
    jme.setMnemonic(KeyEvent.VK_F);

    saveItem = new JMenuItem(KstatResources.getString("FILE.SAVEAS.TEXT"), KeyEvent.VK_S);
    saveItem.addActionListener(this);
    jme.add(saveItem);
    jme.addSeparator();
    exitItem = new JMenuItem(KstatResources.getString("FILE.CLOSE.TEXT"), KeyEvent.VK_C);
    exitItem.addActionListener(this);
    jme.add(exitItem);
    return jme;
  }
 /**
  * Create the Statistics Menu, showing all available statistics for the chosen ChartableKstat.
  *
  * @param cks the ChartableKstat to show the statistics of in the menu
  * @param statistics the initial statistics, which will be checked
  * @return the Statistics Menu
  */
 protected JMenu statisticsMenu(ChartableKstat cks, List<String> statistics) {
   JMenu jmstat = new JMenu(KstatResources.getString("CHART.SHOW"));
   jmstat.setMnemonic(KeyEvent.VK_S);
   for (String stat : cks.getStatistics()) {
     JCheckBoxMenuItem jmi = new JCheckBoxMenuItem(stat, statistics.contains(stat));
     jmi.addActionListener(this);
     jmstat.add(jmi);
   }
   return jmstat;
 }
  /**
   * Create the Sleep for... Menu.
   *
   * @return the Sleep Menu
   */
  protected JMenu sleepMenu() {
    JMenu jms = new JMenu(KstatResources.getString("SLEEP.TEXT"));
    jms.setMnemonic(KeyEvent.VK_U);
    sleepItem1 = new JRadioButtonMenuItem(KstatResources.getString("SLEEP.1"));
    sleepItem1.addActionListener(this);
    sleepItem2 = new JRadioButtonMenuItem(KstatResources.getString("SLEEP.2"));
    sleepItem2.addActionListener(this);
    sleepItem5 = new JRadioButtonMenuItem(KstatResources.getString("SLEEP.5"), true);
    sleepItem5.addActionListener(this);
    sleepItem10 = new JRadioButtonMenuItem(KstatResources.getString("SLEEP.10"));
    sleepItem10.addActionListener(this);
    jms.add(sleepItem1);
    jms.add(sleepItem2);
    jms.add(sleepItem5);
    jms.add(sleepItem10);

    ButtonGroup sleepGroup = new ButtonGroup();
    sleepGroup.add(sleepItem1);
    sleepGroup.add(sleepItem2);
    sleepGroup.add(sleepItem5);
    sleepGroup.add(sleepItem10);

    return jms;
  }