mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
tree improvements
This commit is contained in:
@@ -19,6 +19,8 @@ import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
@@ -33,7 +35,7 @@ import org.diylc.swingframework.openide.DropDownButtonFactory;
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class ComponentButtonFactory {
|
||||
public class ComponentButtonFactory {
|
||||
|
||||
public static int MARGIN = 3;
|
||||
|
||||
@@ -127,6 +129,8 @@ class ComponentButtonFactory {
|
||||
e.consume();
|
||||
}
|
||||
});
|
||||
Border margin = new EmptyBorder(4, 0, 0, 0);
|
||||
label.setBorder(margin);
|
||||
item.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 0));
|
||||
item.add(label);
|
||||
return item;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.diylc.swing.plugins.tree;
|
||||
|
||||
import java.awt.KeyEventDispatcher;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.swing.SwingConstants;
|
||||
@@ -49,6 +52,18 @@ public class ComponentTree implements IPlugIn {
|
||||
getTreePanel().setVisible(
|
||||
ConfigurationManager.getInstance().readString(ConfigPlugin.COMPONENT_BROWSER, ConfigPlugin.SEARCHABLE_TREE)
|
||||
.equals(ConfigPlugin.SEARCHABLE_TREE));
|
||||
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||
if (e.getKeyChar() == 'q') {
|
||||
getTreePanel().getSearchField().requestFocusInWindow();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public TreePanel getTreePanel() {
|
||||
|
||||
@@ -8,20 +8,32 @@ import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.ToolTipManager;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
@@ -29,20 +41,33 @@ import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
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.IPlugInPort;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Template;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.swing.plugins.toolbox.ComponentButtonFactory;
|
||||
|
||||
public class TreePanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(TreePanel.class);
|
||||
|
||||
private DefaultTreeModel treeModel;
|
||||
private JTree tree;
|
||||
private JTextField searchField;
|
||||
private DefaultMutableTreeNode recentNode;
|
||||
private List<String> recentComponents;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
private JPopupMenu popup;
|
||||
|
||||
public TreePanel(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
setLayout(new GridBagLayout());
|
||||
@@ -65,11 +90,63 @@ public class TreePanel extends JPanel {
|
||||
add(scroll, gbc);
|
||||
|
||||
setPreferredSize(new Dimension(240, 200));
|
||||
|
||||
ConfigurationManager.getInstance().addConfigListener(IPlugInPort.RECENT_COMPONENTS_KEY, new IConfigListener() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void valueChanged(String key, Object value) {
|
||||
List<String> newComponents = (List<String>) value;
|
||||
if (!new HashSet<String>(newComponents).equals(new HashSet<String>(TreePanel.this.recentComponents))) {
|
||||
LOG.info("Detected change");
|
||||
refreshRecentComponentsToolbar(newComponents);
|
||||
} else
|
||||
LOG.info("Detected no change");
|
||||
TreePanel.this.recentComponents = new ArrayList<String>(newComponents);
|
||||
}
|
||||
});
|
||||
|
||||
getTree().expandRow(0);
|
||||
}
|
||||
|
||||
public DefaultMutableTreeNode getRecentNode() {
|
||||
if (this.recentNode == null) {
|
||||
this.recentNode = new DefaultMutableTreeNode(new Payload("(Recently Used)"), 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);
|
||||
refreshRecentComponentsToolbar(recent);
|
||||
} else {
|
||||
this.recentComponents = new ArrayList<String>();
|
||||
}
|
||||
}
|
||||
return this.recentNode;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void refreshRecentComponentsToolbar(List<String> recentComponentClassList) {
|
||||
getRecentNode().removeAllChildren();
|
||||
for (String componentClassName : recentComponentClassList) {
|
||||
ComponentType componentType;
|
||||
try {
|
||||
componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) Class.forName(componentClassName));
|
||||
final DefaultMutableTreeNode componentNode = new DefaultMutableTreeNode(new Payload(componentType), false);
|
||||
getRecentNode().add(componentNode);
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOG.error("Could not create recent component button for " + componentClassName, e);
|
||||
}
|
||||
}
|
||||
getTreeModel().nodeStructureChanged(getRecentNode());
|
||||
}
|
||||
|
||||
public DefaultTreeModel getTreeModel() {
|
||||
if (treeModel == null) {
|
||||
final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Components", true);
|
||||
rootNode.add(getRecentNode());
|
||||
Map<String, List<ComponentType>> componentTypes = plugInPort.getComponentTypes();
|
||||
List<String> categories = new ArrayList<String>(componentTypes.keySet());
|
||||
Collections.sort(categories);
|
||||
@@ -88,12 +165,11 @@ public class TreePanel extends JPanel {
|
||||
|
||||
public JTree getTree() {
|
||||
if (tree == null) {
|
||||
|
||||
|
||||
tree = new JTree(getTreeModel());
|
||||
tree.setRootVisible(false);
|
||||
tree.setCellRenderer(new ComponentCellRenderer());
|
||||
tree.setRowHeight(0);
|
||||
ToolTipManager.sharedInstance().registerComponent(tree);
|
||||
tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
|
||||
@Override
|
||||
@@ -109,10 +185,62 @@ public class TreePanel extends JPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tree.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
int row = tree.getClosestRowForLocation(e.getX(), e.getY());
|
||||
tree.setSelectionRow(row);
|
||||
getPopup().show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
public JPopupMenu getPopup() {
|
||||
if (popup == null) {
|
||||
popup = new JPopupMenu();
|
||||
popup.add("Loading...");
|
||||
popup.addPopupMenuListener(new PopupMenuListener() {
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
||||
popup.removeAll();
|
||||
|
||||
popup.add(new SelectAllAction(plugInPort));
|
||||
ComponentType componentType = plugInPort.getNewComponentTypeSlot();
|
||||
if (componentType != null) {
|
||||
popup.add(new JSeparator());
|
||||
|
||||
List<Template> templates = plugInPort.getTemplatesFor(componentType.getCategory(), componentType.getName());
|
||||
if (templates == null || templates.isEmpty()) {
|
||||
JMenuItem item = new JMenuItem("<no templates>");
|
||||
item.setEnabled(false);
|
||||
popup.add(item);
|
||||
} else {
|
||||
for (Template template : templates) {
|
||||
JMenuItem item = ComponentButtonFactory.createTemplateItem(plugInPort, template, componentType);
|
||||
popup.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent e) {}
|
||||
});
|
||||
}
|
||||
return popup;
|
||||
}
|
||||
|
||||
public JTextField getSearchField() {
|
||||
if (searchField == null) {
|
||||
searchField = new JTextField() {
|
||||
@@ -131,7 +259,7 @@ public class TreePanel extends JPanel {
|
||||
if (searchField.getText().trim().length() == 0 && !searchField.hasFocus()) {
|
||||
g2d.setColor(Color.gray);
|
||||
g2d.setFont(searchField.getFont());
|
||||
g2d.drawString("Search", 4, 3 + searchField.getFont().getSize());
|
||||
g2d.drawString("Search (press Q to jump here)", 4, 3 + searchField.getFont().getSize());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -206,7 +334,7 @@ public class TreePanel extends JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < model.getChildCount(rootNode); i++) {
|
||||
DefaultMutableTreeNode categoryNode = (DefaultMutableTreeNode) model.getChild(rootNode, i);
|
||||
tree.expandPath(new TreePath(categoryNode.getPath()));
|
||||
@@ -236,6 +364,9 @@ public class TreePanel extends JPanel {
|
||||
else
|
||||
setPreferredSize(new Dimension(0, 0));
|
||||
} else {
|
||||
setToolTipText("<html><b>" + type.getComponentType().getName() + "</b><br>"
|
||||
+ type.getComponentType().getDescription() + "<br>Author: " + type.getComponentType().getAuthor()
|
||||
+ "<br><br>Left click to instantiate this component, right click for more options" + "</html>");
|
||||
setIcon(type.getComponentType().getIcon());
|
||||
if (type.isVisible())
|
||||
setPreferredSize(new Dimension(240, 32));
|
||||
@@ -282,4 +413,36 @@ public class TreePanel extends JPanel {
|
||||
return componentType == null ? category : componentType.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SelectAllAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
public SelectAllAction(IPlugInPort plugInPort) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
putValue(AbstractAction.NAME, "Select All");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info(getValue(AbstractAction.NAME) + " triggered");
|
||||
ComponentType componentType = plugInPort.getNewComponentTypeSlot();
|
||||
if (componentType != null) {
|
||||
List<IDIYComponent<?>> components = plugInPort.getCurrentProject().getComponents();
|
||||
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
|
||||
for (IDIYComponent<?> component : components) {
|
||||
if (componentType.getInstanceClass().equals(component.getClass())) {
|
||||
newSelection.add(component);
|
||||
}
|
||||
}
|
||||
|
||||
plugInPort.updateSelection(newSelection);
|
||||
plugInPort.setNewComponentTypeSlot(null, null);
|
||||
plugInPort.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user