|
@@ -16,11 +16,9 @@ import javax.swing.*;
|
|
|
import javax.swing.tree.DefaultMutableTreeNode;
|
|
|
import javax.swing.tree.DefaultTreeModel;
|
|
|
import javax.swing.tree.TreeCellRenderer;
|
|
|
-import javax.swing.tree.TreePath;
|
|
|
import java.awt.*;
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
import java.awt.event.MouseEvent;
|
|
|
-import java.awt.event.MouseMotionAdapter;
|
|
|
import java.util.Collection;
|
|
|
import java.util.Objects;
|
|
|
import java.util.Optional;
|
|
@@ -28,11 +26,10 @@ import java.util.logging.Logger;
|
|
|
|
|
|
public class CategoryPanel extends JScrollPane {
|
|
|
private static final Logger log = Logger.getLogger(CategoryPanel.class.getName());
|
|
|
+ private final static int NODE_SIZE = 25;
|
|
|
private final Control control;
|
|
|
private final Gui gui;
|
|
|
-
|
|
|
private final JPanel buttonPanel = new JPanel();
|
|
|
-
|
|
|
// Buttons
|
|
|
private final JPopupMenu btnAddPopUp = new JPopupMenu("New");
|
|
|
private final JButton btnAdd = new JButton(new ImageIcon(Import.loadImage(ImagePreference.Category.Add, 16, 16)));
|
|
@@ -45,202 +42,68 @@ public class CategoryPanel extends JScrollPane {
|
|
|
|
|
|
private final JTree categoryTree = new JTree();
|
|
|
|
|
|
- private final String eraseCategoryMessage = "Do you really want to delete the Category ";
|
|
|
- private final String incorrectDeleteMessage = "Please select a Category or an Object in the left library in order to delete something.";
|
|
|
-
|
|
|
- private boolean dragging = false;
|
|
|
-
|
|
|
public CategoryPanel(Control control, Gui gui) {
|
|
|
this.control = control;
|
|
|
this.gui = gui;
|
|
|
- buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
|
|
|
init();
|
|
|
- setColumnHeaderView(buttonPanel);
|
|
|
- setViewportView(categoryTree);
|
|
|
- this.setMinimumSize(new Dimension(200, 200));
|
|
|
updateCategories(GuiSettings.getCategories());
|
|
|
- control.OnCategoryChanged.addListener(() -> this.updateCategoryUI(GuiSettings.getCategories()));
|
|
|
+ control.OnCategoryChanged.addListener(() -> this.updateCategories(GuiSettings.getCategories()));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private void init() {
|
|
|
+ this.setMinimumSize(new Dimension(200, 200));
|
|
|
toolBar.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
|
toolBar.setFloatable(false);
|
|
|
+ initLayout();
|
|
|
+ initButtons();
|
|
|
|
|
|
+ categoryTree.setCellRenderer(new CategoryTreeRenderer());
|
|
|
+ categoryTree.setRowHeight(NODE_SIZE);
|
|
|
+ CategoryMouseListener mouseListener = new CategoryMouseListener();
|
|
|
+ categoryTree.addMouseListener(mouseListener);
|
|
|
+ categoryTree.addMouseMotionListener(mouseListener);
|
|
|
+
|
|
|
+ setColumnHeaderView(buttonPanel);
|
|
|
+ setViewportView(categoryTree);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initLayout(){
|
|
|
+ buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
|
|
|
btnAddPopUp.add(mItemNew);
|
|
|
- mItemNew.addActionListener(actionEvent -> new CreateNewDialog(control, gui));
|
|
|
btnAddPopUp.addSeparator();
|
|
|
btnAddPopUp.add(mItemCategory);
|
|
|
- mItemCategory.addActionListener(actionEvent -> new CreateNewDialog(control, CreateNewDialog.Option.Category, gui));
|
|
|
btnAddPopUp.add(mItemObject);
|
|
|
- mItemObject.addActionListener(actionEvent -> new CreateNewDialog(control, CreateNewDialog.Option.Object, gui));
|
|
|
btnAddPopUp.add(mItemSwitch);
|
|
|
- mItemSwitch.addActionListener(actionEvent -> new CreateNewDialog(control, CreateNewDialog.Option.Switch, gui));
|
|
|
- btnAdd.addActionListener(actionEvent -> btnAddPopUp.show(btnAdd, -1, +20));
|
|
|
- btnAdd.setToolTipText("<html><b>New</b><br>Add a new Category or Item to the library.</html>");
|
|
|
toolBar.add(btnAdd);
|
|
|
-
|
|
|
-
|
|
|
- // Del Button
|
|
|
- btnDel.addActionListener(actionEvent -> {
|
|
|
- Optional<DefaultMutableTreeNode> nodeInfo = Optional.ofNullable((DefaultMutableTreeNode) categoryTree.getLastSelectedPathComponent());
|
|
|
- nodeInfo.ifPresentOrElse(selectedNode -> {
|
|
|
- String nodeName = selectedNode.getUserObject().toString();
|
|
|
- int depthOfNode = selectedNode.getLevel();
|
|
|
- try {
|
|
|
- switch (depthOfNode) {
|
|
|
- case 1 -> {
|
|
|
- int dialogResult = JOptionPane.showConfirmDialog(gui, eraseCategoryMessage + nodeName + "?",
|
|
|
- "Warning", JOptionPane.YES_NO_OPTION);
|
|
|
- if (dialogResult == JOptionPane.YES_OPTION) {
|
|
|
- GuiSettings.getCategories().stream().filter(cat -> Objects.equals(cat.getName(), nodeName)).findAny()
|
|
|
- .ifPresent(control::deleteCategory);
|
|
|
- }
|
|
|
- }
|
|
|
- case 2 -> {
|
|
|
- DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent();
|
|
|
- control.findCategoryWithName(parent.getUserObject().toString()).ifPresent(cat -> {
|
|
|
- cat.removeObjectsWithName(nodeName);
|
|
|
- });
|
|
|
- }
|
|
|
- default -> JOptionPane.showMessageDialog(gui, incorrectDeleteMessage);
|
|
|
- }
|
|
|
- } catch (Exception ignored) {
|
|
|
- }
|
|
|
- categoryTree.repaint();
|
|
|
- }, () -> JOptionPane.showMessageDialog(gui, incorrectDeleteMessage));
|
|
|
- });
|
|
|
- btnDel.setToolTipText("<html><b>Delete</b><br>Removes a Category or a Category Item.</html>");
|
|
|
toolBar.add(btnDel);
|
|
|
buttonPanel.add(toolBar);
|
|
|
- categoryTree.setCellRenderer(new CategoryTreeRenderer());
|
|
|
-
|
|
|
-
|
|
|
- categoryTree.addMouseListener(new MouseAdapter() {
|
|
|
-
|
|
|
- public void mousePressed(MouseEvent e) {
|
|
|
-
|
|
|
- AbstractCanvasObject tempCps = null;
|
|
|
- TreePath path = categoryTree
|
|
|
- .getPathForLocation(e.getX(), e.getY());
|
|
|
- if(path == null){
|
|
|
- log.info("Path is null");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)path.getLastPathComponent();
|
|
|
- String clickedObjectName = selectedNode.toString();
|
|
|
- // if an Object was selected, the porperties are shown in
|
|
|
- // the table
|
|
|
- if (SwingUtilities.isRightMouseButton(e)) {
|
|
|
- for (Category cat : GuiSettings.getCategories()) {
|
|
|
- for (AbstractCanvasObject cps : cat.getObjects()) {
|
|
|
- if (clickedObjectName.equals(cps.getName())
|
|
|
- && !(cps instanceof HolonSwitch)) {
|
|
|
-// editItem.setEnabled(true);
|
|
|
-// popmenuEdit.show(e.getComponent(), e.getX(), e.getY());
|
|
|
-// catOfObjToBeEdited = selectedNode.getParent().toString();
|
|
|
- tempCps = cps;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- for (Category cat : GuiSettings.getCategories()) {
|
|
|
- for (AbstractCanvasObject cps : cat.getObjects()) {
|
|
|
- if (clickedObjectName.equals(cps.getName())) {
|
|
|
- Image img = Import.loadImage(cps.getImagePath(), 32, 32);
|
|
|
- tempCps = cps;
|
|
|
- dragging = true;
|
|
|
- Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(img, new Point(),
|
|
|
- "Image");
|
|
|
- gui.setCursor(cursor);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (dragging) {
|
|
|
- Canvas groupNodeCanvas = gui.getCanvas();
|
|
|
- Optional<Point> positionInCanvas = Optional.ofNullable(groupNodeCanvas.getMousePosition());
|
|
|
- AbstractCanvasObject finalTempCps = tempCps;
|
|
|
- positionInCanvas.ifPresent(pos -> {
|
|
|
- AbstractCanvasObject h = null;
|
|
|
- if (finalTempCps instanceof HolonObject hO) {
|
|
|
- h = new HolonObject(hO);
|
|
|
- }
|
|
|
- else if (finalTempCps instanceof HolonSwitch sw) {
|
|
|
- h = new HolonSwitch(sw);
|
|
|
- }
|
|
|
- h.setPosition(pos.x, pos.y);
|
|
|
- control.addObjectOnCanvas(control.getModel().getCanvas(), h);
|
|
|
- control.calculateStateAndVisualForCurrentTimeStep();
|
|
|
- });
|
|
|
- }
|
|
|
- gui.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- categoryTree.addMouseMotionListener(new MouseMotionAdapter() {
|
|
|
-
|
|
|
- public void mouseDragged(MouseEvent e) {
|
|
|
- checkForDragAndDrop();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * checks if an object of the current Panel could be replaced by the dragged
|
|
|
- * object
|
|
|
- */
|
|
|
- private void checkForDragAndDrop() {
|
|
|
- try {
|
|
|
- /**
|
|
|
- * if no object gets dragged -> finished
|
|
|
- */
|
|
|
- if (!dragging)
|
|
|
- return;
|
|
|
-
|
|
|
- Canvas groupNodeCanvas = gui.getCanvas();
|
|
|
- /**
|
|
|
- * check for replacements on the canvas
|
|
|
- */
|
|
|
- if (groupNodeCanvas.getMousePosition() == null)
|
|
|
- return;
|
|
|
- int x = (int) groupNodeCanvas.getMousePosition().getX() + 16;
|
|
|
- int y = (int) groupNodeCanvas.getMousePosition().getY() + 16;
|
|
|
-
|
|
|
- /**
|
|
|
- * check for replacement
|
|
|
- */
|
|
|
- groupNodeCanvas.checkForReplacement(x, y);
|
|
|
-
|
|
|
- } catch (Exception ignored) {
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
+ }
|
|
|
+ private void initButtons(){
|
|
|
+ mItemNew.addActionListener(clicked -> new CreateNewDialog(control, gui));
|
|
|
+ mItemCategory.addActionListener(clicked -> new CreateNewDialog(control, CreateNewDialog.Option.Category, gui));
|
|
|
+ mItemObject.addActionListener(clicked -> new CreateNewDialog(control, CreateNewDialog.Option.Object, gui));
|
|
|
+ mItemSwitch.addActionListener(clicked -> new CreateNewDialog(control, CreateNewDialog.Option.Switch, gui));
|
|
|
+ btnAdd.addActionListener(clicked -> btnAddPopUp.show(btnAdd, -1, +20));
|
|
|
+ btnDel.addActionListener(clicked -> TryDeleteSelectedCategory());
|
|
|
+ btnAdd.setToolTipText("<html><b>New</b><br>Add a new Category or Item to the library.</html>");
|
|
|
+ btnDel.setToolTipText("<html><b>Delete</b><br>Removes a Category or a Category Item.</html>");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * reloads the Categories from Model.
|
|
|
- *
|
|
|
- * @param categories the current categories
|
|
|
- */
|
|
|
- private void updateCategories(Collection<Category> categories) {
|
|
|
- DefaultTreeModel treemodel = new DefaultTreeModel(new DefaultMutableTreeNode("Categories") {
|
|
|
-
|
|
|
- {
|
|
|
- DefaultMutableTreeNode node1;
|
|
|
- for (Category c : categories) {
|
|
|
- node1 = new DefaultMutableTreeNode(c.getName());
|
|
|
-
|
|
|
- for (AbstractCanvasObject obj : c.getObjects()) {
|
|
|
- node1.add(new DefaultMutableTreeNode(obj.getName()));
|
|
|
- }
|
|
|
- add(node1);
|
|
|
+ private void TryDeleteSelectedCategory(){
|
|
|
+ Optional<DefaultMutableTreeNode> selectedNode = Optional.ofNullable((DefaultMutableTreeNode) categoryTree.getLastSelectedPathComponent());
|
|
|
+ selectedNode.ifPresentOrElse(node -> {
|
|
|
+ if (node instanceof CategoryTreeNode catNode) {
|
|
|
+ int dialogResult = JOptionPane.showConfirmDialog(gui, "Do you really want to delete the Category " + catNode + "?",
|
|
|
+ "Warning", JOptionPane.YES_NO_OPTION);
|
|
|
+ if (dialogResult == JOptionPane.YES_OPTION) {
|
|
|
+ GuiSettings.getCategories().stream().filter(cat -> Objects.equals(cat.getName(), catNode.toString())).findAny()
|
|
|
+ .ifPresent(control::deleteCategory);
|
|
|
}
|
|
|
-
|
|
|
+ } else if (node instanceof ObjectTreeNode objNode) {
|
|
|
+ objNode.getCategory().getObjects().remove(objNode.object);
|
|
|
}
|
|
|
- });
|
|
|
- categoryTree.setModel(treemodel);
|
|
|
+ categoryTree.repaint();
|
|
|
+ }, () -> JOptionPane.showMessageDialog(gui, "Please select a Category or an Object in the left library in order to delete something."));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -249,46 +112,108 @@ public class CategoryPanel extends JScrollPane {
|
|
|
*
|
|
|
* @param categories the Categories
|
|
|
*/
|
|
|
- public void updateCategoryUI(Collection<Category> categories) {
|
|
|
- DefaultTreeModel model = (DefaultTreeModel) categoryTree.getModel();
|
|
|
- updateCategories(categories);
|
|
|
- model.reload();
|
|
|
+ private void updateCategories(Collection<Category> categories) {
|
|
|
+ DefaultMutableTreeNode root = new DefaultMutableTreeNode("Categories");
|
|
|
+ categories.stream().map(CategoryTreeNode::new).forEach(root::add);
|
|
|
+ categoryTree.setModel(new DefaultTreeModel(root));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private static class CategoryTreeRenderer implements TreeCellRenderer {
|
|
|
@Override
|
|
|
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
|
|
|
boolean leaf, int row, boolean hasFocus) {
|
|
|
- JLabel label = new JLabel();
|
|
|
- Image imgR;
|
|
|
- if (leaf) {
|
|
|
- for (Category cat : GuiSettings.getCategories()) {
|
|
|
- for (AbstractCanvasObject cps : cat.getObjects()) {
|
|
|
- if (value.toString().equals(cps.getName())) {
|
|
|
- imgR = Import.loadImage(cps.getImagePath(), 50, 50);
|
|
|
- if (imgR != null) {
|
|
|
- label.setIcon(new ImageIcon(imgR));
|
|
|
- }
|
|
|
- label.setText(cps.getName());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ JLabel label = new JLabel(value.toString());
|
|
|
+ if (value instanceof CategoryTreeNode) {
|
|
|
+ label.setIcon(new ImageIcon(Import.loadImage(ImagePreference.Category.Folder)));
|
|
|
+ } else if (value instanceof ObjectTreeNode node) {
|
|
|
+ Image image = Import.loadImage(node.getObject().getImagePath(), tree.getRowHeight(), tree.getRowHeight());
|
|
|
+ label.setIcon(new ImageIcon(image));
|
|
|
}
|
|
|
- tree.setRowHeight(50);
|
|
|
if (hasFocus) {
|
|
|
label.setForeground(ColorPreference.Category.Focus);
|
|
|
label.setOpaque(true);
|
|
|
}
|
|
|
- if (label.getText().isEmpty()) {
|
|
|
- label.setText(value.toString());
|
|
|
- if (!value.toString().equals("Categories")) {
|
|
|
- label.setIcon(new ImageIcon(Import.loadImage(ImagePreference.Category.Folder)));
|
|
|
+ return label;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private class CategoryMouseListener extends MouseAdapter{
|
|
|
+ AbstractCanvasObject selected = null;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mousePressed(MouseEvent e) {
|
|
|
+ Optional<DefaultMutableTreeNode> selectedNode = Optional.ofNullable(
|
|
|
+ (DefaultMutableTreeNode) categoryTree.getLastSelectedPathComponent());
|
|
|
+ selectedNode.ifPresent(node -> {
|
|
|
+ int depthOfNode = node.getLevel();
|
|
|
+ if (depthOfNode != 2) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ ObjectTreeNode objectNode = (ObjectTreeNode) node;
|
|
|
+ selected = objectNode.getObject();
|
|
|
+ log.info("Test" + selected);
|
|
|
+ Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(Import.loadImage(selected.getImagePath(), 32, 32), new Point(),
|
|
|
+ "Image");
|
|
|
+ gui.setCursor(cursor);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseReleased(MouseEvent e) {
|
|
|
+ if(selected == null){
|
|
|
+ return;
|
|
|
}
|
|
|
+ gui.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
|
|
+ Canvas groupNodeCanvas = gui.getCanvas();
|
|
|
+ Optional<Point> positionInCanvas = Optional.ofNullable(groupNodeCanvas.getMousePosition());
|
|
|
+ AbstractCanvasObject finalTempCps = selected;
|
|
|
+ final int halfCursorSize = GuiSettings.getPictureScaleDiv2();
|
|
|
+ positionInCanvas.ifPresent(pos -> {
|
|
|
+ AbstractCanvasObject obj = null;
|
|
|
+ if (finalTempCps instanceof HolonObject hO) {
|
|
|
+ obj = new HolonObject(hO);
|
|
|
+ obj.setPosition(pos.x + halfCursorSize, pos.y + halfCursorSize);
|
|
|
+ } else if (finalTempCps instanceof HolonSwitch sw) {
|
|
|
+ obj = new HolonSwitch(sw);
|
|
|
+ obj.setPosition(pos.x + halfCursorSize, pos.y + halfCursorSize);
|
|
|
+ }
|
|
|
+ control.addObjectOnCanvas(groupNodeCanvas.getGroupNode(), obj);
|
|
|
+ control.calculateStateAndVisualForCurrentTimeStep();
|
|
|
+ });
|
|
|
+ selected = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- return label;
|
|
|
+ private static class CategoryTreeNode extends DefaultMutableTreeNode {
|
|
|
+ private final Category category;
|
|
|
+
|
|
|
+ public CategoryTreeNode(Category category) {
|
|
|
+ super(category.getName());
|
|
|
+ this.category = category;
|
|
|
+ category.getObjects().stream().map(obj -> new ObjectTreeNode(category, obj)).forEach(this::add);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Category getCategory() {
|
|
|
+ return category;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class ObjectTreeNode extends DefaultMutableTreeNode {
|
|
|
+ private final AbstractCanvasObject object;
|
|
|
+ private final Category category;
|
|
|
+
|
|
|
+ public ObjectTreeNode(Category category, AbstractCanvasObject object) {
|
|
|
+ super(object.getName());
|
|
|
+ this.category = category;
|
|
|
+ this.object = object;
|
|
|
+ }
|
|
|
+
|
|
|
+ public AbstractCanvasObject getObject() {
|
|
|
+ return object;
|
|
|
+ }
|
|
|
|
|
|
+ public Category getCategory() {
|
|
|
+ return category;
|
|
|
}
|
|
|
}
|
|
|
}
|