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_ARABIC = "itemArabic";
45 public static final String ITEM_ENGLISH = "itemEnglish";
46
47 private final AppMenubar appMenubar;
48
49 private final JMenu menuView;
50
51 public MenuWindows(AppMenubar appMenubar) {
52 super(I18nUtil.valueByKey("MENUBAR_WINDOWS"));
53 this.appMenubar = appMenubar;
54
55 this.setName(MenuWindows.MENU_WINDOWS);
56 I18nViewUtil.addComponentForKey("MENUBAR_WINDOWS", this);
57 this.setMnemonic('W');
58
59 JMenuItem itemNewWindows = new JMenuItem(new ActionNewWindow());
60 I18nViewUtil.addComponentForKey("NEW_WINDOW_MENU", itemNewWindows);
61
62 this.add(itemNewWindows);
63 var menuAppearance = new JMenu(I18nUtil.valueByKey("MENUBAR_APPEARANCE"));
64 I18nViewUtil.addComponentForKey("MENUBAR_APPEARANCE", menuAppearance);
65 menuAppearance.setMnemonic('A');
66
67 JMenuItem itemNewWindows4k = new JMenuItem(
68 new ActionNewWindow("Open window in 4K resolution...", "-Dsun.java2d.uiScale=2.5")
69 );
70 menuAppearance.add(itemNewWindows4k);
71
72 var groupRadio = new ButtonGroup();
73 var menuThemes = new JMenu(I18nUtil.valueByKey("MENUBAR_THEMES"));
74 I18nViewUtil.addComponentForKey("MENUBAR_THEMES", menuAppearance);
75 menuThemes.setMnemonic('T');
76
77 Arrays.asList(
78 new AbstractMap.SimpleEntry<>(FlatLightFlatIJTheme.class.getName(), "IntelliJ"),
79 new AbstractMap.SimpleEntry<>(FlatDarkFlatIJTheme.class.getName(), "IntelliJ Dark"),
80 new AbstractMap.SimpleEntry<>(FlatMacLightLaf.class.getName(), "macOS"),
81 new AbstractMap.SimpleEntry<>(FlatMacDarkLaf.class.getName(), "macOS Dark"),
82 new AbstractMap.SimpleEntry<>(FlatMTGitHubIJTheme.class.getName(), "GitHub"),
83 new AbstractMap.SimpleEntry<>(FlatMTGitHubDarkIJTheme.class.getName(), "GitHub Dark"),
84 new AbstractMap.SimpleEntry<>(FlatHighContrastIJTheme.class.getName(), "High contrast")
85 ).forEach(entry -> {
86 JMenuItem item = new RadioItemNonClosing(
87 new AbstractAction() {
88 @Override
89 public void actionPerformed(ActionEvent e) {
90 AppMenubar.applyTheme(entry.getKey());
91 }
92 }
93 );
94 item.setText(entry.getValue());
95 item.setSelected(entry.getKey().equals(MediatorHelper.model().getMediatorUtils().preferencesUtil().getThemeFlatLafName()));
96 groupRadio.add(item);
97 menuThemes.add(item);
98 });
99
100 this.add(itemNewWindows);
101 this.add(menuAppearance);
102 this.add(menuThemes);
103 this.add(new JSeparator());
104 this.add(this.initMenuTranslation());
105 this.add(new JSeparator());
106
107 this.menuView = new JMenu(I18nUtil.valueByKey("MENUBAR_VIEW"));
108 I18nViewUtil.addComponentForKey("MENUBAR_VIEW", this.menuView);
109 this.menuView.setMnemonic('V');
110
111 AtomicInteger accelerator = new AtomicInteger(0x31);
112 AtomicInteger tabPosition = new AtomicInteger();
113 MediatorHelper.frame().getTabManagers().getIconsTabs().forEach(entry -> {
114 var menuItem = new JMenuItem(I18nUtil.valueByKey(entry.getKeyLabel()), entry.getIcon());
115 I18nViewUtil.addComponentForKey(entry.getKeyLabel(), menuItem);
116 menuItem.setName(entry.getKeyLabel());
117 this.menuView.add(menuItem);
118
119 menuItem.setAccelerator(KeyStroke.getKeyStroke(
120 KeyEvent.getExtendedKeyCodeForChar(accelerator.getAndIncrement()),
121 InputEvent.CTRL_DOWN_MASK
122 ));
123
124 final var position = tabPosition.get();
125 menuItem.addActionListener(actionEvent -> {
126 CardLayout cardLayout = (CardLayout) MediatorHelper.tabManagersCards().getLayout();
127 cardLayout.show(MediatorHelper.tabManagersCards(), menuItem.getName());
128 MediatorHelper.frame().getTabManagers().setSelectedIndex(position);
129 });
130 tabPosition.getAndIncrement();
131 });
132
133 this.add(this.menuView);
134
135 var menuPanel = new JMenu(I18nUtil.valueByKey("MENUBAR_PANEL"));
136 I18nViewUtil.addComponentForKey("MENUBAR_PANEL", menuPanel);
137 menuPanel.setMnemonic('C');
138
139 Arrays.asList(
140 new ModelCheckboxMenu(
141 "CONSOLE_CHUNK_LABEL",
142 PreferencesUtil.CHUNK_VISIBLE,
143 () -> MediatorHelper.panelConsoles().insertChunkTab(),
144 UiUtil.CHUNK.getIcon()
145 ),
146 new ModelCheckboxMenu(
147 "CONSOLE_BINARY_LABEL",
148 PreferencesUtil.BINARY_VISIBLE,
149 () -> MediatorHelper.panelConsoles().insertBooleanTab(),
150 UiUtil.BINARY.getIcon()
151 ),
152 new ModelCheckboxMenu(
153 "CONSOLE_NETWORK_LABEL",
154 PreferencesUtil.NETWORK_VISIBLE,
155 () -> MediatorHelper.panelConsoles().insertNetworkTab(),
156 UiUtil.NETWORK.getIcon()
157 ),
158 new ModelCheckboxMenu(
159 "CONSOLE_JAVA_LABEL",
160 PreferencesUtil.JAVA_VISIBLE,
161 () -> MediatorHelper.panelConsoles().insertJavaTab(),
162 UiUtil.CUP.getIcon(),
163 false
164 )
165 ).forEach(model -> {
166 var menuItem = new JCheckBoxMenuItem(
167 I18nUtil.valueByKey(model.i18n),
168 model.icon,
169 model.isChecked
170 ) {
171 @Override
172 protected void processMouseEvent(MouseEvent e) {
173 if (RadioItemNonClosing.shouldClose(e, this)) {
174 super.processMouseEvent(e);
175 }
176 }
177 };
178 I18nViewUtil.addComponentForKey(model.i18n, menuItem);
179 menuPanel.add(menuItem);
180
181 menuItem.addActionListener(actionEvent -> {
182 if (menuItem.isSelected()) {
183 model.runnableInsertTab.run();
184 } else {
185 MediatorHelper.tabConsoles().remove(MediatorHelper.tabConsoles().indexOfTab(model.icon));
186 }
187 });
188 });
189
190 this.add(menuPanel);
191 this.add(new JSeparator());
192 this.add(this.getMenuItemSqlEngine());
193 this.add(this.getMenuItemPreferences());
194 }
195
196 private JMenuItem getMenuItemSqlEngine() {
197 var itemSqlEngine = new JMenuItem(I18nUtil.valueByKey(MenuWindows.I18N_SQL_ENGINE));
198 I18nViewUtil.addComponentForKey(MenuWindows.I18N_SQL_ENGINE, itemSqlEngine);
199 itemSqlEngine.setName("itemSqlEngine");
200 itemSqlEngine.setMnemonic('S');
201
202 itemSqlEngine.addActionListener(actionEvent -> {
203 var titleTabSqlEngine = "SQL Engine";
204 for (var i = 0 ; i < MediatorHelper.tabResults().getTabCount() ; i++) {
205 if (titleTabSqlEngine.equals(MediatorHelper.tabResults().getTitleAt(i))) {
206 MediatorHelper.tabResults().setSelectedIndex(i);
207 return;
208 }
209 }
210
211 MediatorHelper.frame().getSplitNS().initSplitOrientation();
212
213 var panelSqlEngine = new SqlEngine();
214 MediatorHelper.tabResults().addTab(titleTabSqlEngine, panelSqlEngine);
215 MediatorHelper.tabResults().setSelectedComponent(panelSqlEngine);
216
217
218 var header = new TabHeader(I18nViewUtil.valueByKey(MenuWindows.I18N_SQL_ENGINE), UiUtil.COG.getIcon());
219 I18nViewUtil.addComponentForKey(MenuWindows.I18N_SQL_ENGINE, header.getTabLabel());
220
221
222 MediatorHelper.tabResults().setTabComponentAt(MediatorHelper.tabResults().indexOfComponent(panelSqlEngine), header);
223 MediatorHelper.tabResults().updateUI();
224 });
225
226 return itemSqlEngine;
227 }
228
229 private JMenuItem getMenuItemPreferences() {
230 JMenuItem itemPreferences = new JMenuItem(I18nUtil.valueByKey(MenuWindows.I18N_PREFERENCES), 'P');
231 I18nViewUtil.addComponentForKey(MenuWindows.I18N_PREFERENCES, itemPreferences);
232 itemPreferences.setName("itemPreferences");
233
234
235 var titleTabPreferences = "Preferences";
236
237 itemPreferences.addActionListener(actionEvent -> {
238 for (var i = 0 ; i < MediatorHelper.tabResults().getTabCount() ; i++) {
239 if (titleTabPreferences.equals(MediatorHelper.tabResults().getTitleAt(i))) {
240 MediatorHelper.tabResults().setSelectedIndex(i);
241 return;
242 }
243 }
244
245 MediatorHelper.frame().getSplitNS().initSplitOrientation();
246
247 var panelPreferences = new PanelPreferences();
248 MediatorHelper.tabResults().addTab(titleTabPreferences, panelPreferences);
249 MediatorHelper.tabResults().setSelectedComponent(panelPreferences);
250
251
252 var header = new TabHeader(I18nViewUtil.valueByKey(MenuWindows.I18N_PREFERENCES), UiUtil.COG.getIcon());
253 I18nViewUtil.addComponentForKey(MenuWindows.I18N_PREFERENCES, header.getTabLabel());
254
255
256 MediatorHelper.tabResults().setTabComponentAt(MediatorHelper.tabResults().indexOfComponent(panelPreferences), header);
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 -> {
305 modelItem.getMenuItem().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
306 modelItem.getMenuItem().setName(MenuWindows.ITEM_ARABIC);
307 });
308
309 return menuTranslation;
310 }
311
312 public void switchLocaleFromPreferences() {
313 AppMenubar.ITEMS_TRANSLATE.stream().filter(model -> model.getLanguage().getLanguageTag().equals(
314 MediatorHelper.model().getMediatorUtils().preferencesUtil().getLanguageTag()
315 ))
316 .forEach(modelItem -> {
317 modelItem.getMenuItem().setActionCommand(MenuWindows.ACTION_STARTING_APP);
318 modelItem.getMenuItem().doClick();
319 });
320 }
321
322
323
324
325 public JMenu getMenuView() {
326 return this.menuView;
327 }
328 }