/******************************************************************************* * Copyright (c) 2010 Stefan A. Tzeggai. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Stefan A. Tzeggai - initial API and implementation ******************************************************************************/ package org.geopublishing.geopublisher.gui.group; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import org.apache.log4j.Logger; import org.geopublishing.atlasViewer.GpCoreUtil; import org.geopublishing.atlasViewer.dp.DpEntry; import org.geopublishing.atlasViewer.dp.DpRef; import org.geopublishing.atlasViewer.dp.Group; import org.geopublishing.atlasViewer.map.Map; import org.geopublishing.atlasViewer.map.MapRef; import org.geopublishing.geopublisher.gui.internal.GPDialogManager; import org.geopublishing.geopublisher.swing.GeopublisherGUI; import de.schmitzm.jfree.chart.style.ChartStyle; /** * This JPanel shows the {@link Group}s tree. New children can be added by * Drag'n'Drop and {@link Group}s can be created, edited and deleted. * * @author Stefan Alfons Tzeggai */ public class EditGroupsDnDJTreePanel extends JPanel { static final private Logger LOGGER = Logger .getLogger(EditGroupsDnDJTreePanel.class); private final Group rootGroup; private JScrollPane groupsTreeScrollPane = null; // private JPanel buttonPanel; // private JButton editGroupJButton; // private JButton deleteGroupJButton; private DnDJTree dndTree; /** * Creates a new {@link EditGroupsDnDJTreePanel} that allows to reorder the * {@link JTree} by D'n'D and has buttons to add, delete and edit * {@link Group}s * * @param rootGroup * {@link Group} to be represented */ public EditGroupsDnDJTreePanel(final Group rootGroup) { this.rootGroup = rootGroup; setLayout(new BorderLayout()); add(getGroupsTreeScrollPane(rootGroup), BorderLayout.CENTER); // add(getButtonPanel(), BorderLayout.SOUTH); /** * Add a Listener to the MapPool to update the GroupTree whenever the * MapPool changed. */ rootGroup.getAc().getMapPool() .addChangeListener(new PropertyChangeListener() { @Override public void propertyChange(final PropertyChangeEvent evt) { updateJTree(null); } }); /** * Add a Listener to the DataPool to update the GroupTree whenever the * DataPool changed. Note: ATM the listener is never removed :-/ */ rootGroup.getAc().getDataPool() .addChangeListener(new PropertyChangeListener() { @Override public void propertyChange(final PropertyChangeEvent evt) { updateJTree(null); } }); /** * Setting tool-tips so the users know how to handle this Panel */ setToolTipText(GeopublisherGUI.R("EditGroupsDnDJTreePanel.TT")); getJTree().setToolTipText( GeopublisherGUI.R("EditGroupsDnDJTreePanel.TT")); } /** * @param rootGroup * If the {@link GroupsTreeScrollPane} has to be newly created, * only then a {@link Group} is needed * @return New or lazy {@link GroupsTreeScrollPane} */ private JScrollPane getGroupsTreeScrollPane(final Group rootGroup) { if (groupsTreeScrollPane == null) { groupsTreeScrollPane = new JScrollPane(getJTree()); } return groupsTreeScrollPane; } /** * @return The {@link JTree} - actually a {@link DnDJTree} - that hold all * the menu and menu-items together. */ public final DnDJTree getJTree() { if (dndTree == null) { if (rootGroup == null) throw new IllegalStateException("The rootGroup has to be set!"); dndTree = new DnDJTree(); dndTree.setModel(new DefaultTreeModel(rootGroup)); // Only allow single selections dndTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); dndTree.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(final MouseEvent e) { /* * In any case select the clicked node in the tree */ final Point clickPoint = e.getPoint(); final TreePath path = dndTree.getPathForLocation( clickPoint.x, clickPoint.y); if (path == null) { // LOGGER.warn("not on a node"); return; } final TreeNode clickedNode = (TreeNode) path .getLastPathComponent(); dndTree.setSelectionPath(path); /* * If a Map of Dpe is clicked, select it in the pools */ { if (clickedNode instanceof MapRef) { MapRef mapRef = (MapRef) clickedNode; final Map targetMap = mapRef.getTarget(); // Select the Entry in the table GeopublisherGUI.getInstance().getJFrame() .getMappoolJTable() .select(targetMap.getId()); } else if (clickedNode instanceof DpRef<?>) { final DpEntry<? extends ChartStyle> targetDpe = ((DpRef<DpEntry<? extends ChartStyle>>) clickedNode) .getTarget(); // Select the Entry in the table GeopublisherGUI.getInstance().getJFrame() .getDatapoolJTable() .select(targetDpe.getId()); } } /* * Open a PopupMenu if the right mouse button was pressed. * Start the default action if double-clicked. */ if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3) // The right mouse opens the popup { new GroupJPopupMenu(EditGroupsDnDJTreePanel.this, clickedNode, rootGroup).show( e.getSource() instanceof Component ? (Component) e .getSource() : EditGroupsDnDJTreePanel.this, clickPoint.x, clickPoint.y); } else if (e.getClickCount() == 2) // Double lick starts a default action { if (clickedNode instanceof MapRef) { final Map map = ((MapRef) clickedNode).getTarget(); GPDialogManager.dm_MapComposer.getInstanceFor(map, EditGroupsDnDJTreePanel.this, map); } else if (clickedNode instanceof DpRef<?>) { final DpEntry<? extends ChartStyle> dpe = ((DpRef<DpEntry<? extends ChartStyle>>) clickedNode) .getTarget(); GPDialogManager.dm_EditDpEntry.getInstanceFor(dpe, EditGroupsDnDJTreePanel.this, dpe); } } } }); dndTree.setCellRenderer(new GroupTreeCellRenderer()); } return dndTree; } // // /** // * @return JPanel wit Edit, Create and Delete Button // */ // private JPanel getButtonPanel() { // if (buttonPanel == null) { // buttonPanel = new JPanel(); // // buttonPanel.add(getNewGroupJButton()); // buttonPanel.add(getDeleteGroupJButton()); // buttonPanel.add(getEditGroupJButton()); // } // // return buttonPanel; // } // // /** // * @return {@link JButton} that deletes the selected {@link Group} or the // * Group element that is selected. // */ // private JButton getDeleteGroupJButton() { // if (deleteGroupJButton == null) { // // deleteGroupJButton = new JButton(); // deleteGroupJButton.setEnabled(false); // // // Adding a listener // JTree dndJTree = getJTree(); // TreeSelectionModel selectionModel = dndJTree.getSelectionModel(); // selectionModel // .addTreeSelectionListener(new TreeSelectionListener() { // // public void valueChanged(TreeSelectionEvent e) { // Object source = e.getSource(); // if (source instanceof DefaultTreeSelectionModel) { // DefaultTreeSelectionModel s = (DefaultTreeSelectionModel) source; // if (s.getSelectionPath() == null) { // deleteGroupJButton.setEnabled(false); // } else { // deleteGroupJButton.setEnabled(true); // } // } else { // deleteGroupJButton.setEnabled(false); // } // } // // }); // // deleteGroupJButton.setAction(new // GroupTreeDeleteAction(EditGroupsDnDJTreePanel.this)); // } // return deleteGroupJButton; // } /** * Recreate the tree * * @param expandToThisNode * may be <code>null</code> */ public void updateJTree(final TreeNode expandToThisNode) { // Maybe not the best way, but this makes the JTree update // the change getJTree().setModel(new DefaultTreeModel(rootGroup)); if (expandToThisNode != null) getJTree().expandPath(GpCoreUtil.getPath(expandToThisNode)); repaint(); } // // /** // * @return A {@link JButton} that changes ask the user to change the name // + // * description of the selected {@link Group} // */ // private JButton getEditGroupJButton() { // // if (editGroupJButton == null) { // // editGroupJButton = new JButton(new GroupTreeEditAction( // EditGroupsDnDJTreePanel.this) { // // }); // editGroupJButton.setEnabled(false); // // // Adding a listener // JTree dndJTree = getJTree(); // TreeSelectionModel selectionModel = dndJTree.getSelectionModel(); // selectionModel // .addTreeSelectionListener(new TreeSelectionListener() { // // public void valueChanged(TreeSelectionEvent e) { // Object source = e.getSource(); // if (source instanceof DefaultTreeSelectionModel) { // DefaultTreeSelectionModel s = (DefaultTreeSelectionModel) source; // TreePath selectionPath = s.getSelectionPath(); // if (selectionPath == null) { // editGroupJButton.setEnabled(false); // } else { // Object node = selectionPath // .getLastPathComponent(); // if (node instanceof Group) { // editGroupJButton.setEnabled(true); // } else // editGroupJButton.setEnabled(false); // } // } else { // editGroupJButton.setEnabled(false); // } // } // // }); // // } // return editGroupJButton; // } // // /** // * @return A {@link JButton} that creates a new {@link Group} at either // the // * root entry or the selected entry. // */ // private JButton getNewGroupJButton() { // final JButton newGroupJButton = new JButton(); // // newGroupJButton.setAction(new AbstractAction(Geopublisher // .R("GroupTree.Action.New"), Icons.ICON_ADD_SMALL) { // // public void actionPerformed(final ActionEvent e) { // final Group newGroup = new Group(rootGroup.getAc()); // // final EditGroupJDialog editGroupGUI = new EditGroupJDialog( // SwingUtil.getParentWindow(EditGroupsDnDJTreePanel.this), // newGroup); // editGroupGUI.setVisible(true); // // if (editGroupGUI.isCancelled()) // return; // // final JTree dndJTree = getJTree(); // final TreeSelectionModel selectionModel = dndJTree // .getSelectionModel(); // // DefaultTreeModel treeModel = (DefaultTreeModel) dndJTree // // .getModel(); // // if (selectionModel.isSelectionEmpty()) // // If nothing is selected, create a new Group in the // // rootGroup // { // rootGroup.add(newGroup); // } else { // // Something is selected, create a new Group at the // // first selection // final TreePath selectionPath = selectionModel // .getSelectionPath(); // final Object node = selectionPath.getLastPathComponent(); // if (node instanceof Group) { // final Group targetGroup = (Group) node; // targetGroup.add(newGroup); // } else { // LOGGER // .warn("Can't insert a new group at selection. Adding to default rootGroup"); // rootGroup.add(newGroup); // } // } // // // Maybe not the best way, but this makes the JTree update // // the change // dndJTree.setModel(new DefaultTreeModel(rootGroup)); // dndJTree.expandPath(AVUtil.getPath(newGroup)); // repaint(); // } // }); // // return newGroupJButton; // } public Group getRootGroup() { return rootGroup; } }