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.tree;
12  
13  import com.jsql.util.I18nUtil;
14  import com.jsql.view.swing.tree.model.AbstractNodeModel;
15  import com.jsql.view.swing.util.UiStringUtil;
16  import com.jsql.view.swing.util.UiUtil;
17  
18  import javax.swing.*;
19  import javax.swing.tree.DefaultMutableTreeNode;
20  import java.awt.*;
21  import java.awt.event.FocusAdapter;
22  import java.awt.event.FocusEvent;
23  import java.awt.event.KeyAdapter;
24  import java.awt.event.KeyEvent;
25  import java.nio.charset.StandardCharsets;
26  import java.util.stream.Stream;
27  
28  /**
29   * A tree Node composed of an icon, a GIF loader, a progress bar, a label.
30   */
31  public class PanelNode extends JPanel {
32      
33      /**
34       * Default icon of the node (database or table).
35       */
36      private final JLabel iconNode = new JLabel();
37  
38      /**
39       * A GIF loader, displayed if progress track is unknown (like columns).
40       */
41      private final JLabel loaderWait = new JLabel();
42  
43      /**
44       * Progress bar displayed during injection, with pause icon displayed if user paused the process.
45       */
46      private final ProgressBarPausable progressBar = new ProgressBarPausable();
47  
48      /**
49       * Text of the node.
50       */
51      private final JLabel nodeLabel = new JLabel();
52      private final JTextField textFieldEditable = new JTextField(15);
53      
54      /**
55       * Create Panel for tree nodes.
56       * @param tree JTree to populate
57       * @param currentNode Node to draw in the tree
58       */
59      public PanelNode(final JTree tree, final DefaultMutableTreeNode currentNode) {
60          this.loaderWait.setIcon(UiUtil.HOURGLASS.getIcon());
61          this.loaderWait.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
62  
63          this.progressBar.setPreferredSize(new Dimension(20, 20));
64          this.progressBar.setBorder(BorderFactory.createEmptyBorder(4, 3, 4, 3));
65  
66          this.nodeLabel.setOpaque(true);
67  
68          this.iconNode.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
69          
70          this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
71          
72          Stream.of(
73              this.iconNode,
74              this.loaderWait,
75              this.progressBar,
76              this.nodeLabel,
77              this.textFieldEditable
78          )
79          .forEach(component -> {
80              this.add(component);
81              component.setVisible(false);
82          });
83          
84          this.setComponentOrientation(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()));
85          
86          this.initTextFieldEditable(tree, currentNode);
87      }
88  
89      private void initTextFieldEditable(final JTree tree, final DefaultMutableTreeNode currentNode) {
90          this.textFieldEditable.addActionListener(e -> {
91              AbstractNodeModel nodeModel = (AbstractNodeModel) currentNode.getUserObject();
92              nodeModel.setIsEdited(false);
93              
94              this.nodeLabel.setVisible(true);
95              this.textFieldEditable.setVisible(false);
96              tree.requestFocusInWindow();
97  
98              nodeModel.getElementDatabase().setElementValue(new String(
99                  this.textFieldEditable.getText().getBytes(StandardCharsets.UTF_8),
100                 StandardCharsets.UTF_8
101             ));
102             this.nodeLabel.setText(UiStringUtil.detectUtf8Html(nodeModel.getElementDatabase().getLabelWithCount()));
103             
104             tree.revalidate();
105             tree.repaint();
106         });
107         
108         this.textFieldEditable.addFocusListener(new FocusAdapter() {
109             @Override
110             public void focusLost(FocusEvent e) {
111                 AbstractNodeModel nodeModel = (AbstractNodeModel) currentNode.getUserObject();
112                 nodeModel.setIsEdited(false);
113                 tree.revalidate();
114                 tree.repaint();
115             }
116         });
117         
118         KeyAdapter keyAdapterF2 = new KeyAdapter() {
119             @Override
120             public void keyPressed(KeyEvent e) {
121                 AbstractNodeModel nodeModel = (AbstractNodeModel) currentNode.getUserObject();
122                 
123                 if (e.getKeyCode() == KeyEvent.VK_F2 && !nodeModel.isRunning()) {
124                     nodeModel.setIsEdited(true);
125                     
126                     PanelNode.this.nodeLabel.setVisible(false);
127                     PanelNode.this.textFieldEditable.setVisible(true);
128                     PanelNode.this.textFieldEditable.requestFocusInWindow();
129                     
130                     tree.revalidate();
131                     tree.repaint();
132                 }
133             }
134         };
135         
136         this.addKeyListener(keyAdapterF2);
137         this.textFieldEditable.addKeyListener(keyAdapterF2);
138     }
139 
140     /**
141      * Change the text icon.
142      * @param newIcon An icon to display next to the text.
143      */
144     public void setIconNode(Icon newIcon) {
145         this.iconNode.setIcon(newIcon);
146     }
147     
148     /**
149      * Display text icon to the left.
150      */
151     public void showIcon() {
152         this.iconNode.setVisible(true);
153     }
154     
155     /**
156      * Mask the node icon for example when the loader component is displayed.
157      */
158     public void hideIcon() {
159         this.iconNode.setVisible(false);
160     }
161     
162     /**
163      * Change the loader icon.
164      * @param newIcon An icon to display for the loader.
165      */
166     public void setLoaderIcon(Icon newIcon) {
167         this.loaderWait.setIcon(newIcon);
168     }
169 
170     /**
171      * Display the animated gif loader.
172      */
173     public void showLoader() {
174         this.loaderWait.setVisible(true);
175     }
176     
177     
178     // Getter and setter
179 
180     public ProgressBarPausable getProgressBar() {
181         return this.progressBar;
182     }
183 
184     public JLabel getNodeLabel() {
185         return this.nodeLabel;
186     }
187 
188     public JTextField getTextFieldEditable() {
189         return this.textFieldEditable;
190     }
191 }