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.panel.split;
12  
13  import com.jsql.view.swing.util.JSplitPaneWithZeroSizeDivider;
14  import com.jsql.model.InjectionModel;
15  import com.jsql.util.I18nUtil;
16  import com.jsql.util.PreferencesUtil;
17  import com.jsql.view.swing.panel.PanelConsoles;
18  import com.jsql.view.swing.tab.TabManagersCards;
19  import com.jsql.view.swing.tab.TabResults;
20  import com.jsql.view.swing.util.MediatorHelper;
21  import com.jsql.view.swing.util.UiUtil;
22  
23  import javax.swing.*;
24  import java.awt.*;
25  import java.awt.event.MouseAdapter;
26  import java.awt.event.MouseEvent;
27  import java.util.prefs.Preferences;
28  
29  /**
30   * SplitPane composed of tree and tabs on top, and info tabs on bottom.
31   */
32  public class SplitNS extends JSplitPaneWithZeroSizeDivider {
33  
34      public static final String BUTTON_SHOW_CONSOLES_HIDDEN = "buttonShowConsolesHidden";
35  
36      /**
37       * SplitPane containing Manager panels on the left and result tabs on the right.
38       */
39      private final JSplitPane splitEW = new JSplitPaneWithZeroSizeDivider(JSplitPane.HORIZONTAL_SPLIT);
40  
41      private static final JPanel PANEL_HIDDEN_CONSOLES = new JPanel();
42      
43      /**
44       * MouseAdapter used on arrow on tabbedpane header and on
45       * ersatz button when bottom panel is hidden.
46       */
47      private static final ActionHideShowConsole ACTION_HIDE_SHOW_CONSOLE = new ActionHideShowConsole(SplitNS.PANEL_HIDDEN_CONSOLES);
48      private static final ActionHideShowResult ACTION_HIDE_SHOW_RESULT= new ActionHideShowResult();
49  
50      /**
51       * Create main panel with Manager panels on the left, result tabs on the right,
52       * and consoles in the bottom.
53       */
54      public SplitNS() {
55          super(JSplitPane.VERTICAL_SPLIT);
56          var preferences = Preferences.userRoot().node(InjectionModel.class.getName());
57          var tabManagersProxy = new TabManagersCards();
58          new TabResults();  // initialized but hidden
59  
60          // Tree and tabs on top
61          this.splitEW.setLeftComponent(tabManagersProxy);
62          JLabel labelApp = new JLabel(UiUtil.APP_BIG.getIcon());
63          labelApp.setMinimumSize(new Dimension(100, 0));
64          this.splitEW.setRightComponent(labelApp);
65          var verticalLeftRightSplitter = preferences.getDouble(PreferencesUtil.EW_SPLIT, 0.33);
66          this.splitEW.setDividerLocation(Math.clamp(verticalLeftRightSplitter, 0.0, 1.0));
67  
68          JLabel labelShowConsoles = new JLabel(UiUtil.ARROW_UP.getIcon());
69          labelShowConsoles.setBorder(BorderFactory.createEmptyBorder());
70          labelShowConsoles.addMouseListener(new MouseAdapter() {
71              @Override
72              public void mouseClicked(MouseEvent e) {
73                  SplitNS.ACTION_HIDE_SHOW_CONSOLE.actionPerformed(null);
74              }
75          });
76          labelShowConsoles.setName(SplitNS.BUTTON_SHOW_CONSOLES_HIDDEN);
77          SplitNS.PANEL_HIDDEN_CONSOLES.setLayout(new BorderLayout());
78          SplitNS.PANEL_HIDDEN_CONSOLES.add(labelShowConsoles, BorderLayout.LINE_END);
79          SplitNS.PANEL_HIDDEN_CONSOLES.setVisible(false);
80          SplitNS.PANEL_HIDDEN_CONSOLES.addMouseListener(new MouseAdapter() {
81              @Override
82              public void mousePressed(MouseEvent e) {
83                  if (e.getButton() == MouseEvent.BUTTON2) {  // middle click on header with no tab
84                      SplitNS.ACTION_HIDE_SHOW_CONSOLE.actionPerformed(null);
85                  }
86              }
87          });
88  
89          var panelManagerResult = new JPanel(new BorderLayout());
90          panelManagerResult.add(this.splitEW, BorderLayout.CENTER);
91          panelManagerResult.add(SplitNS.PANEL_HIDDEN_CONSOLES, BorderLayout.SOUTH);
92          this.setTopComponent(panelManagerResult);
93  
94          var panelConsoles = new PanelConsoles();
95          MediatorHelper.register(panelConsoles);
96          this.setBottomComponent(panelConsoles);
97  
98          this.setResizeWeight(1);
99      }
100 
101     /**
102      * Switch left component with right component when locale orientation requires it.
103      */
104     public void initSplitOrientation() {
105         if (MediatorHelper.tabResults().getTabCount() == 0) {
106             int dividerLocation = this.splitEW.getDividerLocation();
107 
108             // required by linux: set both to null => applyComponentOrientation => set both components
109             this.splitEW.setLeftComponent(null);
110             this.splitEW.setRightComponent(null);
111 
112             var componentOrientation = ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale());
113             this.splitEW.applyComponentOrientation(componentOrientation);
114 
115             if (ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getCurrentLocale()))) {
116                 this.splitEW.setLeftComponent(MediatorHelper.tabResults());
117                 this.splitEW.setRightComponent(MediatorHelper.tabManagersCards());
118             } else {
119                 this.splitEW.setLeftComponent(MediatorHelper.tabManagersCards());
120                 this.splitEW.setRightComponent(MediatorHelper.tabResults());
121             }
122             SwingUtilities.invokeLater(() -> this.splitEW.setDividerLocation(dividerLocation));  // wait for EDT refresh to prevent wrong location
123         }
124     }
125 
126     public void invokeLaterWithSplitOrientation(Runnable runnable) {
127         SwingUtilities.invokeLater(() -> {
128             this.initSplitOrientation();
129             runnable.run();
130         });
131     }
132 
133 
134     // Getter and setter
135 
136     public JSplitPane getSplitEW() {
137         return this.splitEW;
138     }
139 
140     public static ActionHideShowConsole getActionHideShowConsole() {
141         return SplitNS.ACTION_HIDE_SHOW_CONSOLE;
142     }
143     
144     public static ActionHideShowResult getActionHideShowResult() {
145         return SplitNS.ACTION_HIDE_SHOW_RESULT;
146     }
147 }