$darkmode
DENOPTIM
GUI.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2020 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.gui;
20
21import java.awt.Color;
22import java.awt.Dimension;
23import java.awt.event.WindowAdapter;
24import java.awt.event.WindowEvent;
25import java.awt.event.WindowFocusListener;
26import java.io.File;
27import java.util.concurrent.TimeUnit;
28import java.util.logging.Logger;
29
30import javax.swing.JFrame;
31import javax.swing.JOptionPane;
32import javax.swing.JPanel;
33import javax.swing.ToolTipManager;
34import javax.swing.UIManager;
35
36import org.apache.commons.cli.CommandLine;
37
38import denoptim.files.FileFormat;
39import denoptim.files.FileUtils;
40import denoptim.task.StaticTaskManager;
41import denoptim.utils.Randomizer;
42
56public class GUI implements Runnable
57{
61 private JFrame frame;
62
66 private JPanel framePane;
67
72
76 private int width = 960;
77
81 private int height = 690;
82
86 private CommandLine cmd;
87
91 static final String GUILOGGER = "GUILogger";
92
96 static final Randomizer PRNG = new Randomizer(System.currentTimeMillis());
97
98//------------------------------------------------------------------------------
99
103 public GUI(CommandLine cmd)
104 {
105 this.cmd = cmd;
106 ToolTipManager.sharedInstance().setDismissDelay(6000);
107 ToolTipManager.sharedInstance().setInitialDelay(1000);
108 ToolTipManager.sharedInstance().setReshowDelay(100);
109 Logger.getLogger(GUILOGGER);
110 }
111
112//------------------------------------------------------------------------------
113
117 public void run()
118 {
119 frame = new JFrame("DENOPTIM - GUI");
120 frame.setPreferredSize(new Dimension(width, height));
121 frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
122 frame.addWindowListener(new WindowAdapter() {
123 @Override
124 public void windowClosing(WindowEvent windowEvent) {
126 }
127 });
128
129 //Frame pane contains all (tools bar and the rest)
130 framePane = (JPanel) frame.getContentPane();
131
132 //Menu bar
133 MainToolBar menuBar = new MainToolBar();
134 frame.setJMenuBar(menuBar);
135
136 //Main panel is a deck of cards that contains all but the tool bar
137 mainPanel = new GUIMainPanel(menuBar);
138 framePane.add(mainPanel);
140 menuBar.setRefToMasterGUI(this);
141
143
144 // Hack to debug com.apple.laf.AquaLookAndFeel. Such LAF when combined
145 // with "dark mode" (i.e., the system appearance where all windows have
146 // dark colors) tries to change the appearance, but in not fully
147 // self-consistent. For example, it sets the background
148 // of the MenuBar components to a dark color, but does not adapt the
149 // foreground color accordingly.
150 // Thus, the menu is unreadable because painter using
151 // dark grey font on black-ish background. To overcome this problem we
152 // set the foreground to a lighter shade of grey.
153 if (UIManager.getLookAndFeel().getClass().getName().equals(
154 "com.apple.laf.AquaLookAndFeel") && weRunOnMacDarkMode())
155 {
156 UIManager.getLookAndFeelDefaults().put("MenuBar.foreground",
157 new Color(150,150,150));
158 UIManager.getLookAndFeelDefaults().put("TableHeader.background",
159 new Color(200,200,200));
160 }
161
162 try {
163 this.frame.pack();
164 this.frame.setLocationRelativeTo(null);
165 this.frame.setVisible(true);
166 this.frame.addWindowFocusListener(new WindowFocusListener() {
167
168 @Override
169 public void windowLostFocus(WindowEvent e) {
171 }
172
173 @Override
174 public void windowGainedFocus(WindowEvent e) {
176 }
177 });
178
179 if (cmd!=null && cmd.getArgList().size()>0)
180 {
181 for (String arg : cmd.getArgList())
182 {
183 File file = new File(arg);
185 try
186 {
187 format = FileUtils.detectFileFormat(file);
188 } catch (Throwable t)
189 {
190 // We have ensured the format is recognized in the Main
191 }
192 menuBar.openFile(file, format);
193 }
194 }
195 } catch (Exception e) {
196 e.printStackTrace();
197 }
198 }
199
200//------------------------------------------------------------------------------
201
205 private static boolean weRunOnMacDarkMode()
206 {
207 try
208 {
209 final Process p = Runtime.getRuntime().exec(new String[]
210 {"defaults", "read", "-g", "AppleInterfaceStyle"});
211 p.waitFor(100, TimeUnit.MILLISECONDS);
212 return p.exitValue() == 0;
213 }
214 catch (Throwable ex)
215 {
216 return false;
217 }
218 }
219
220//------------------------------------------------------------------------------
221
225 protected void closeIfAllSaved()
226 {
228 {
229 String[] options = new String[]{"Yes, stop running tasks","No"};
230 int res = JOptionPane.showOptionDialog(frame,
231 "<html>Found running tasks.<br>Do you want to "
232 + "stop all running tasks?</html>",
233 "Stop all?",
234 JOptionPane.YES_NO_OPTION,
235 JOptionPane.QUESTION_MESSAGE,
236 UIManager.getIcon("OptionPane.warningIcon"),
237 options,
238 options[1]);
239 if (res == 1 || res == -1)
240 {
241 return;
242 }
243 }
244
245 try {
247 } catch (Exception e) {
248 e.printStackTrace();
249 String[] options = new String[]{"Yes, stop and close"};
250 JOptionPane.showOptionDialog(frame,
251 "<html>Problems killing the running tasks.<br>Will force "
252 + "quit all tasks and shutdown.</html>",
253 "Force quit",
254 JOptionPane.DEFAULT_OPTION,
255 JOptionPane.QUESTION_MESSAGE,
256 UIManager.getIcon("OptionPane.warningIcon"),
257 options,
258 options[0]);
259 Runtime.getRuntime().halt(0);
260 }
261
263 {
264 /*
265 //FOR SOME REASON USING HTML HERE PREVENTS DISPLAYING THE TEXT
266 "<html>Found unsaved changes.<br>Are you sure you want to "
267 + "close this window?</html>",
268 */
269 String[] options = new String[]{"Yes","No"};
270 int res = JOptionPane.showOptionDialog(frame,
271 "Found unsaved changes. "
272 + "Are you sure you want to close this window?",
273 "Close Window?",
274 JOptionPane.DEFAULT_OPTION,
275 JOptionPane.QUESTION_MESSAGE,
276 UIManager.getIcon("OptionPane.warningIcon"),
277 options,
278 options[1]);
279 if (res == 0)
280 {
281 Runtime.getRuntime().halt(0);
282 }
283 }
284 else
285 {
286 //System.exit(0); //this will wait for synch locks to be released,
287 // but here we want to really stop the JVM and kill all threads.
288 Runtime.getRuntime().halt(0);
289 }
290 }
291
292//------------------------------------------------------------------------------
293
294}
static FileFormat detectFileFormat(File inFile)
Inspects a file/folder and tries to detect if there is one of the data sources that is recognized by ...
Definition: FileUtils.java:399
Graphical User Interface of the DENOPTIM package.
Definition: GUI.java:57
CommandLine cmd
Command line options.
Definition: GUI.java:86
static final Randomizer PRNG
Random number generator specific for the GUI, and any of its tasks.
Definition: GUI.java:96
GUIMainPanel mainPanel
Panel including all but tool bar.
Definition: GUI.java:71
void closeIfAllSaved()
Close GUI is there are no unsaved changes to the open components.
Definition: GUI.java:225
void run()
Launch the application.
Definition: GUI.java:117
int width
Default width.
Definition: GUI.java:76
JPanel framePane
Panel including tool bar.
Definition: GUI.java:66
static final String GUILOGGER
Name of logger for the GUI.
Definition: GUI.java:91
GUI(CommandLine cmd)
Constructor that specifies parameters.
Definition: GUI.java:103
int height
Default height.
Definition: GUI.java:81
static boolean weRunOnMacDarkMode()
Checks if we are in dark mode.
Definition: GUI.java:205
JFrame frame
GUI window frame.
Definition: GUI.java:61
The main panel is a deck of cards that occupies all the GUI frame.
boolean hasUnsavedChanges()
Checks is any card has unsaved changes.
Component add(Component comp)
Add a component and a reference to such component in the main tool bar.
The home panel contains shortcuts buttons to perform the most common tasks.
Definition: HomePanel.java:53
Main tool bar of the DENOPTIM graphical user interface.
void openFile(File file, FileFormat fileFormat)
Process a file that has a recognized file format and loads a suitable GUI card to visualize the file ...
void setRefToMasterGUI(GUI gui)
Sets the reference to master GUI.
void setRefToMainPanel(GUIMainPanel mainPanel)
Sets the reference to main panel for creating functionality of menu items depending on main panel ide...
Manager for tasks submitted by the GUI.
static JProgressBar queueStatusBar
Reference to progress bar in GUI.
Tool to generate random numbers and random decisions.
Definition: Randomizer.java:35
File formats identified by DENOPTIM.
Definition: FileFormat.java:32