/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.gui.dialog.optionDialog; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeSelectionModel; import edu.yu.einstein.genplay.core.DAS.DASServerListWriter; import edu.yu.einstein.genplay.core.manager.application.ConfigurationManager; import edu.yu.einstein.genplay.exception.ExceptionManager; import edu.yu.einstein.genplay.util.Images; import edu.yu.einstein.genplay.util.Utils; /** * Dialog allowing to change the configuration of the program. * @author Julien Lajugie * @version 0.1 */ public final class OptionDialog extends JDialog implements TreeSelectionListener, PropertyChangeListener { private static final long serialVersionUID = 4050757943368845382L; // Generated ID private static final Dimension OPTION_DIALOG_DIMENSION = new Dimension(600, 400); // dimension of this window private final ConfigurationManager cm; // A ConfigurationManager private final JTree jt; // Tree private final JScrollPane jspTreeView; // Scroll pane containing the tree private final JPanel jpOption; // Panel containing the different panel of configuration private final JButton jbOk; // Button OK private final JButton jbCancel; // Button cancel private final JSplitPane jspDivider; // Divider between the tree and the panel private final String defaultDirectory; // default directory private final boolean showMenuBar; // show menu bar private final String lookAndFeel; // look and feel private final String dasServerListFile; // DAS Server List File private final int trackCount; // track count private final int trackHeight; // track height private final int undoCount; // undo count private final boolean resetTrack; // reset track feature private final boolean legend; // show legend (multi genome) private MemoryOptionPanel memoryOptionPanel = null; // panel for the install version of GenPlay on OSX to modify the max memory private int approved = CANCEL_OPTION; // Equals APPROVE_OPTION if user clicked OK, CANCEL_OPTION if not /** * Return value when OK has been clicked. */ public static final int APPROVE_OPTION = 0; /** * Return value when Cancel has been clicked. */ public static final int CANCEL_OPTION = 1; /** * Creates an instance of {@link OptionDialog} */ public OptionDialog() { super(); cm = ConfigurationManager.getInstance(); dasServerListFile = cm.getDASServerListFile(); defaultDirectory = cm.getDefaultDirectory(); lookAndFeel = cm.getLookAndFeel(); showMenuBar = cm.isMenuBarShown(); trackCount = cm.getTrackCount(); trackHeight = cm.getTrackHeight(); undoCount = cm.getUndoCount(); resetTrack = cm.isResetTrack(); legend = cm.isLegend(); DefaultMutableTreeNode top = new DefaultMutableTreeNode("Options"); createNodes(top); jt = new JTree(top); // hide the root node jt.setRootVisible(false); // hide the lines jt.setShowsRootHandles(true); // Remove the icon from the tree DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); renderer.setLeafIcon(null); renderer.setClosedIcon(null); renderer.setOpenIcon(null); jt.setCellRenderer(renderer); jt.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); jt.addTreeSelectionListener(this); jspTreeView = new JScrollPane(jt); jspTreeView.getVerticalScrollBar().setUnitIncrement(Utils.SCROLL_INCREMENT_UNIT); jpOption = new JPanel(); // Add the scroll panes to a split pane. jspDivider = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); jspDivider.setLeftComponent(jspTreeView); jspDivider.setBottomComponent(jpOption); jspDivider.setContinuousLayout(true); Dimension minimumSize = new Dimension(100, 1); jspTreeView.setMinimumSize(minimumSize); jpOption.setMinimumSize(minimumSize); jspDivider.setDividerLocation(OPTION_DIALOG_DIMENSION.width / 3); jbOk = new JButton("OK"); jbOk.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // save the data when okay has been pressed approved = APPROVE_OPTION; setVisible(false); try { ConfigurationManager.getInstance().writeConfiguration(); if (DASOptionPanel.tableChangedFlag == true) { cm.setDASServerListFile(cm.getDASServerListFile()); DASServerListWriter dasServerListWriter = new DASServerListWriter(); dasServerListWriter.write(DASOptionPanel.tableData, cm.getDASServerListFile()); } // if the memory option panel exist we write changes if needed if (memoryOptionPanel != null) { memoryOptionPanel.writeNewPList(); } } catch (IOException er) { JOptionPane.showMessageDialog(getRootPane(), "Error while saving the configuration", "Error", JOptionPane.ERROR_MESSAGE); ExceptionManager.getInstance().caughtException(er); } } }); jbCancel = new JButton("Cancel"); jbCancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setVisible(false); } }); // we want the size of the two buttons to be equal jbOk.setPreferredSize(jbCancel.getPreferredSize()); setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.weightx = 1; c.weighty = 0.99; c.gridx = 0; c.gridy = 0; c.gridwidth = 2; add(jspDivider, c); c.fill = GridBagConstraints.VERTICAL; c.weightx = 0.99; c.weighty = 0.01; c.gridx = 0; c.gridy = 1; c.gridwidth = 1; c.anchor = GridBagConstraints.LINE_END; add(jbOk, c); c.weightx = 0.01; c.gridx = 1; c.anchor = GridBagConstraints.LINE_START; add(jbCancel, c); jt.setSelectionRow(0); addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { // if the modification had been canceled we restore // the cm the way it was when the window was opened if (approved == CANCEL_OPTION) { cm.setDASServerListFile(dasServerListFile); cm.setDefaultDirectory(defaultDirectory); cm.setLookAndFeel(lookAndFeel); cm.setShowMenuBar(showMenuBar); cm.setTrackCount(trackCount); cm.setTrackHeight(trackHeight); cm.setUndoCount(undoCount); } } }); setTitle("Option"); setSize(OPTION_DIALOG_DIMENSION); setIconImages(Images.getApplicationImages()); setResizable(false); setModalityType(ModalityType.APPLICATION_MODAL); setLocationRelativeTo(getRootPane()); setDefaultCloseOperation(HIDE_ON_CLOSE); getRootPane().setDefaultButton(jbOk); } /** * Creates the data of the tree. * @param top Root DefaultMutableTreeNode of the tree. */ private void createNodes(DefaultMutableTreeNode top) { DefaultMutableTreeNode category = null; category = new DefaultMutableTreeNode(new GeneralOptionPanel()); top.add(category); category = new DefaultMutableTreeNode(new TrackOptionPanel()); top.add(category); category = new DefaultMutableTreeNode(new DASOptionPanel()); top.add(category); if(Utils.isMacInstall()) { try { memoryOptionPanel = new MemoryOptionPanel(); if (memoryOptionPanel != null) { category = new DefaultMutableTreeNode(memoryOptionPanel); top.add(category); } } catch (IOException e) { // do nothing } } category = new DefaultMutableTreeNode(new RestoreOptionPanel()); top.add(category); } /** * @return true if dasServerListFile changed */ public boolean dasServerListFileChanged() { return !dasServerListFile.equals(cm.getDASServerListFile()); } /** * @return true if defaultDirectory changed */ public boolean defaultDirectoryChanged() { return !defaultDirectory.equals(cm.getDefaultDirectory()); } /** * @return true if the legend parameter changed */ public boolean legendChanged() { return legend != cm.isLegend(); } /** * @return true if lookAndFeel changed */ public boolean lookAndFeelChanged() { return !lookAndFeel.equals(cm.getLookAndFeel()); } /** * Restores the data and regenerate the tree when the option restore * configuration is clicked. */ @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equalsIgnoreCase("reset")) { DefaultMutableTreeNode top = new DefaultMutableTreeNode("Options"); createNodes(top); jt.setModel(new DefaultTreeModel(top)); jt.revalidate(); jt.setSelectionRow(0); } } /** * @return true if the reset track parameter changed */ public boolean resetTrackChanged() { return resetTrack != cm.isResetTrack(); } /** * Shows the component. * @param parent the parent component of the dialog, can be null; see showDialog for details * @return APPROVE_OPTION is OK is clicked. CANCEL_OPTION otherwise. */ public int showConfigurationDialog(Component parent) { setLocationRelativeTo(parent); setVisible(true); return approved; } public boolean showMenuBarChanged() { return showMenuBar != cm.isMenuBarShown(); } /** * @return true if trackCount changed */ public boolean trackCountChanged() { return trackCount != cm.getTrackCount(); } /** * @return true if trackHeight changed */ public boolean trackHeightChanged() { return trackHeight != cm.getTrackHeight(); } /** * @return true if the undo count changed */ public boolean undoCountChanged() { return undoCount != cm.getUndoCount(); } /** * Changes the panel displayed when the node of the tree changes. */ @Override public void valueChanged(TreeSelectionEvent arg0) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) jt.getLastSelectedPathComponent(); jpOption.removeAll(); if ((node != null) && (node.isLeaf())) { Object nodeInfo = node.getUserObject(); if (nodeInfo != null) { jpOption.add((JPanel) nodeInfo); ((JPanel) nodeInfo).addPropertyChangeListener(this); } } jpOption.revalidate(); jpOption.repaint(); } }