1 package com.jsql.view.swing.menubar;
2
3 import com.formdev.flatlaf.intellijthemes.FlatDarkFlatIJTheme;
4 import com.formdev.flatlaf.intellijthemes.FlatHighContrastIJTheme;
5 import com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme;
6 import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTGitHubDarkIJTheme;
7 import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTGitHubIJTheme;
8 import com.formdev.flatlaf.themes.FlatMacDarkLaf;
9 import com.formdev.flatlaf.themes.FlatMacLightLaf;
10 import com.jsql.util.I18nUtil;
11 import com.jsql.util.PreferencesUtil;
12 import com.jsql.view.swing.action.ActionNewWindow;
13 import com.jsql.view.swing.dialog.translate.Language;
14 import com.jsql.view.swing.panel.PanelPreferences;
15 import com.jsql.view.swing.sql.SqlEngine;
16 import com.jsql.view.swing.tab.TabHeader;
17 import com.jsql.view.swing.util.I18nViewUtil;
18 import com.jsql.view.swing.util.MediatorHelper;
19 import com.jsql.view.swing.util.RadioItemNonClosing;
20 import com.jsql.view.swing.util.UiUtil;
21
22 import javax.swing.*;
23 import java.awt.*;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.InputEvent;
26 import java.awt.event.KeyEvent;
27 import java.awt.event.MouseEvent;
28 import java.util.AbstractMap;
29 import java.util.Arrays;
30 import java.util.Locale;
31 import java.util.concurrent.atomic.AtomicBoolean;
32 import java.util.concurrent.atomic.AtomicInteger;
33
34 public class MenuWindows extends JMenu {
35
36 private static final String I18N_SQL_ENGINE = "MENUBAR_SQL_ENGINE";
37 private static final String I18N_PREFERENCES = "MENUBAR_PREFERENCES";
38 private final AppMenubar appMenubar;
39
40 private final JMenu menuView;
41
42 public MenuWindows(AppMenubar appMenubar) {
43 super(I18nUtil.valueByKey("MENUBAR_WINDOWS"));
44 this.appMenubar = appMenubar;
45
46 this.setName("menuWindows");
47 I18nViewUtil.addComponentForKey("MENUBAR_WINDOWS", this);
48 this.setMnemonic('W');
49
50 JMenuItem itemNewWindows = new JMenuItem(new ActionNewWindow());
51 I18nViewUtil.addComponentForKey("NEW_WINDOW_MENU", itemNewWindows);
52
53 this.add(itemNewWindows);
54 var menuAppearance = new JMenu(I18nUtil.valueByKey("MENUBAR_APPEARANCE"));
55 I18nViewUtil.addComponentForKey("MENUBAR_APPEARANCE", menuAppearance);
56 menuAppearance.setMnemonic('A');
57
58 JMenuItem itemNewWindows4k = new JMenuItem(
59 new ActionNewWindow("Open window in 4K resolution...", "-Dsun.java2d.uiScale=2.5")
60 );
61 menuAppearance.add(itemNewWindows4k);
62
63 var groupRadio = new ButtonGroup();
64 var menuThemes = new JMenu(I18nUtil.valueByKey("MENUBAR_THEMES"));
65 I18nViewUtil.addComponentForKey("MENUBAR_THEMES", menuAppearance);
66 menuThemes.setMnemonic('T');
67
68 Arrays.asList(
69 new AbstractMap.SimpleEntry<>(FlatLightFlatIJTheme.class.getName(), "IntelliJ"),
70 new AbstractMap.SimpleEntry<>(FlatDarkFlatIJTheme.class.getName(), "IntelliJ Dark"),
71 new AbstractMap.SimpleEntry<>(FlatMacLightLaf.class.getName(), "macOS"),
72 new AbstractMap.SimpleEntry<>(FlatMacDarkLaf.class.getName(), "macOS Dark"),
73 new AbstractMap.SimpleEntry<>(FlatMTGitHubIJTheme.class.getName(), "GitHub"),
74 new AbstractMap.SimpleEntry<>(FlatMTGitHubDarkIJTheme.class.getName(), "GitHub Dark"),
75 new AbstractMap.SimpleEntry<>(FlatHighContrastIJTheme.class.getName(), "High contrast")
76 ).forEach(entry -> {
77 JMenuItem item = new RadioItemNonClosing(
78 new AbstractAction() {
79 @Override
80 public void actionPerformed(ActionEvent e) {
81 AppMenubar.applyTheme(entry.getKey());
82 }
83 }
84 );
85 item.setText(entry.getValue());
86 item.setSelected(entry.getKey().equals(MediatorHelper.model().getMediatorUtils().getPreferencesUtil().getThemeFlatLafName()));
87 groupRadio.add(item);
88 menuThemes.add(item);
89 });
90
91 this.add(itemNewWindows);
92 this.add(menuAppearance);
93 this.add(menuThemes);
94 this.add(new JSeparator());
95 this.add(this.initMenuTranslation());
96 this.add(new JSeparator());
97
98 this.menuView = new JMenu(I18nUtil.valueByKey("MENUBAR_VIEW"));
99 I18nViewUtil.addComponentForKey("MENUBAR_VIEW", this.menuView);
100 this.menuView.setMnemonic('V');
101
102 AtomicInteger accelerator = new AtomicInteger(0x31);
103 AtomicInteger tabPosition = new AtomicInteger();
104 MediatorHelper.frame().getTabManagers().getIconsTabs().forEach(entry -> {
105 var menuItem = new JMenuItem(I18nUtil.valueByKey(entry.getKeyLabel()), entry.getIcon());
106 I18nViewUtil.addComponentForKey(entry.getKeyLabel(), menuItem);
107 menuItem.setName(entry.getKeyLabel());
108 this.menuView.add(menuItem);
109
110 menuItem.setAccelerator(KeyStroke.getKeyStroke(
111 KeyEvent.getExtendedKeyCodeForChar(accelerator.getAndIncrement()),
112 InputEvent.CTRL_DOWN_MASK
113 ));
114
115 final var position = tabPosition.get();
116 menuItem.addActionListener(actionEvent -> {
117 CardLayout cardLayout = (CardLayout) MediatorHelper.tabManagersCards().getLayout();
118 cardLayout.show(MediatorHelper.tabManagersCards(), menuItem.getName());
119 MediatorHelper.frame().getTabManagers().setSelectedIndex(position);
120 });
121 tabPosition.getAndIncrement();
122 });
123
124 this.add(this.menuView);
125
126 var menuPanel = new JMenu(I18nUtil.valueByKey("MENUBAR_PANEL"));
127 I18nViewUtil.addComponentForKey("MENUBAR_PANEL", menuPanel);
128 menuPanel.setMnemonic('C');
129
130 Arrays.asList(
131 new ModelCheckboxMenu(
132 "CONSOLE_CHUNK_LABEL",
133 PreferencesUtil.CHUNK_VISIBLE,
134 () -> MediatorHelper.panelConsoles().insertChunkTab(),
135 UiUtil.CHUNK.getIcon()
136 ),
137 new ModelCheckboxMenu(
138 "CONSOLE_BINARY_LABEL",
139 PreferencesUtil.BINARY_VISIBLE,
140 () -> MediatorHelper.panelConsoles().insertBooleanTab(),
141 UiUtil.BINARY.getIcon()
142 ),
143 new ModelCheckboxMenu(
144 "CONSOLE_NETWORK_LABEL",
145 PreferencesUtil.NETWORK_VISIBLE,
146 () -> MediatorHelper.panelConsoles().insertNetworkTab(),
147 UiUtil.NETWORK.getIcon()
148 ),
149 new ModelCheckboxMenu(
150 "CONSOLE_JAVA_LABEL",
151 PreferencesUtil.JAVA_VISIBLE,
152 () -> MediatorHelper.panelConsoles().insertJavaTab(),
153 UiUtil.CUP.getIcon(),
154 false
155 )
156 ).forEach(model -> {
157 var menuItem = new JCheckBoxMenuItem(
158 I18nUtil.valueByKey(model.i18n),
159 model.icon,
160 model.isChecked
161 ) {
162 @Override
163 protected void processMouseEvent(MouseEvent e) {
164 if (RadioItemNonClosing.shouldClose(e, this)) {
165 super.processMouseEvent(e);
166 }
167 }
168 };
169 I18nViewUtil.addComponentForKey(model.i18n, menuItem);
170 menuPanel.add(menuItem);
171
172 menuItem.addActionListener(actionEvent -> {
173 if (menuItem.isSelected()) {
174 model.runnableInsertTab.run();
175 } else {
176 MediatorHelper.tabConsoles().remove(MediatorHelper.tabConsoles().indexOfTab(model.icon));
177 }
178 });
179 });
180
181 this.add(menuPanel);
182 this.add(new JSeparator());
183 this.add(this.getMenuItemSqlEngine());
184 this.add(this.getMenuItemPreferences());
185 }
186
187 private JMenuItem getMenuItemSqlEngine() {
188 var itemSqlEngine = new JMenuItem(I18nUtil.valueByKey(MenuWindows.I18N_SQL_ENGINE));
189 I18nViewUtil.addComponentForKey(MenuWindows.I18N_SQL_ENGINE, itemSqlEngine);
190 itemSqlEngine.setName("itemSqlEngine");
191 itemSqlEngine.setMnemonic('S');
192
193
194 var titleTabSqlEngine = "SQL Engine";
195
196 itemSqlEngine.addActionListener(actionEvent -> {
197 for (var i = 0 ; i < MediatorHelper.tabResults().getTabCount() ; i++) {
198 if (titleTabSqlEngine.equals(MediatorHelper.tabResults().getTitleAt(i))) {
199 MediatorHelper.tabResults().setSelectedIndex(i);
200 return;
201 }
202 }
203
204 MediatorHelper.frame().getSplitNS().initSplitOrientation();
205
206 var panelSqlEngine = new SqlEngine();
207 MediatorHelper.tabResults().addTab(titleTabSqlEngine, panelSqlEngine);
208 MediatorHelper.tabResults().setSelectedComponent(panelSqlEngine);
209
210
211 var header = new TabHeader(I18nViewUtil.valueByKey(MenuWindows.I18N_SQL_ENGINE), UiUtil.COG.getIcon());
212 I18nViewUtil.addComponentForKey(MenuWindows.I18N_SQL_ENGINE, header.getTabLabel());
213
214
215 MediatorHelper.tabResults().setTabComponentAt(MediatorHelper.tabResults().indexOfComponent(panelSqlEngine), header);
216 MediatorHelper.tabResults().updateUI();
217 });
218
219 return itemSqlEngine;
220 }
221
222 private JMenuItem getMenuItemPreferences() {
223 JMenuItem itemPreferences = new JMenuItem(I18nUtil.valueByKey(MenuWindows.I18N_PREFERENCES), 'P');
224 I18nViewUtil.addComponentForKey(MenuWindows.I18N_PREFERENCES, itemPreferences);
225 itemPreferences.setName("itemPreferences");
226
227
228 var titleTabPreferences = "Preferences";
229
230 itemPreferences.addActionListener(actionEvent -> {
231 for (var i = 0 ; i < MediatorHelper.tabResults().getTabCount() ; i++) {
232 if (titleTabPreferences.equals(MediatorHelper.tabResults().getTitleAt(i))) {
233 MediatorHelper.tabResults().setSelectedIndex(i);
234 return;
235 }
236 }
237
238 MediatorHelper.frame().getSplitNS().initSplitOrientation();
239
240 var panelPreferences = new PanelPreferences();
241 MediatorHelper.tabResults().addTab(titleTabPreferences, panelPreferences);
242 MediatorHelper.tabResults().setSelectedComponent(panelPreferences);
243
244
245 var header = new TabHeader(I18nViewUtil.valueByKey(MenuWindows.I18N_PREFERENCES), UiUtil.COG.getIcon());
246 I18nViewUtil.addComponentForKey(MenuWindows.I18N_PREFERENCES, header.getTabLabel());
247
248
249 MediatorHelper.tabResults().setTabComponentAt(MediatorHelper.tabResults().indexOfComponent(panelPreferences), header);
250
251 MediatorHelper.tabResults().updateUI();
252 });
253
254 return itemPreferences;
255 }
256
257 private JMenu initMenuTranslation() {
258 var menuTranslation = new JMenu(I18nUtil.valueByKey("MENUBAR_LANGUAGE"));
259 I18nViewUtil.addComponentForKey("MENUBAR_LANGUAGE", menuTranslation);
260 menuTranslation.setName("menuTranslation");
261 menuTranslation.setMnemonic('L');
262
263 var groupRadioLanguage = new ButtonGroup();
264 var atomicIsAnySelected = new AtomicBoolean(false);
265 AppMenubar.MODELS_ITEM.forEach(model -> {
266 atomicIsAnySelected.set(atomicIsAnySelected.get() || model.getLanguage().isCurrentLanguage());
267 model.setMenuItem(new RadioItemNonClosing(
268 model.getLanguage().getMenuItemLabel(),
269 model.getLanguage().getFlag(),
270 model.getLanguage().isCurrentLanguage()
271 ));
272 model.getMenuItem().addActionListener(actionEvent -> {
273 this.appMenubar.switchLocale(
274 model.getLanguage() == Language.EN
275 ? Locale.ROOT
276 : Locale.forLanguageTag(model.getLanguage().getLanguageTag())
277 );
278 MediatorHelper.model().getMediatorUtils().getPreferencesUtil().withLanguageTag(model.getLanguage().getLanguageTag()).persist();
279 });
280 menuTranslation.add(model.getMenuItem());
281 groupRadioLanguage.add(model.getMenuItem());
282 });
283
284 AppMenubar.MODELS_ITEM.stream().filter(model -> model.getLanguage() == Language.EN)
285 .forEach(modelItem -> {
286 modelItem.getMenuItem().setSelected(!atomicIsAnySelected.get());
287 modelItem.getMenuItem().setName("itemEnglish");
288 });
289 AppMenubar.MODELS_ITEM.stream().filter(model -> model.getLanguage() == Language.RU)
290 .forEach(modelItem -> modelItem.getMenuItem().setName("itemRussian"));
291 AppMenubar.MODELS_ITEM.stream().filter(model -> model.getLanguage() == Language.AR)
292 .forEach(modelItem -> modelItem.getMenuItem().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT));
293
294 return menuTranslation;
295 }
296
297 public void switchLocaleFromPreferences() {
298 AppMenubar.MODELS_ITEM.stream().filter(model -> model.getLanguage().getLanguageTag().equals(
299 MediatorHelper.model().getMediatorUtils().getPreferencesUtil().getLanguageTag()
300 ))
301 .forEach(modelItem -> modelItem.getMenuItem().doClick());
302 }
303
304
305
306
307 public JMenu getMenuView() {
308 return this.menuView;
309 }
310 }