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                 if (e.getKeyCode() == KeyEvent.VK_F2 && !nodeModel.isRunning()) {
123                     nodeModel.setIsEdited(true);
124                     
125                     PanelNode.this.nodeLabel.setVisible(false);
126                     PanelNode.this.textFieldEditable.setVisible(true);
127                     PanelNode.this.textFieldEditable.requestFocusInWindow();
128                     
129                     tree.revalidate();
130                     tree.repaint();
131                 }
132             }
133         };
134         
135         this.addKeyListener(keyAdapterF2);
136         this.textFieldEditable.addKeyListener(keyAdapterF2);
137     }
138 
139     /**
140      * Change the text icon.
141      * @param newIcon An icon to display next to the text.
142      */
143     public void setIconNode(Icon newIcon) {
144         this.iconNode.setIcon(newIcon);
145     }
146     
147     /**
148      * Display text icon to the left.
149      */
150     public void showIcon() {
151         this.iconNode.setVisible(true);
152     }
153     
154     /**
155      * Mask the node icon for example when the loader component is displayed.
156      */
157     public void hideIcon() {
158         this.iconNode.setVisible(false);
159     }
160     
161     /**
162      * Change the loader icon.
163      * @param newIcon An icon to display for the loader.
164      */
165     public void setLoaderIcon(Icon newIcon) {
166         this.loaderWait.setIcon(newIcon);
167     }
168 
169     /**
170      * Display the animated gif loader.
171      */
172     public void showLoader() {
173         this.loaderWait.setVisible(true);
174     }
175     
176     
177     // Getter and setter
178 
179     public ProgressBarPausable getProgressBar() {
180         return this.progressBar;
181     }
182 
183     public JLabel getNodeLabel() {
184         return this.nodeLabel;
185     }
186 
187     public JTextField getTextFieldEditable() {
188         return this.textFieldEditable;
189     }
190 }