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.model;
12  
13  import com.jsql.model.bean.database.Table;
14  import com.jsql.model.suspendable.AbstractSuspendable;
15  import com.jsql.util.StringUtil;
16  import com.jsql.view.swing.text.JPopupTextField;
17  import com.jsql.view.swing.tree.custom.CheckBoxMenuItemIconCustom;
18  import com.jsql.view.swing.tree.ImageOverlap;
19  import com.jsql.view.swing.tree.PanelNode;
20  import com.jsql.view.swing.tree.action.ActionCheckAll;
21  import com.jsql.view.swing.tree.custom.JPopupMenuCustomExtract;
22  import com.jsql.view.swing.util.I18nViewUtil;
23  import com.jsql.view.swing.util.MediatorHelper;
24  import com.jsql.view.swing.util.UiUtil;
25  
26  import javax.swing.*;
27  import javax.swing.tree.DefaultMutableTreeNode;
28  import javax.swing.tree.DefaultTreeModel;
29  import javax.swing.tree.TreePath;
30  import java.awt.*;
31  
32  /**
33   * Table model displaying the table icon on the label.
34   */
35  public class NodeModelTable extends AbstractNodeModel {
36      
37      /**
38       * Node as a table model.
39       * @param table Element table coming from model
40       */
41      public NodeModelTable(Table table) {
42          super(table);
43      }
44  
45      @Override
46      protected Icon getLeafIcon(boolean leaf) {
47          if (leaf) {
48              return UiUtil.TABLE_LINEAR.getIcon();
49          } else {
50              return UiUtil.TABLE_BOLD.getIcon();
51          }
52      }
53  
54      @Override
55      protected void displayProgress(PanelNode panelNode, DefaultMutableTreeNode currentNode) {
56          if (StringUtil.INFORMATION_SCHEMA.equals(this.getParent().toString())) {
57              panelNode.showLoader();
58              AbstractSuspendable suspendableTask = MediatorHelper.model().getMediatorUtils().getThreadUtil().get(this.getElementDatabase());
59              if (suspendableTask != null && suspendableTask.isPaused()) {
60                  panelNode.setLoaderIcon(new ImageOverlap(UiUtil.HOURGLASS.getIcon(), UiUtil.PATH_PAUSE));
61              }
62          } else {
63              super.displayProgress(panelNode, currentNode);
64          }
65      }
66  
67      @Override
68      public void runAction() {
69          if (this.isRunning()) {  // Prevent double thread run
70              return;
71          }
72              
73          DefaultMutableTreeNode treeNode = MediatorHelper.treeDatabase().getTreeNodeModels().get(this.getElementDatabase());
74          treeNode.removeAllChildren();
75          
76          DefaultTreeModel treeModel = (DefaultTreeModel) MediatorHelper.treeDatabase().getModel();
77          treeModel.reload(treeNode);
78  
79          new SwingWorker<>() {
80              @Override
81              protected Object doInBackground() throws Exception {
82                  Thread.currentThread().setName("SwingWorkerNodeModelTable");
83                  var selectedTable = (Table) NodeModelTable.this.getElementDatabase();
84                  return MediatorHelper.model().getDataAccess().listColumns(selectedTable);
85              }
86          }.execute();
87          
88          this.setRunning(true);
89      }
90  
91      @Override
92      protected void buildMenu(JPopupMenuCustomExtract tablePopupMenu, final TreePath path) {
93          this.addCheckUncheckItems(tablePopupMenu, path);
94          // this.addCustomLoadItems(tablePopupMenu);
95      }
96  
97      private void addCustomLoadItems(JPopupMenuCustomExtract tablePopupMenu) {
98          
99          var menuCustomLoad = new JMenu("Custom load");
100         
101         var buttonGroupLoadRows = new ButtonGroup();
102         
103         JMenuItem menuItemLoadAllRows = new JRadioButtonMenuItem("Load all rows (default)", true);
104         JMenuItem menuItemLoadOneRow = new JRadioButtonMenuItem("Load first row only");
105         JMenuItem menuItemDump = new JCheckBoxMenuItem("Dump to a file");
106         
107         var panelCustomFromRow = new JPanel(new BorderLayout());
108         final JTextField inputCustomFromRow = new JPopupTextField("no.", "1").getProxy();
109         inputCustomFromRow.setHorizontalAlignment(SwingConstants.TRAILING);
110         var d = new Dimension(
111             (int) inputCustomFromRow.getPreferredSize().getWidth() + 50,
112             (int) inputCustomFromRow.getPreferredSize().getHeight()
113         );
114         inputCustomFromRow.setPreferredSize(d);
115 
116         final var radioCustomFromRow = new JCheckBox("<html><pre style=\"font-family:'Segoe UI';padding-left: 1px;\">Load from row no.&#9;</pre></html>");
117         radioCustomFromRow.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0));
118         radioCustomFromRow.setIcon(new CheckBoxMenuItemIconCustom());
119         radioCustomFromRow.setFocusPainted(false);
120         
121         panelCustomFromRow.add(radioCustomFromRow, BorderLayout.LINE_START);
122         panelCustomFromRow.add(inputCustomFromRow, BorderLayout.CENTER);
123         
124         var panelCustomToRow = new JPanel(new BorderLayout());
125         final JTextField inputCustomToRow = new JPopupTextField("no.", "65565").getProxy();
126         inputCustomToRow.setHorizontalAlignment(SwingConstants.TRAILING);
127         inputCustomToRow.setPreferredSize(d);
128 
129         final var radioCustomToRow = new JCheckBox("<html><pre style=\"font-family:'Segoe UI';padding-left: 1px;\">Load to row no.&#9;&#9;&#9;&#9;&#9;&#9;</pre></html>");
130         radioCustomToRow.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0));
131         radioCustomToRow.setIcon(new CheckBoxMenuItemIconCustom());
132         radioCustomToRow.setFocusPainted(false);
133         
134         panelCustomToRow.add(radioCustomToRow, BorderLayout.LINE_START);
135         panelCustomToRow.add(inputCustomToRow, BorderLayout.CENTER);
136         
137         var panelCustomFromChar = new JPanel(new BorderLayout());
138         final JTextField inputCustomFromChar = new JPopupTextField("no.", "1").getProxy();
139         inputCustomFromChar.setHorizontalAlignment(SwingConstants.TRAILING);
140         inputCustomFromChar.setPreferredSize(d);
141 
142         final var radioCustomFromChar = new JCheckBox("<html><pre style=\"font-family:'Segoe UI';padding-left: 1px;\">Load from char no.</pre></html>");
143         radioCustomFromChar.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0));
144         radioCustomFromChar.setIcon(new CheckBoxMenuItemIconCustom());
145         radioCustomFromChar.setFocusPainted(false);
146         
147         panelCustomFromChar.add(radioCustomFromChar, BorderLayout.LINE_START);
148         panelCustomFromChar.add(inputCustomFromChar, BorderLayout.CENTER);
149         
150         var panelCustomToChar = new JPanel(new BorderLayout());
151         final JTextField inputCustomToChar = new JPopupTextField("no.", "65565").getProxy();
152         inputCustomToChar.setHorizontalAlignment(SwingConstants.TRAILING);
153         inputCustomToChar.setPreferredSize(d);
154 
155         final var radioCustomToChar = new JCheckBox("<html><pre style=\"font-family:'Segoe UI';padding-left: 1px;\">Load to char no.&#9;&#9;&#9;&#9;&#9;</pre></html>");
156         radioCustomToChar.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0));
157         radioCustomToChar.setIcon(new CheckBoxMenuItemIconCustom());
158         radioCustomToChar.setFocusPainted(false);
159         
160         panelCustomToChar.add(radioCustomToChar, BorderLayout.LINE_START);
161         panelCustomToChar.add(inputCustomToChar, BorderLayout.CENTER);
162 
163         buttonGroupLoadRows.add(menuItemLoadAllRows);
164         buttonGroupLoadRows.add(menuItemLoadOneRow);
165       
166         menuCustomLoad.add(menuItemLoadAllRows);
167         menuCustomLoad.add(menuItemLoadOneRow);
168         menuCustomLoad.add(new JSeparator());
169         menuCustomLoad.add(panelCustomFromRow);
170         menuCustomLoad.add(panelCustomToRow);
171         menuCustomLoad.add(panelCustomFromChar);
172         menuCustomLoad.add(panelCustomToChar);
173         menuCustomLoad.add(new JSeparator());
174         menuCustomLoad.add(menuItemDump);
175 
176         tablePopupMenu.add(new JSeparator());
177         tablePopupMenu.add(menuCustomLoad);
178         
179         tablePopupMenu.setButtonGroupLoadRows(buttonGroupLoadRows);
180         tablePopupMenu.setRadioCustomFromChar(radioCustomFromChar);
181         tablePopupMenu.setRadioCustomToChar(radioCustomToChar);
182         tablePopupMenu.setRadioCustomFromRow(radioCustomFromRow);
183         tablePopupMenu.setRadioCustomToRow(radioCustomToRow);
184     }
185 
186     private void addCheckUncheckItems(JPopupMenuCustomExtract tablePopupMenu, final TreePath path) {
187         JMenuItem menuItemCheckAll = new JMenuItem(I18nViewUtil.valueByKey("COLUMNS_CHECK_ALL"), 'C');
188         I18nViewUtil.addComponentForKey("COLUMNS_CHECK_ALL", menuItemCheckAll);
189         
190         JMenuItem menuItemUncheckAll = new JMenuItem(I18nViewUtil.valueByKey("COLUMNS_UNCHECK_ALL"), 'U');
191         I18nViewUtil.addComponentForKey("COLUMNS_UNCHECK_ALL", menuItemUncheckAll);
192 
193         if (!this.isLoaded()) {
194             menuItemCheckAll.setEnabled(false);
195             menuItemUncheckAll.setEnabled(false);
196         }
197 
198         menuItemCheckAll.addActionListener(new ActionCheckAll(true, path));
199         menuItemUncheckAll.addActionListener(new ActionCheckAll(false, path));
200 
201         tablePopupMenu.add(new JSeparator());
202         tablePopupMenu.add(menuItemCheckAll);
203         tablePopupMenu.add(menuItemUncheckAll);
204     }
205     
206     @Override
207     public boolean isPopupDisplayable() {
208         return this.isLoaded() || !this.isLoaded() && this.isRunning();
209     }
210 }