View Javadoc
1   /*******************************************************************************
2    * Copyhacked (H) 2012-2025.
3    * This program and the accompanying materials
4    * are made available under no term at all, use it like
5    * you want, but share and discuss it
6    * every time possible with every body.
7    * 
8    * Contributors:
9    *      ron190 at ymail dot com - initial implementation
10   ******************************************************************************/
11  package com.jsql.view.swing.manager;
12  
13  import com.jsql.util.LogLevelUtil;
14  import com.jsql.view.swing.tree.CellEditorNode;
15  import com.jsql.view.swing.tree.CellRendererNode;
16  import com.jsql.view.swing.tree.TreeDatabase;
17  import com.jsql.view.swing.tree.model.AbstractNodeModel;
18  import com.jsql.view.swing.tree.model.NodeModelEmpty;
19  import com.jsql.view.swing.util.I18nViewUtil;
20  import com.jsql.view.swing.util.MediatorHelper;
21  import org.apache.logging.log4j.LogManager;
22  import org.apache.logging.log4j.Logger;
23  
24  import javax.swing.*;
25  import javax.swing.event.TreeModelEvent;
26  import javax.swing.event.TreeModelListener;
27  import javax.swing.tree.DefaultMutableTreeNode;
28  import javax.swing.tree.TreePath;
29  import javax.swing.tree.TreeSelectionModel;
30  import java.awt.*;
31  import java.awt.event.KeyAdapter;
32  import java.awt.event.KeyEvent;
33  import java.awt.event.MouseAdapter;
34  import java.awt.event.MouseEvent;
35  
36  /**
37   * Manager to code/decode string in various methods.
38   */
39  public class ManagerDatabase extends JPanel {
40      
41      private static final Logger LOGGER = LogManager.getRootLogger();
42  
43      private final TreeDatabase tree;
44  
45      /**
46       * Create a panel to encode a string.
47       */
48      public ManagerDatabase() {
49          super(new BorderLayout());
50  
51          // First node in tree
52          AbstractNodeModel nodeModelEmpty = new NodeModelEmpty(I18nViewUtil.valueByKey("DATABASE_EMPTY"));
53          var root = new DefaultMutableTreeNode(nodeModelEmpty);
54          I18nViewUtil.addComponentForKey("DATABASE_EMPTY", nodeModelEmpty);
55  
56          this.tree = new TreeDatabase(root);
57          this.tree.setName("treeDatabases");
58          MediatorHelper.register(this.tree);
59  
60          this.tree.setCellRenderer(new CellRendererNode());
61          this.tree.addMouseListener(this.getTreeMouseListener());
62          this.tree.addKeyListener(this.getTreeKeyListener());
63          this.tree.setCellEditor(new CellEditorNode());
64          this.tree.setEditable(true);  // allows repaint nodes
65          this.tree.setShowsRootHandles(true);
66          this.tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
67          this.tree.getModel().addTreeModelListener(new TreeModelProgressListener());  // required to repaint progress bar
68  
69          this.add(new JScrollPane(this.tree), BorderLayout.CENTER);
70      }
71  
72      private KeyAdapter getTreeKeyListener() {
73          return new KeyAdapter() {
74              @Override
75              public void keyPressed(KeyEvent e) {
76                  if (e.getKeyCode() == KeyEvent.VK_F2) {
77                      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) ManagerDatabase.this.tree.getLastSelectedPathComponent();
78                      if (treeNode != null) {
79                          AbstractNodeModel nodeModel = (AbstractNodeModel) treeNode.getUserObject();
80                          if (nodeModel != null && nodeModel.getPanel() != null && !nodeModel.isRunning()) {
81                              nodeModel.setIsEdited(true);
82                          }
83                      }
84                  }
85              }
86          };
87      }
88  
89      private MouseAdapter getTreeMouseListener() {
90          return new MouseAdapter() {
91              @Override
92              public void mousePressed(MouseEvent event) {
93                  int selRow = ManagerDatabase.this.tree.getRowForLocation(event.getX(), event.getY());
94                  TreePath selPath = ManagerDatabase.this.tree.getPathForLocation(event.getX(), event.getY());
95                  if (selRow != -1 && event.getClickCount() == 2) {
96                      // Fix ArrayIndexOutOfBoundsException on collapsePath()
97                      try {
98                          if (ManagerDatabase.this.tree.isExpanded(selPath)) {
99                              ManagerDatabase.this.tree.collapsePath(selPath);
100                         } else {
101                             ManagerDatabase.this.tree.expandPath(selPath);
102                         }
103                     } catch (ArrayIndexOutOfBoundsException e) {
104                         LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
105                     }
106                 }
107             }
108         };
109     }
110     
111     private class TreeModelProgressListener implements TreeModelListener {
112         @Override
113         public void treeNodesChanged(TreeModelEvent treeModelEvent) {
114             if (treeModelEvent == null) {
115                 return;
116             }
117             ManagerDatabase.this.tree.firePropertyChange(
118                 JTree.ROOT_VISIBLE_PROPERTY,
119                 !ManagerDatabase.this.tree.isRootVisible(),
120                 ManagerDatabase.this.tree.isRootVisible()
121             );
122             ManagerDatabase.this.tree.treeDidChange();
123         }
124         @Override
125         public void treeStructureChanged(TreeModelEvent treeModelEvent) {
126             // Do nothing
127         }
128         @Override
129         public void treeNodesRemoved(TreeModelEvent treeModelEvent) {
130             // Do nothing
131         }
132         @Override
133         public void treeNodesInserted(TreeModelEvent treeModelEvent) {
134             // Do nothing
135         }
136     }
137 }