2 * Instantlauncher. Copyright ©2012-2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public License
6 * or later as published by the Free Software Foundation.
9 package eu.svjatoslav.instantlauncher.menu;
11 import eu.svjatoslav.commons.gui.dialog.ExceptionDialog;
12 import eu.svjatoslav.instantlauncher.Utils;
15 import javax.swing.border.EmptyBorder;
17 import java.awt.event.MouseEvent;
18 import java.awt.event.MouseListener;
20 import java.util.Arrays;
21 import java.util.HashSet;
26 public static final Dimension SIZE_MENU_PANEL = new Dimension(210, 900);
27 private static final Color BUTTON_BG_DIRECTORY = new Color(0, 0, 60);
29 private static final Color BUTTON_BG_DIRECTORY_SELECTED = new Color(0, 0, 100);
30 private static final Color BUTTON_BG_LINK = new Color(60, 60, 0);
32 private static final Color BUTTON_BG_LINK_SELECTED = new Color(100, 100, 0);
33 private static final Color BUTTON_BG_EXECUTABLE_FILE = new Color(60, 0, 0);
35 private static final Color BUTTON_BG_EXECUTABLE_FILE_SELECTED = new Color(100, 0, 0);
36 private static final Color BUTTON_BG_NONEXECUTABLE_FILE = new Color(0, 60, 0);
38 private static final Color BUTTON_BG_NONEXECUTABLE_FILE_SELECTED = new Color(0, 100, 0);
39 private static final Dimension SIZE_BUTTON = new Dimension(200, 30);
40 private final Set<MenuListener> menuListeners = new HashSet<>();
41 private JPanel menuPanel;
42 private JButton selectedButton;
43 private File selectedFile;
45 public Menu(final File directory) {
46 buildContentPanel(directory);
51 * Assign specific colors to:
57 private static Color getFileColor(final File file, final boolean selected) {
58 if (file.isDirectory())
60 return BUTTON_BG_DIRECTORY_SELECTED;
62 return BUTTON_BG_DIRECTORY;
65 if (file.canExecute()) {
67 return BUTTON_BG_EXECUTABLE_FILE_SELECTED;
69 return BUTTON_BG_EXECUTABLE_FILE;
71 return BUTTON_BG_NONEXECUTABLE_FILE_SELECTED;
73 return BUTTON_BG_NONEXECUTABLE_FILE;
76 return BUTTON_BG_LINK_SELECTED;
78 return BUTTON_BG_LINK;
81 public void addMenuListener(final MenuListener menuListener) {
82 menuListeners.add(menuListener);
85 private JButton buildButton(final File file) {
87 if (file.isDirectory())
88 button = new JButton("[ " + file.getName() + " ]");
90 button = new JButton(file.getName());
92 button.setBackground(getFileColor(file, false));
93 button.setForeground(new Color(255, 255, 255));
95 button.setBorder(new EmptyBorder(5, 10, 5, 10));
97 final Menu.ButtonMouseListener mouseListener = new ButtonMouseListener(button, this, file);
98 button.addMouseListener(mouseListener);
100 button.setHorizontalTextPosition(SwingConstants.CENTER);
103 Utils.setComponentSize(button, SIZE_BUTTON);
108 private void buildContentPanel(final File directory) {
109 menuPanel = new JPanel();
111 Utils.setComponentSize(menuPanel, SIZE_MENU_PANEL);
113 final BoxLayout layout = new BoxLayout(menuPanel, BoxLayout.Y_AXIS);
114 menuPanel.setLayout(layout);
115 menuPanel.setBackground(Color.BLACK);
117 final File[] listFiles = directory.listFiles();
119 // Sort files by name
120 Arrays.sort(listFiles, (f1, f2) -> {
122 // directories come before files
123 if (f1.isFile() && f2.isDirectory())
125 if (f2.isFile() && f1.isDirectory())
128 // order by file name
129 return f1.getName().toUpperCase().compareTo(f2.getName().toUpperCase());
132 // add files to the panel
133 for (final File file : listFiles)
134 // ignore hidden files
135 if (!file.getName().startsWith(".")) {
136 menuPanel.add(Box.createVerticalStrut(10));
137 menuPanel.add(buildButton(file));
141 public JPanel getMenuPanel() {
145 private JButton getSelectedButton() {
146 return selectedButton;
149 private File getSelectedFile() {
153 private void menuItemHighlighted(final File chosenFile) {
154 for (final MenuListener menuListener : menuListeners)
155 menuListener.menuItemHighlighted(this, chosenFile);
158 private void menuItemSelected(final File chosenFile) {
159 for (final MenuListener menuListener : menuListeners)
160 menuListener.menuItemSelected(chosenFile);
163 private void menuItemSelectedAlternative(final File chosenFile) {
164 for (final MenuListener menuListener : menuListeners)
165 menuListener.menuItemSelectedAlternative(chosenFile);
168 private void menuItemSelectedAlternative2(final File chosenFile) {
169 for (final MenuListener menuListener : menuListeners)
170 menuListener.menuItemSelectedAlternative2(chosenFile);
173 private void setSelected(final JButton selectedButton, final File selectedFile) {
174 this.selectedButton = selectedButton;
175 this.selectedFile = selectedFile;
178 public static class ButtonMouseListener implements MouseListener {
180 final JButton parentButton;
181 final Menu parentMenu;
184 public ButtonMouseListener(final JButton button, final Menu parentMenu, final File file) {
185 parentButton = button;
186 this.parentMenu = parentMenu;
191 public void mouseClicked(final MouseEvent e) {
194 if (e.getButton() == 1) // left mouse click
195 parentMenu.menuItemSelected(file);
196 if (e.getButton() == 2) // middle mouse click
197 parentMenu.menuItemSelectedAlternative2(file);
198 if (e.getButton() == 3) //right mouse click
199 parentMenu.menuItemSelectedAlternative(file);
200 } catch (final Exception ex) {
201 new ExceptionDialog(ex);
206 public void mouseEntered(final MouseEvent e) {
208 if (parentButton != parentMenu.getSelectedButton()) {
210 if (parentMenu.getSelectedButton() != null)
211 parentMenu.getSelectedButton().setBackground(getFileColor(parentMenu.getSelectedFile(), false));
213 parentMenu.setSelected(parentButton, file);
214 parentButton.setBackground(getFileColor(file, true));
216 parentMenu.menuItemHighlighted(file);
218 } catch (final Exception ex) {
219 new ExceptionDialog(ex);
224 public void mouseExited(final MouseEvent e) {
228 public void mousePressed(final MouseEvent e) {
232 public void mouseReleased(final MouseEvent e) {