reorganized Searchable Tree, new custom model

This commit is contained in:
bancika
2020-09-17 17:35:17 +02:00
parent d5b6a29fdd
commit 4f2e1db6d7
6 changed files with 580 additions and 463 deletions
@@ -3182,6 +3182,10 @@
<changeType>IMPROVEMENT</changeType> <changeType>IMPROVEMENT</changeType>
<description>Switched from iText to OrsonPDF library for PDF creation. Render text as vectors to ensure consistency with display and avoid font issues</description> <description>Switched from iText to OrsonPDF library for PDF creation. Render text as vectors to ensure consistency with display and avoid font issues</description>
</org.diylc.appframework.update.Change> </org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Rewritten most of the code behind Searchable Tree functionality to make it faster and more stable</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType> <changeType>IMPROVEMENT</changeType>
<description>Improved rendering precision, especially when using metric units</description> <description>Improved rendering precision, especially when using metric units</description>
+6 -9
View File
@@ -23,10 +23,8 @@
5PDT 5PDT
5PDT (Center OFF) 5PDT (Center OFF)
AWG AWG
Access User Files
And And
C-B-E BJT C-B-E BJT
Click the lighbulb icon in the bottom-right corner of the window for more info.
D-G-S JFET D-G-S JFET
D-G-S MOSFET D-G-S MOSFET
D-S-G JFET D-S-G JFET
@@ -39,6 +37,8 @@ DP5T
DPDT DPDT
DPDT (Center OFF) DPDT (Center OFF)
Deutsch Deutsch
Dimension Mode
Donate
E-B-C BJT E-B-C BJT
English English
Español Español
@@ -47,9 +47,11 @@ G-D-S JFET
G-D-S MOSFET G-D-S MOSFET
G-S-D JFET G-S-D JFET
G-S-D MOSFET G-S-D MOSFET
Inline
Italiano Italiano
Lin
Log
NPN NPN
Nand
Nederlands Nederlands
Nor Nor
Not Not
@@ -57,19 +59,14 @@ Or
PAF PAF
PCB PCB
PNP PNP
Round WOG A Rev log
Round WOG B
S-G-D JFET S-G-D JFET
S-G-D MOSFET S-G-D MOSFET
SMD SMD
SPDT SPDT
SPDT (Center OFF) SPDT (Center OFF)
SPST SPST
Selection is empty.
Soap Bar
Sprache
Srpski Srpski
Version history is not available.
Xnor Xnor
Xor Xor
cm cm
@@ -0,0 +1,364 @@
/*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
* DIYLC 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.
*
* DIYLC 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 DIYLC. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
package org.diylc.swing.plugins.tree;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.common.ComponentType;
import org.diylc.common.Favorite;
import org.diylc.common.IBlockProcessor.InvalidBlockException;
import org.diylc.common.IPlugInPort;
import org.diylc.core.IDIYComponent;
public class CustomTreeModel implements TreeModel {
private static final Logger LOG = Logger.getLogger(CustomTreeModel.class);
private IPlugInPort plugInPort;
private Object root = "root";
private String searchText = null;
private Map<String, List<ComponentType>> componentTypes;
private List<String> categories;
private List<TreeNode> visibleCategories;
private Map<String, List<TreeNode>> visibleLeaves;
private Map<String, ComponentType> typesByClass;
private List<Favorite> favorites;
private List<String> recentComponents;
private List<String> blocks;
private EventListenerList listenerList = new EventListenerList();
private static final String FAVORITES = "(Favorites)";
private static final String RECENTLY_USED = "(Recently Used)";
private static final String BUILDING_BLOCKS = "(Building Blocks)";
public CustomTreeModel(IPlugInPort plugInPort) {
super();
this.plugInPort = plugInPort;
this.componentTypes = plugInPort.getComponentTypes();
this.categories = new ArrayList<String>(this.componentTypes.keySet());
Collections.sort(this.categories);
this.categories.add(0, BUILDING_BLOCKS);
this.categories.add(0, RECENTLY_USED);
this.categories.add(0, FAVORITES);
this.visibleLeaves = new HashMap<String, List<TreeNode>>();
this.typesByClass = new HashMap<String, ComponentType>();
for (Map.Entry<String, List<ComponentType>> e : componentTypes.entrySet())
for (ComponentType c : e.getValue())
typesByClass.put(c.getInstanceClass().getCanonicalName(), c);
this.initialize();
updateVisibleCategories();
}
public String getSearchText() {
return searchText;
}
public void setSearchText(String searchText) {
this.searchText = searchText.toLowerCase();
updateVisibleCategories();
}
private void updateVisibleCategories() {
this.visibleCategories = new ArrayList<TreeNode>();
for (String category : this.categories)
if (categoryMatches(this.searchText, category))
this.visibleCategories.add(new TreeNode(category, null, false));
this.visibleLeaves.clear();
fireTreeStructureChanged(new Object[] { root });
}
private List<TreeNode> getLeavesFor(String category) {
if (this.visibleLeaves.containsKey(category))
return this.visibleLeaves.get(category);
List<TreeNode> visibleTypes = new ArrayList<TreeNode>();
if (FAVORITES.equals(category)) {
for (Favorite fav : this.favorites) {
ComponentType type = this.typesByClass.get(fav.getName());
if (this.searchText == null || type.getName().toLowerCase().contains(this.searchText)) {
visibleTypes.add(new TreeNode(type, new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
plugInPort.setNewComponentTypeSlot(type, null, false);
}
}));
}
}
}
if (RECENTLY_USED.equals(category)) {
for (String className : this.recentComponents) {
ComponentType type = this.typesByClass.get(className);
if (this.searchText == null || type.getName().toLowerCase().contains(this.searchText)) {
visibleTypes.add(new TreeNode(type, new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
plugInPort.setNewComponentTypeSlot(type, null, false);
}
}));
}
}
}
if (BUILDING_BLOCKS.equals(category)) {
for (String block : this.blocks) {
if (this.searchText == null || block.toLowerCase().contains(this.searchText)) {
visibleTypes.add(new TreeNode(block, new MouseAdapter() {
long previousActionTime = 0;
@Override
public void mouseClicked(MouseEvent e) {
if (e == null || SwingUtilities.isLeftMouseButton(e) && System.currentTimeMillis() - previousActionTime > 100) {
previousActionTime = System.currentTimeMillis();
try {
plugInPort.loadBlock(block);
} catch (InvalidBlockException e1) {
e1.printStackTrace();
}
}
}
}, true));
}
}
}
if (componentTypes.containsKey(category))
for (ComponentType type : componentTypes.get(category))
if (this.searchText == null
|| category.toLowerCase().contains(this.searchText.toLowerCase()) ||
typeMatches(this.searchText, type))
visibleTypes.add(new TreeNode(type, new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
plugInPort.setNewComponentTypeSlot(type, null, false);
}
}));
this.visibleLeaves.put(category, visibleTypes);
return visibleTypes;
}
private boolean typeMatches(String searchText, ComponentType type) {
if (searchText == null || searchText.isEmpty())
return true;
if (type.getName().toLowerCase().contains(searchText))
return true;
return false;
}
private boolean categoryMatches(String searchText, String category) {
if (searchText == null || searchText.isEmpty())
return true;
if (category.toLowerCase().contains(searchText))
return true;
if (FAVORITES.equals(category)) {
for (Favorite fav : this.favorites) {
ComponentType type = typesByClass.get(fav.getName());
if (type.getName().toLowerCase().contains(searchText))
return true;
}
}
if (RECENTLY_USED.equals(category)) {
for (String className : this.recentComponents) {
ComponentType type = typesByClass.get(className);
if (type.getName().toLowerCase().contains(searchText))
return true;
}
}
if (BUILDING_BLOCKS.equals(category)) {
for (String block : this.blocks) {
if (block.toLowerCase().contains(searchText))
return true;
}
}
if (componentTypes.containsKey(category))
for (ComponentType type : componentTypes.get(category))
if (typeMatches(searchText, type))
return true;
return false;
}
@Override
public Object getRoot() {
return root;
}
@Override
public Object getChild(Object parent, int index) {
if (parent == root)
return visibleCategories.get(index);
List<TreeNode> typesFor = getLeavesFor(parent.toString());
Object obj = typesFor.get(index);
return obj;
}
@Override
public int getChildCount(Object parent) {
if (parent == root)
return visibleCategories.size();
List<TreeNode> typesFor = getLeavesFor(parent.toString());
return typesFor.size();
}
@Override
public boolean isLeaf(Object node) {
if (node == root)
return false;
if (node instanceof TreeNode) {
TreeNode p = (TreeNode) node;
return p.isLeaf();
}
return true;
}
@Override
public void valueForPathChanged(TreePath path, Object newValue) {
// read only, nothing to do here
}
@Override
public int getIndexOfChild(Object parent, Object child) {
if (parent == root)
return visibleCategories.indexOf(child);
List<TreeNode> typesFor = getLeavesFor(parent.toString());
return typesFor.indexOf(child);
}
@Override
public void addTreeModelListener(TreeModelListener l) {
listenerList.add(TreeModelListener.class, l);
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
listenerList.remove(TreeModelListener.class, l);
}
protected void fireTreeStructureChanged(Object[] path) {
TreeModelEvent event = new TreeModelEvent(this, path);
EventListener[] listeners = listenerList.getListeners(TreeModelListener.class);
for (int i = 0; i < listeners.length; i++)
((TreeModelListener) listeners[i]).treeStructureChanged(event);
}
@SuppressWarnings("unchecked")
private void initialize() {
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.FAVORITES_KEY,
new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
List<Favorite> newFavorites = (List<Favorite>) value;
if (newFavorites != null && !newFavorites.equals(CustomTreeModel.this.favorites)) {
LOG.info("Detected favorites change");
CustomTreeModel.this.favorites = new ArrayList<Favorite>(newFavorites);
CustomTreeModel.this.visibleLeaves.remove(FAVORITES);
fireTreeStructureChanged(new Object[] { root, CustomTreeModel.this.visibleCategories.get(0) });
} else
LOG.info("Detected no favorites change");
}
});
this.favorites = new ArrayList<Favorite>((List<Favorite>) ConfigurationManager.getInstance()
.readObject(IPlugInPort.FAVORITES_KEY, new ArrayList<Favorite>()));
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.RECENT_COMPONENTS_KEY,
new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
List<String> newComponents = (List<String>) value;
if (newComponents != null && !new HashSet<String>(newComponents)
.equals(new HashSet<String>(CustomTreeModel.this.recentComponents))) {
LOG.info("Detected recent component change");
CustomTreeModel.this.recentComponents = new ArrayList<String>(newComponents);
CustomTreeModel.this.visibleLeaves.remove(RECENTLY_USED);
fireTreeStructureChanged(new Object[] { root, CustomTreeModel.this.visibleCategories.get(1) });
} else
LOG.info("Detected no recent component change");
}
});
this.recentComponents = new ArrayList<String>((List<String>) ConfigurationManager.getInstance()
.readObject(IPlugInPort.RECENT_COMPONENTS_KEY, new ArrayList<String>()));
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.BLOCKS_KEY,
new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
Map<String, List<IDIYComponent<?>>> newBlocks =
(Map<String, List<IDIYComponent<?>>>) value;
if (newBlocks != null) {
List<String> blockNames = new ArrayList<String>(newBlocks.keySet());
Collections.sort(blockNames);
if (!blockNames.equals(CustomTreeModel.this.blocks)) {
LOG.info("Detected block change");
CustomTreeModel.this.blocks = blockNames;
CustomTreeModel.this.visibleLeaves.remove(BUILDING_BLOCKS);
fireTreeStructureChanged(new Object[] { root, CustomTreeModel.this.visibleCategories.get(2 )});
} else
LOG.info("Detected no block change");
} else
LOG.info("Detected no block change");
}
});
Map<String, List<IDIYComponent<?>>> newBlocks =
(Map<String, List<IDIYComponent<?>>>) ConfigurationManager.getInstance()
.readObject(IPlugInPort.BLOCKS_KEY, null);
if (newBlocks == null)
this.blocks = new ArrayList<String>();
else {
this.blocks = new ArrayList<String>(newBlocks.keySet());
Collections.sort(this.blocks);
}
}
}
@@ -28,7 +28,6 @@ import javax.swing.tree.TreePath;
import org.diylc.common.ComponentType; import org.diylc.common.ComponentType;
import org.diylc.common.IPlugInPort; import org.diylc.common.IPlugInPort;
import org.diylc.swing.plugins.canvas.EmptyTransferable; import org.diylc.swing.plugins.canvas.EmptyTransferable;
import org.diylc.swing.plugins.tree.TreePanel.Payload;
/** /**
* {@link DragGestureListener} for {@link TreePanel}. * {@link DragGestureListener} for {@link TreePanel}.
@@ -47,14 +46,14 @@ class TreeGestureListener implements DragGestureListener {
@Override @Override
public void dragGestureRecognized(DragGestureEvent dge) { public void dragGestureRecognized(DragGestureEvent dge) {
ComponentType type = null; ComponentType type = null;
Payload payload = null; TreeNode payload = null;
if (presenter.getNewComponentTypeSlot() == null) { if (presenter.getNewComponentTypeSlot() == null) {
JTree tree = (JTree) dge.getComponent(); JTree tree = (JTree) dge.getComponent();
Point p = dge.getDragOrigin(); Point p = dge.getDragOrigin();
TreePath path = tree.getClosestPathForLocation(p.x, p.y); TreePath path = tree.getClosestPathForLocation(p.x, p.y);
if (path != null && path.getLastPathComponent() instanceof DefaultMutableTreeNode) { if (path != null && path.getLastPathComponent() instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode leaf = (DefaultMutableTreeNode) path.getLastPathComponent(); DefaultMutableTreeNode leaf = (DefaultMutableTreeNode) path.getLastPathComponent();
payload = (Payload) leaf.getUserObject(); payload = (TreeNode) leaf.getUserObject();
if (payload != null && (payload.getComponentType() != null || payload.getClickListener() != null)) if (payload != null && (payload.getComponentType() != null || payload.getClickListener() != null))
type = payload.getComponentType(); type = payload.getComponentType();
} }
@@ -0,0 +1,82 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC 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.
DIYLC 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 DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.swing.plugins.tree;
import java.awt.event.MouseListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.diylc.common.ComponentType;
public class TreeNode {
private ComponentType componentType;
private String category;
private MouseListener clickListener;
private boolean isLeaf;
private final Pattern contributedPattern = Pattern.compile("^(.*)\\[(.*)\\]");
public TreeNode(ComponentType componentType, MouseListener clickListener) {
super();
this.componentType = componentType;
this.clickListener = clickListener;
this.isLeaf = true;
}
public TreeNode(String category, MouseListener clickListener, boolean isLeaf) {
super();
this.category = category;
this.clickListener = clickListener;
this.isLeaf = isLeaf;
}
public ComponentType getComponentType() {
return componentType;
}
public MouseListener getClickListener() {
return clickListener;
}
public boolean isLeaf() {
return isLeaf;
}
public String forDisplay() {
if (componentType == null) {
String display = category;
Matcher match = contributedPattern.matcher(display);
if (match.find()) {
String name = match.group(1);
String owner = match.group(2);
display = name + "<font color='gray'>[" + owner + "]</font>";
}
return display;
}
return componentType.getName();
}
@Override
public String toString() {
return componentType == null ? category : componentType.getName();
}
}
@@ -34,17 +34,12 @@ import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.Icon; import javax.swing.Icon;
@@ -67,7 +62,6 @@ import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel; import javax.swing.tree.TreeSelectionModel;
@@ -78,14 +72,12 @@ import org.diylc.appframework.miscutils.IConfigListener;
import org.diylc.common.ComponentType; import org.diylc.common.ComponentType;
import org.diylc.common.Favorite; import org.diylc.common.Favorite;
import org.diylc.common.Favorite.FavoriteType; import org.diylc.common.Favorite.FavoriteType;
import org.diylc.common.IBlockProcessor.InvalidBlockException;
import org.diylc.common.IPlugInPort; import org.diylc.common.IPlugInPort;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
import org.diylc.core.IView; import org.diylc.core.IView;
import org.diylc.core.Template; import org.diylc.core.Template;
import org.diylc.images.IconLoader; import org.diylc.images.IconLoader;
import org.diylc.lang.LangUtil; import org.diylc.lang.LangUtil;
import org.diylc.presenter.ComponentProcessor;
import org.diylc.swing.ISwingUI; import org.diylc.swing.ISwingUI;
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory; import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
@@ -100,23 +92,18 @@ public class TreePanel extends JPanel {
public static final String COMPONENT_SHORTCUT_KEY = "componentShortcuts"; public static final String COMPONENT_SHORTCUT_KEY = "componentShortcuts";
private DefaultTreeModel treeModel; private CustomTreeModel treeModel;
private JTree tree; private JTree tree;
private JScrollPane treeScroll; private JScrollPane treeScroll;
private JTextField searchField; private JTextField searchField;
private DefaultMutableTreeNode recentNode;
private DefaultMutableTreeNode blocksNode;
private DefaultMutableTreeNode favoritesNode;
private List<String> recentComponents;
private List<Favorite> favorites; private List<Favorite> favorites;
private List<String> blocks;
private IPlugInPort plugInPort; private IPlugInPort plugInPort;
private ISwingUI swingUI; private ISwingUI swingUI;
private boolean initializing = false;
private JPopupMenu popup; private JPopupMenu popup;
@SuppressWarnings("unchecked")
public TreePanel(IPlugInPort plugInPort, ISwingUI swingUI) { public TreePanel(IPlugInPort plugInPort, ISwingUI swingUI) {
this.plugInPort = plugInPort; this.plugInPort = plugInPort;
this.swingUI = swingUI; this.swingUI = swingUI;
@@ -141,63 +128,21 @@ public class TreePanel extends JPanel {
setPreferredSize(new Dimension(240, 200)); setPreferredSize(new Dimension(240, 200));
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.RECENT_COMPONENTS_KEY, new IConfigListener() { ConfigurationManager.getInstance().addConfigListener(IPlugInPort.FAVORITES_KEY,
new IConfigListener() {
@SuppressWarnings("unchecked")
@Override
public void valueChanged(String key, Object value) {
List<String> newComponents = (List<String>) value;
if (newComponents != null
&& !new HashSet<String>(newComponents).equals(new HashSet<String>(TreePanel.this.recentComponents))) {
LOG.info("Detected recent component change");
refreshRecentComponents(newComponents);
} else
LOG.info("Detected no recent component change");
TreePanel.this.recentComponents = new ArrayList<String>(newComponents);
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.BLOCKS_KEY, new IConfigListener() {
@SuppressWarnings("unchecked")
@Override
public void valueChanged(String key, Object value) {
Map<String, List<IDIYComponent<?>>> newBlocks = (Map<String, List<IDIYComponent<?>>>) value;
if (newBlocks != null) {
List<String> blockNames = new ArrayList<String>(newBlocks.keySet());
Collections.sort(blockNames);
if (!blockNames.equals(TreePanel.this.blocks)) {
LOG.info("Detected block change");
refreshBuildingBlocks(blockNames);
} else
LOG.info("Detected no block change");
} else
LOG.info("Detected no block change");
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.TEMPLATES_KEY, new IConfigListener() {
@Override
public void valueChanged(String key, Object value) {
LOG.info("Detected variants change, repainting the tree");
repaint();
}
});
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.FAVORITES_KEY, new IConfigListener() {
@SuppressWarnings("unchecked")
@Override @Override
public void valueChanged(String key, Object value) { public void valueChanged(String key, Object value) {
List<Favorite> newFavorites = (List<Favorite>) value; List<Favorite> newFavorites = (List<Favorite>) value;
if (newFavorites != null && !newFavorites.equals(TreePanel.this.favorites)) { if (newFavorites != null && !newFavorites.equals(TreePanel.this.favorites)) {
LOG.info("Detected favorites change"); LOG.info("Detected favorites change");
refreshFavorites(newFavorites); TreePanel.this.favorites = new ArrayList<Favorite>(newFavorites);
} else } else
LOG.info("Detected no favorites change"); LOG.info("Detected no favorites change");
} }
}); });
this.favorites = (List<Favorite>) ConfigurationManager.getInstance()
.readObject(IPlugInPort.FAVORITES_KEY, new ArrayList<Favorite>());
getTree().expandRow(0); getTree().expandRow(0);
@@ -207,9 +152,11 @@ public class TreePanel extends JPanel {
private void initializeDnD() { private void initializeDnD() {
// Initialize drag source recognizer. // Initialize drag source recognizer.
DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(getTree(), DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(getTree(),
DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK, new TreeGestureListener(plugInPort)); DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK,
new TreeGestureListener(plugInPort));
// Initialize drop target. // Initialize drop target.
new DropTarget(getTree(), DnDConstants.ACTION_COPY_OR_MOVE, new TreeTargetListener(plugInPort), true); new DropTarget(getTree(), DnDConstants.ACTION_COPY_OR_MOVE, new TreeTargetListener(plugInPort),
true);
} }
public JScrollPane getTreeScroll() { public JScrollPane getTreeScroll() {
@@ -220,218 +167,47 @@ public class TreePanel extends JPanel {
return treeScroll; return treeScroll;
} }
public DefaultMutableTreeNode getRecentNode() { public CustomTreeModel getTreeModel() {
if (this.recentNode == null) {
this.recentNode = new DefaultMutableTreeNode(new Payload("(Recently Used)", null), true);
@SuppressWarnings("unchecked")
List<String> recent =
(List<String>) ConfigurationManager.getInstance().readObject(IPlugInPort.RECENT_COMPONENTS_KEY, null);
if (recent != null) {
this.recentComponents = new ArrayList<String>(recent);
refreshRecentComponents(recent);
} else {
this.recentComponents = new ArrayList<String>();
}
}
return this.recentNode;
}
public DefaultMutableTreeNode getBlocksNode() {
if (this.blocksNode == null) {
this.blocksNode = new DefaultMutableTreeNode(new Payload("(Building Blocks)", null), true);
@SuppressWarnings("unchecked")
Map<String, List<IDIYComponent<?>>> newBlocks =
(Map<String, List<IDIYComponent<?>>>) ConfigurationManager.getInstance().readObject(
IPlugInPort.BLOCKS_KEY, null);
if (newBlocks != null) {
List<String> blockNames = new ArrayList<String>(newBlocks.keySet());
Collections.sort(blockNames);
refreshBuildingBlocks(blockNames);
} else {
this.blocks = new ArrayList<String>();
}
}
return this.blocksNode;
}
public DefaultMutableTreeNode getFavoritesNode() {
if (this.favoritesNode == null) {
this.favoritesNode = new DefaultMutableTreeNode(new Payload("(Favorites)", null), true);
@SuppressWarnings("unchecked")
List<Favorite> favorites = (List<Favorite>) ConfigurationManager.getInstance().readObject(IPlugInPort.FAVORITES_KEY, null);
if (favorites != null) {
refreshFavorites(favorites);
} else {
this.favorites = new ArrayList<Favorite>();
}
}
return this.favoritesNode;
}
@SuppressWarnings("unchecked")
private void refreshRecentComponents(List<String> recentComponentClassList) {
getRecentNode().removeAllChildren();
for (String componentClassName : recentComponentClassList) {
final ComponentType componentType;
try {
componentType =
ComponentProcessor.getInstance().extractComponentTypeFrom(
(Class<? extends IDIYComponent<?>>) Class.forName(componentClassName));
Payload payload = new Payload(componentType, new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (plugInPort.getNewComponentTypeSlot() != componentType)
plugInPort.setNewComponentTypeSlot(componentType, null, false);
}
});
final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false);
String text = getSearchField().getText();
boolean visible =
text.trim().length() == 0 || componentType.getName().toLowerCase().contains(text.toLowerCase())
|| componentType.getDescription().toLowerCase().contains(text.toLowerCase())
|| componentType.getCategory().toLowerCase().contains(text.toLowerCase());
payload.setVisible(visible);
getRecentNode().add(componentNode);
} catch (ClassNotFoundException e) {
LOG.error("Could not create recent component button for " + componentClassName, e);
}
}
if (!initializing)
getTreeModel().nodeStructureChanged(getRecentNode());
}
private void refreshBuildingBlocks(List<String> blocks) {
this.blocks = blocks;
getBlocksNode().removeAllChildren();
for (final String block : blocks) {
Payload payload = new Payload(block, new MouseAdapter() {
long previousActionTime = 0;
@Override
public void mouseClicked(MouseEvent e) {
if (e == null || SwingUtilities.isLeftMouseButton(e) && System.currentTimeMillis() - previousActionTime > 100) {
previousActionTime = System.currentTimeMillis();
try {
plugInPort.loadBlock(block);
} catch (InvalidBlockException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false);
String text = getSearchField().getText();
boolean visible = text.trim().length() == 0 || block.toLowerCase().contains(text.toLowerCase());
payload.setVisible(visible);
getBlocksNode().add(componentNode);
}
if (!initializing)
getTreeModel().nodeStructureChanged(getBlocksNode());
}
private void refreshFavorites(List<Favorite> favorites) {
this.favorites = new ArrayList<Favorite>(favorites);
getFavoritesNode().removeAllChildren();
Map<String, List<ComponentType>> types = plugInPort.getComponentTypes();
Map<String, ComponentType> typesByClass = new HashMap<String, ComponentType>();
for (Map.Entry<String, List<ComponentType>> e : types.entrySet())
for (ComponentType c : e.getValue())
typesByClass.put(c.getInstanceClass().getCanonicalName(), c);
for (Favorite f : favorites) {
if (f.getType() == FavoriteType.Component) {
final ComponentType type = typesByClass.get(f.getName());
if (type != null) {
DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(new Payload(type, new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
plugInPort.setNewComponentTypeSlot(type, null, false);
}
}), false);
getFavoritesNode().add(componentNode);
}
} else if (f.getType() == FavoriteType.Block) {
final String block = f.getName();
Payload payload = new Payload(block, new MouseAdapter() {
long previousActionTime = 0;
@Override
public void mouseClicked(MouseEvent e) {
if (e == null || SwingUtilities.isLeftMouseButton(e) && System.currentTimeMillis() - previousActionTime > 100) {
previousActionTime = System.currentTimeMillis();
try {
plugInPort.loadBlock(block);
} catch (InvalidBlockException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(payload, false);
String text = getSearchField().getText();
boolean visible = text.trim().length() == 0 || block.toLowerCase().contains(text.toLowerCase());
payload.setVisible(visible);
getFavoritesNode().add(componentNode);
}
}
if (!initializing)
getTreeModel().nodeStructureChanged(getFavoritesNode());
}
public DefaultTreeModel getTreeModel() {
if (treeModel == null) { if (treeModel == null) {
final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Components", true); treeModel = new CustomTreeModel(plugInPort);
initializing = true;
rootNode.add(getFavoritesNode());
rootNode.add(getRecentNode());
rootNode.add(getBlocksNode());
initializing = false;
Map<String, List<ComponentType>> componentTypes = plugInPort.getComponentTypes();
List<String> categories = new ArrayList<String>(componentTypes.keySet());
Collections.sort(categories);
for (String category : categories) {
final DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(new Payload(category, null));
rootNode.add(categoryNode);
for (final ComponentType type : componentTypes.get(category)) {
final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(new Payload(type, new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
plugInPort.setNewComponentTypeSlot(type, null, false);
}
}), false);
categoryNode.add(componentNode);
}
}
treeModel = new DefaultTreeModel(rootNode);
treeModel.addTreeModelListener(new TreeModelAdapter() { treeModel.addTreeModelListener(new TreeModelAdapter() {
@Override
public void treeNodesRemoved(TreeModelEvent e) {
super.treeNodesRemoved(e);
}
@Override @Override
public void treeNodesChanged(TreeModelEvent e) { public void treeStructureChanged(TreeModelEvent e) {
// TODO Auto-generated method stub String searchText = treeModel.getSearchText();
super.treeNodesChanged(e);
// when we are searching for something, expand all nodes
if (searchText != null && !searchText.isEmpty()) {
int n = treeModel.getChildCount(treeModel.getRoot());
for (int i = 0; i < n; i++) {
Object toExpand = treeModel.getChild(treeModel.getRoot(), i);
tree.expandPath(new TreePath(new Object[] { treeModel.getRoot(), toExpand } ));
}
}
} }
}); });
} }
return treeModel; return treeModel;
} }
@SuppressWarnings("unchecked")
public static void setNodeExpandedState(JTree tree, DefaultMutableTreeNode node,
boolean expanded) {
ArrayList<DefaultMutableTreeNode> list = Collections.list(node.children());
for (DefaultMutableTreeNode treeNode : list) {
setNodeExpandedState(tree, treeNode, expanded);
}
if (!expanded && node.isRoot()) {
return;
}
TreePath path = new TreePath(node.getPath());
if (expanded) {
tree.expandPath(path);
} else {
tree.collapsePath(path);
}
}
public JTree getTree() { public JTree getTree() {
if (tree == null) { if (tree == null) {
tree = new JTree(getTreeModel()); tree = new JTree(getTreeModel());
@@ -448,9 +224,9 @@ public class TreePanel extends JPanel {
if (!e.isAddedPath()) if (!e.isAddedPath())
return; return;
DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.getPath().getLastPathComponent(); Object node = e.getPath().getLastPathComponent();
if (node != null && node.getUserObject() != null) { if (node != null && node instanceof TreeNode) {
Payload payload = (Payload) node.getUserObject(); TreeNode payload = (TreeNode) node;
if (payload.getClickListener() != null) { if (payload.getClickListener() != null) {
payload.getClickListener().mouseClicked(null); payload.getClickListener().mouseClicked(null);
} }
@@ -471,9 +247,9 @@ public class TreePanel extends JPanel {
getPopup().show(e.getComponent(), e.getX(), e.getY()); getPopup().show(e.getComponent(), e.getX(), e.getY());
} else { } else {
TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY()); TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY());
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); Object node = path.getLastPathComponent();
if (node != null && node.getUserObject() != null) { if (node != null && node instanceof TreeNode) {
Payload payload = (Payload) node.getUserObject(); TreeNode payload = (TreeNode) node;
if (payload.getClickListener() != null) { if (payload.getClickListener() != null) {
payload.getClickListener().mouseClicked(e); payload.getClickListener().mouseClicked(e);
} }
@@ -495,18 +271,16 @@ public class TreePanel extends JPanel {
public void popupMenuWillBecomeVisible(PopupMenuEvent e) { public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
popup.removeAll(); popup.removeAll();
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); Object selectedNode = tree.getLastSelectedPathComponent();
if (selectedNode == null || selectedNode.getUserObject() == null) if (selectedNode == null || !(selectedNode instanceof TreeNode))
return; return;
Payload payload = (Payload) selectedNode.getUserObject(); TreeNode payload = (TreeNode) selectedNode;
final ComponentType componentType = payload.getComponentType(); final ComponentType componentType = payload.getComponentType();
final String identifier = final String identifier = componentType == null ? "block:" + payload.toString()
componentType == null ? "block:" + payload.toString() : componentType.getInstanceClass() : componentType.getInstanceClass().getCanonicalName();
.getCanonicalName();
JMenu shortcutSubmenu = new JMenu("Assign Shortcut"); JMenu shortcutSubmenu = new JMenu("Assign Shortcut");
final JMenuItem noneItem = new JMenuItem("None"); final JMenuItem noneItem = new JMenuItem("None");
@@ -515,8 +289,8 @@ public class TreePanel extends JPanel {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
HashMap<String, String> map = HashMap<String, String> map = (HashMap<String, String>) ConfigurationManager
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(COMPONENT_SHORTCUT_KEY, null); .getInstance().readObject(COMPONENT_SHORTCUT_KEY, null);
if (map == null) if (map == null)
map = new HashMap<String, String>(); map = new HashMap<String, String>();
@@ -544,9 +318,8 @@ public class TreePanel extends JPanel {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
HashMap<String, String> map = HashMap<String, String> map = (HashMap<String, String>) ConfigurationManager
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(COMPONENT_SHORTCUT_KEY, .getInstance().readObject(COMPONENT_SHORTCUT_KEY, null);
null);
if (map == null) if (map == null)
map = new HashMap<String, String>(); map = new HashMap<String, String>();
@@ -571,10 +344,11 @@ public class TreePanel extends JPanel {
shortcutSubmenu.add(item); shortcutSubmenu.add(item);
} }
if (selectedNode.isLeaf()) { if (getTreeModel().isLeaf(selectedNode)) {
final Favorite fav = final Favorite fav =
new Favorite(componentType == null ? FavoriteType.Block : FavoriteType.Component, new Favorite(componentType == null ? FavoriteType.Block : FavoriteType.Component,
componentType == null ? payload.toString() : componentType.getInstanceClass().getCanonicalName()); componentType == null ? payload.toString()
: componentType.getInstanceClass().getCanonicalName());
final boolean isFavorite = favorites != null && favorites.indexOf(fav) >= 0; final boolean isFavorite = favorites != null && favorites.indexOf(fav) >= 0;
final JMenuItem favoritesItem = final JMenuItem favoritesItem =
new JMenuItem(isFavorite ? "Remove From Favorites" : "Add To Favorites", new JMenuItem(isFavorite ? "Remove From Favorites" : "Add To Favorites",
@@ -608,11 +382,12 @@ public class TreePanel extends JPanel {
popup.add(item); popup.add(item);
} else { } else {
for (Template template : templates) { for (Template template : templates) {
JMenuItem item = ComponentButtonFactory.createVariantItem(plugInPort, template, componentType); JMenuItem item =
ComponentButtonFactory.createVariantItem(plugInPort, template, componentType);
popup.add(item); popup.add(item);
} }
} }
} else if (selectedNode.isLeaf()) { } else if (getTreeModel().isLeaf(selectedNode)) {
popup.add(shortcutSubmenu); popup.add(shortcutSubmenu);
popup.add(new DeleteBlockAction(plugInPort, swingUI, payload.toString())); popup.add(new DeleteBlockAction(plugInPort, swingUI, payload.toString()));
} }
@@ -679,55 +454,8 @@ public class TreePanel extends JPanel {
public void process() { public void process() {
String text = searchField.getText(); String text = searchField.getText();
DefaultTreeModel model = getTreeModel(); CustomTreeModel model = getTreeModel();
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) model.getRoot(); model.setSearchText(text);
for (int i = 0; i < model.getChildCount(rootNode); i++) {
int visibleCount = 0;
DefaultMutableTreeNode categoryNode = (DefaultMutableTreeNode) model.getChild(rootNode, i);
for (int j = 0; j < model.getChildCount(categoryNode); j++) {
DefaultMutableTreeNode componentNode = (DefaultMutableTreeNode) model.getChild(categoryNode, j);
Object obj = componentNode.getUserObject();
if (obj != null && obj.getClass().equals(Payload.class)) {
Payload payload = (Payload) obj;
boolean visible = false;
if (text.trim().length() == 0) {
visible = true;
} else if (payload.getComponentType() != null) {
ComponentType type = payload.getComponentType();
visible =
type.getName().toLowerCase().contains(text.toLowerCase())
|| type.getDescription().toLowerCase().contains(text.toLowerCase())
|| type.getCategory().toLowerCase().contains(text.toLowerCase());
} else {
visible = payload.toString().toLowerCase().contains(text.toLowerCase());
}
if (visible != payload.isVisible()) {
payload.setVisible(visible);
model.nodeStructureChanged(componentNode);
}
if (visible)
visibleCount++;
}
}
Object obj = categoryNode.getUserObject();
if (obj != null && obj.getClass().equals(Payload.class)) {
Payload payload = (Payload) obj;
boolean categoryVisible = visibleCount > 0;
if (categoryVisible != payload.isVisible()) {
payload.setVisible(categoryVisible);
model.nodeStructureChanged(rootNode);
}
if (categoryVisible && text.trim().length() > 0) {
getTree().expandPath(new TreePath(categoryNode.getPath()));
}
}
}
for (int i = 0; i < model.getChildCount(rootNode); i++) {
DefaultMutableTreeNode categoryNode = (DefaultMutableTreeNode) model.getChild(rootNode, i);
getTree().expandPath(new TreePath(categoryNode.getPath()));
}
} }
}); });
} }
@@ -740,127 +468,68 @@ public class TreePanel extends JPanel {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean selected, public Component getTreeCellRendererComponent(final JTree tree, final Object value,
final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { final boolean selected, final boolean expanded, final boolean leaf, final int row,
final boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
Object obj = ((DefaultMutableTreeNode) value).getUserObject(); Object obj = value;
if (obj != null && obj.getClass().equals(Payload.class)) { if (obj != null && obj.getClass().equals(TreeNode.class)) {
Payload payload = (Payload) obj; TreeNode payload = (TreeNode) obj;
if (payload.getComponentType() == null) { if (payload.getComponentType() == null) {
setToolTipText(null); setToolTipText(null);
if (leaf) if (leaf)
setIcon(IconLoader.Component.getIcon()); setIcon(IconLoader.Component.getIcon());
if (payload.isVisible())
setPreferredSize(new Dimension(250, 20)); setPreferredSize(new Dimension(250, 20));
else
setPreferredSize(new Dimension(0, 0));
} else { } else {
setToolTipText("<html><b>" + payload.getComponentType().getName() + "</b><br>" setToolTipText("<html><b>" + payload.getComponentType().getName() + "</b><br>"
+ payload.getComponentType().getDescription() + "<br>Author: " + payload.getComponentType().getAuthor() + payload.getComponentType().getDescription() + "<br>Author: "
+ "<br><br>" + CLICK_TO_INSTANTIATE + "</html>"); + payload.getComponentType().getAuthor() + "<br><br>" + CLICK_TO_INSTANTIATE
+ "</html>");
setIcon(payload.getComponentType().getIcon()); setIcon(payload.getComponentType().getIcon());
if (payload.isVisible())
setPreferredSize(new Dimension(250, 32)); setPreferredSize(new Dimension(250, 32));
else
setPreferredSize(new Dimension(0, 0));
} }
String shortCutHtml = ""; String shortCutHtml = "";
String variantsHtml = ""; String variantsHtml = "";
if (payload.isVisible()) { HashMap<String, String> shortcutMap = (HashMap<String, String>) ConfigurationManager
HashMap<String, String> shortcutMap = .getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY, null);
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY, String identifier = payload.getComponentType() == null ? "block:" + payload.toString()
null); : payload.getComponentType().getInstanceClass().getCanonicalName();
String identifier =
payload.getComponentType() == null ? "block:" + payload.toString() : payload.getComponentType()
.getInstanceClass().getCanonicalName();
if (shortcutMap != null && shortcutMap.containsValue(identifier)) { if (shortcutMap != null && shortcutMap.containsValue(identifier)) {
for (String key : shortcutMap.keySet()) { for (String key : shortcutMap.keySet()) {
if (shortcutMap.get(key).equals(identifier)) { if (shortcutMap.get(key).equals(identifier)) {
shortCutHtml = " <a style=\"text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; background-color: #eeeeee; color: #666666;\">&nbsp;" shortCutHtml =
" <a style=\"text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; background-color: #eeeeee; color: #666666;\">&nbsp;"
+ key + "&nbsp;</a>"; + key + "&nbsp;</a>";
} }
} }
} }
}
if (payload.getComponentType() != null) { if (payload.getComponentType() != null) {
List<Template> variants = plugInPort.getVariantsFor(payload.getComponentType()); List<Template> variants = plugInPort.getVariantsFor(payload.getComponentType());
if (variants != null && !variants.isEmpty()) { if (variants != null && !variants.isEmpty()) {
variantsHtml = " <a style=\"text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; background-color: #D7FFC6; color: #666666;\">[+" variantsHtml =
" <a style=\"text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; background-color: #D7FFC6; color: #666666;\">[+"
+ variants.size() + "]</a>"; + variants.size() + "]</a>";
} }
} }
// translate categories // translate categories
setText("<html>" + (payload.getComponentType() == null ? LangUtil.translate(payload.forDisplay()) : payload.forDisplay()) + shortCutHtml + variantsHtml + "</html>"); setText("<html>"
+ (payload.getComponentType() == null ? LangUtil.translate(payload.forDisplay())
: payload.forDisplay())
+ shortCutHtml + variantsHtml + "</html>");
} }
return this; return this;
} }
} }
public class Payload {
private ComponentType componentType;
private String category;
private boolean isVisible;
private MouseListener clickListener;
private final Pattern contributedPattern = Pattern.compile("^(.*)\\[(.*)\\]");
public Payload(ComponentType componentType, MouseListener clickListener) {
super();
this.componentType = componentType;
this.clickListener = clickListener;
this.isVisible = true;
}
public Payload(String category, MouseListener clickListener) {
super();
this.category = category;
this.clickListener = clickListener;
this.isVisible = true;
}
public ComponentType getComponentType() {
return componentType;
}
public boolean isVisible() {
return isVisible;
}
public void setVisible(boolean isVisible) {
this.isVisible = isVisible;
}
public MouseListener getClickListener() {
return clickListener;
}
public String forDisplay() {
if (componentType == null) {
String display = category;
Matcher match = contributedPattern.matcher(display);
if (match.find()) {
String name = match.group(1);
String owner = match.group(2);
display = name + "<font color='gray'>[" + owner + "]</font>";
}
return display;
}
return componentType.getName();
}
@Override
public String toString() {
return componentType == null ? category : componentType.getName();
}
}
public static class SelectAllAction extends AbstractAction { public static class SelectAllAction extends AbstractAction {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -913,7 +582,9 @@ public class TreePanel extends JPanel {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
LOG.info(getValue(AbstractAction.NAME) + " triggered"); LOG.info(getValue(AbstractAction.NAME) + " triggered");
if (swingUI.showConfirmDialog("Are you sure you want to delete building block \"" + blockName + "\"?", "Delete Building Block", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) == IView.YES_OPTION) if (swingUI.showConfirmDialog(
"Are you sure you want to delete building block \"" + blockName + "\"?",
"Delete Building Block", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) == IView.YES_OPTION)
plugInPort.deleteBlock(blockName); plugInPort.deleteBlock(blockName);
} }
} }