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