/* Copyright (c) 2008-2010, developers of the Ascension Log Visualizer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package com.googlecode.logVisualizer.gui; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.WindowConstants; import javax.swing.filechooser.FileFilter; import org.jfree.ui.RefineryUtilities; import com.googlecode.logVisualizer.chart.turnrundownGantt.TurnAreaCategory; import com.googlecode.logVisualizer.chart.turnrundownGantt.TurnrundownGantt; import com.googlecode.logVisualizer.logData.turn.TurnInterval; import com.googlecode.logVisualizer.util.CategoryViewFileHandler; public final class LocationCategoryCustomizer extends JDialog { /** * */ private static final long serialVersionUID = -5853302439038344217L; private static final FileFilter CATEGORY_VIEW_FILES = new FileFilter() { @Override public boolean accept(final File f) { return f.isDirectory() || f.getName().toLowerCase().endsWith(".cvw"); } @Override public String getDescription() { return "Category Views"; } }; private final TurnrundownGantt turnrundownChart; private final JFileChooser viewChooser; private JSplitPane splitter; private JButton deleteCategory; private JButton addLoation; private JButton removeArea; private JButton addCategory; private JButton updateChart; private JButton loadCategoryView; private JButton saveCategoryView; private JTextField categoryName; private JComboBox<TurnAreaCategory> categoryList; private JList<String> categoryInventory; private JList<String> areas; private JList<String> areasAddList; /** * @param owner * The JFrame which owns this dialog. * @param turnrundownChart * The turnrundown gantt chart on which certain actions can be * performed. */ public LocationCategoryCustomizer(final JFrame owner, final TurnrundownGantt turnrundownChart) { super(owner, true); this.turnrundownChart = turnrundownChart; this.viewChooser = new JFileChooser(); this.viewChooser .setFileSelectionMode(ListSelectionModel.SINGLE_SELECTION); this.viewChooser .setFileFilter(LocationCategoryCustomizer.CATEGORY_VIEW_FILES); this.setLayout(new GridBagLayout()); this.addGUIElements(); this.addActions(); this.addToolTips(); this.updateData(); this.pack(); this.setTitle("Area categories customization"); RefineryUtilities.centerFrameOnScreen(this); this.splitter.setDividerLocation(0.6); this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); this.setVisible(true); } private void addGUIElements() { this.splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT); this.updateChart = new JButton("Update Chart"); this.loadCategoryView = new JButton("Load Category View"); this.saveCategoryView = new JButton("Save Category View"); final JPanel categoryCreaterPane = new JPanel(new GridLayout(1, 0, 20, 5)); GridBagConstraints gbc; categoryCreaterPane.add(this.createAreaAddingPane()); categoryCreaterPane.add(this.createCategoryAddingPane()); this.splitter.setTopComponent(categoryCreaterPane); this.splitter.setBottomComponent(this.createCategoryPane()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 3; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(5, 5, 5, 5); this.add(this.splitter, gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.fill = GridBagConstraints.VERTICAL; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(25, 5, 5, 0); this.add(this.loadCategoryView, gbc); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 2; gbc.fill = GridBagConstraints.VERTICAL; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(25, 5, 5, 5); this.add(this.saveCategoryView, gbc); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 2; gbc.fill = GridBagConstraints.VERTICAL; gbc.ipadx = 150; gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(25, 0, 5, 5); this.add(this.updateChart, gbc); } private JPanel createCategoryPane() { final JPanel categoryPane = new JPanel(new GridBagLayout()); this.categoryInventory = new JList<>(new DefaultListModel<>()); this.deleteCategory = new JButton("Delete Category"); this.categoryList = new JComboBox<>(); GridBagConstraints gbc; this.categoryInventory .setSelectionMode(ListSelectionModel.SINGLE_SELECTION); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(5, 0, 5, 0); categoryPane.add(new JScrollPane(this.categoryInventory), gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.fill = GridBagConstraints.BOTH; categoryPane.add(this.deleteCategory, gbc); gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; categoryPane.add(this.categoryList, gbc); return categoryPane; } private JPanel createAreaAddingPane() { final JPanel areaAddingPane = new JPanel(new GridBagLayout()); this.areas = new JList<>(new DefaultListModel<>()); this.addLoation = new JButton("Add Area"); GridBagConstraints gbc; this.areas.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.insets = new Insets(0, 0, 5, 0); areaAddingPane.add(new JScrollPane(this.areas), gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.fill = GridBagConstraints.BOTH; areaAddingPane.add(this.addLoation, gbc); return areaAddingPane; } private JPanel createCategoryAddingPane() { final JPanel categoryAddingPane = new JPanel(new GridBagLayout()); this.areasAddList = new JList<>(new DefaultListModel<>()); this.categoryName = new JTextField(); this.addCategory = new JButton("Create Category"); this.removeArea = new JButton("Remove Area"); final JLabel categoryNameL = new JLabel("Category name:"); GridBagConstraints gbc; this.areasAddList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.insets = new Insets(5, 0, 5, 0); categoryAddingPane.add(new JScrollPane(this.areasAddList), gbc); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.fill = GridBagConstraints.VERTICAL; gbc.ipadx = 150; gbc.anchor = GridBagConstraints.EAST; categoryAddingPane.add(this.categoryName, gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(0, 5, 0, 0); categoryAddingPane.add(categoryNameL, gbc); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 3; gbc.fill = GridBagConstraints.VERTICAL; gbc.anchor = GridBagConstraints.EAST; categoryAddingPane.add(this.addCategory, gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 3; gbc.fill = GridBagConstraints.VERTICAL; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(0, 0, 0, 10); categoryAddingPane.add(this.removeArea, gbc); return categoryAddingPane; } private void addActions() { this.categoryList.addItemListener(new ItemListener() { @Override public void itemStateChanged(final ItemEvent e) { if (LocationCategoryCustomizer.this.categoryList .getSelectedItem() != null) { ((DefaultListModel<String>) LocationCategoryCustomizer.this.categoryInventory .getModel()).removeAllElements(); for (final String s : LocationCategoryCustomizer.this.categoryList .getItemAt( LocationCategoryCustomizer.this.categoryList .getSelectedIndex()) .getTurnAreaNames()) { ((DefaultListModel<String>) LocationCategoryCustomizer.this.categoryInventory .getModel()).addElement(s); } } } }); this.addLoation.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { if (!LocationCategoryCustomizer.this.areas.isSelectionEmpty()) { ((DefaultListModel<String>) LocationCategoryCustomizer.this.areasAddList .getModel()) .addElement(LocationCategoryCustomizer.this.areas .getSelectedValue()); ((DefaultListModel<String>) LocationCategoryCustomizer.this.areas .getModel()) .remove(LocationCategoryCustomizer.this.areas .getSelectedIndex()); LocationCategoryCustomizer.this.areas.setSelectedIndex(0); LocationCategoryCustomizer.this.areasAddList .setSelectedIndex(0); } } }); this.areas.addMouseListener(new MouseListener() { @Override public void mouseClicked(final MouseEvent e) { if (e.getClickCount() >= 2) { if (!LocationCategoryCustomizer.this.areas .isSelectionEmpty()) { ((DefaultListModel<String>) LocationCategoryCustomizer.this.areasAddList .getModel()) .addElement(LocationCategoryCustomizer.this.areas .getSelectedValue()); ((DefaultListModel<String>) LocationCategoryCustomizer.this.areas .getModel()) .remove(LocationCategoryCustomizer.this.areas .getSelectedIndex()); LocationCategoryCustomizer.this.areas .setSelectedIndex(0); LocationCategoryCustomizer.this.areasAddList .setSelectedIndex(0); } } } @Override public void mouseEntered(final MouseEvent e) { } @Override public void mouseExited(final MouseEvent e) { } @Override public void mousePressed(final MouseEvent e) { } @Override public void mouseReleased(final MouseEvent e) { } }); this.removeArea.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { if (!LocationCategoryCustomizer.this.areasAddList .isSelectionEmpty()) { LocationCategoryCustomizer.this .addLocation(LocationCategoryCustomizer.this.areasAddList .getSelectedValue()); ((DefaultListModel<String>) LocationCategoryCustomizer.this.areasAddList .getModel()) .remove(LocationCategoryCustomizer.this.areasAddList .getSelectedIndex()); LocationCategoryCustomizer.this.areas.setSelectedIndex(0); LocationCategoryCustomizer.this.areasAddList .setSelectedIndex(0); } } }); this.areasAddList.addMouseListener(new MouseListener() { @Override public void mouseClicked(final MouseEvent e) { if (e.getClickCount() >= 2) { if (!LocationCategoryCustomizer.this.areasAddList .isSelectionEmpty()) { LocationCategoryCustomizer.this .addLocation(LocationCategoryCustomizer.this.areasAddList .getSelectedValue()); ((DefaultListModel<String>) LocationCategoryCustomizer.this.areasAddList .getModel()) .remove(LocationCategoryCustomizer.this.areasAddList .getSelectedIndex()); LocationCategoryCustomizer.this.areas .setSelectedIndex(0); LocationCategoryCustomizer.this.areasAddList .setSelectedIndex(0); } } } @Override public void mouseEntered(final MouseEvent e) { } @Override public void mouseExited(final MouseEvent e) { } @Override public void mousePressed(final MouseEvent e) { } @Override public void mouseReleased(final MouseEvent e) { } }); this.addCategory.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { LocationCategoryCustomizer.this.addCategory(); } }); this.categoryName.addKeyListener(new KeyListener() { @Override public void keyPressed(final KeyEvent e) { if (e.getKeyChar() == '\n') { LocationCategoryCustomizer.this.addCategory(); } } @Override public void keyReleased(final KeyEvent e) { } @Override public void keyTyped(final KeyEvent e) { } }); this.deleteCategory.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { if (LocationCategoryCustomizer.this.categoryList .getSelectedItem() != null) { LocationCategoryCustomizer.this.turnrundownChart .getCategories() .remove(LocationCategoryCustomizer.this.categoryList .getSelectedIndex()); LocationCategoryCustomizer.this.updateData(); } } }); this.updateChart.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { LocationCategoryCustomizer.this.dispose(); } }); this.loadCategoryView.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { final int state = LocationCategoryCustomizer.this.viewChooser .showOpenDialog(null); if (state == JFileChooser.APPROVE_OPTION) { try { LocationCategoryCustomizer.this.turnrundownChart.setCategories(CategoryViewFileHandler .parseOutCategories(LocationCategoryCustomizer.this.viewChooser .getSelectedFile())); LocationCategoryCustomizer.this.updateData(); } catch (final IOException e1) { e1.printStackTrace(); } } } }); this.saveCategoryView.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { final int state = LocationCategoryCustomizer.this.viewChooser .showSaveDialog(null); if (state == JFileChooser.APPROVE_OPTION) { try { CategoryViewFileHandler .createCategoryViewFile( LocationCategoryCustomizer.this.turnrundownChart .getCategories(), LocationCategoryCustomizer.this.viewChooser .getSelectedFile()); } catch (final IOException e1) { e1.printStackTrace(); } } } }); } private void addToolTips() { this.deleteCategory .setToolTipText("Delete the currently selected category"); this.addLoation .setToolTipText("Add an area to the current category in construction"); this.removeArea .setToolTipText("Remove an area from the current category in construction"); this.addCategory .setToolTipText("<html>Saves the category in the category list. Note that you" + "<p>need to name a category before you can save it.</p></html>"); this.updateChart .setToolTipText("<html>Closes this window and updates the turn rundown gantt" + "<p>chart with the new category configuration.</p></html>"); this.loadCategoryView .setToolTipText("Load a previously saved category configuration"); this.saveCategoryView .setToolTipText("Save the current category configuration to a file for future use"); this.categoryName .setToolTipText("<html>Name of the current category in construction. Note that you" + "<p>need to name a category before you can save it.</p></html>"); this.categoryList.setToolTipText("List of categories currently used"); this.categoryInventory .setToolTipText("List of all areas inside the currently selected category"); this.areas .setToolTipText("<html>All uncategorized areas. Every location in here will" + "<p>be its own category in the turn rundown gantt chart.</p></html>"); this.areasAddList .setToolTipText("List of all areas inside the category currently in construction"); } void updateData() { ((DefaultListModel<String>) this.areas.getModel()).removeAllElements(); ((DefaultListModel<String>) this.areasAddList.getModel()) .removeAllElements(); ((DefaultListModel<String>) this.categoryInventory.getModel()) .removeAllElements(); this.categoryName.setText(""); this.updateCategoryList(); final List<String> areaNames = new ArrayList<>(200); for (final TurnInterval ti : this.turnrundownChart.getLogData() .getTurnsSpent()) { final boolean isInLocationList = areaNames.contains(ti .getAreaName()); if (!isInLocationList && !this.isInCategories(ti.getAreaName())) { areaNames.add(ti.getAreaName()); } } Collections.sort(areaNames); for (final String s : areaNames) { ((DefaultListModel<String>) this.areas.getModel()).addElement(s); } this.areas.setSelectedIndex(0); } private void updateCategoryList() { this.categoryList.removeAllItems(); for (final TurnAreaCategory tlc : this.turnrundownChart.getCategories()) { this.categoryList.addItem(tlc); } } private boolean isInCategories(final String area) { for (int i = 0; i < this.categoryList.getItemCount(); i++) { for (final String s : this.categoryList.getItemAt(i) .getTurnAreaNames()) { if (area.startsWith(s)) { return true; } } } return false; } void addLocation(final String areaName) { final List<String> areaNames = new ArrayList<>(200); for (int i = 0; i < ((DefaultListModel<String>) this.areas.getModel()) .getSize(); i++) { areaNames.add(((DefaultListModel<String>) this.areas.getModel()) .get(i)); } areaNames.add(areaName); Collections.sort(areaNames); ((DefaultListModel<String>) this.areas.getModel()).removeAllElements(); for (final String s : areaNames) { ((DefaultListModel<String>) this.areas.getModel()).addElement(s); } } void addCategory() { if (!this.areasAddList.isSelectionEmpty() && !this.categoryName.getText().equals("")) { final TurnAreaCategory tac = new TurnAreaCategory( this.categoryName.getText()); for (int i = 0; i < ((DefaultListModel<String>) this.areasAddList .getModel()).getSize(); i++) { tac.addTurnAreaName(((DefaultListModel<String>) this.areasAddList .getModel()).get(i)); } this.turnrundownChart.addCategory(tac); this.updateData(); } } @Override public void dispose() { super.dispose(); this.turnrundownChart.updateChart(); } }