2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.javascript.json.JSON;
25 import java.awt.Toolkit;
26 import java.awt.event.MouseEvent;
27 import java.io.BufferedReader;
29 import java.io.FileReader;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.Reader;
35 import java.util.Properties;
37 import javax.swing.SwingUtilities;
39 import org.json.simple.parser.JSONParser;
40 import org.json.simple.parser.ParseException;
43 * System platform information used by Applet and Application
50 private static boolean isJS = /** @j2sNative true || */
53 private static Boolean isNoJSMac = null, isNoJSWin = null, isMac = null,
56 private static Boolean isHeadless = null;
59 * added to group mouse events into Windows and nonWindows (mac, unix, linux)
63 public static boolean isMac()
66 ? (isMac = (System.getProperty("os.name").indexOf("Mac") >= 0))
71 * added to group mouse events into Windows and nonWindows (mac, unix, linux)
75 public static boolean isWin()
78 ? (isWin = (System.getProperty("os.name").indexOf("Win") >= 0))
84 * @return true if HTML5 JavaScript
86 public static boolean isJS()
92 * sorry folks - Macs really are different
94 * BH: disabled for SwingJS -- will need to check key-press issues
96 * @return true if we do things in a special way.
98 public static boolean isAMacAndNotJS()
100 return (isNoJSMac == null ? (isNoJSMac = !isJS && isMac()) : isNoJSMac);
104 * Check if we are on a Microsoft plaform...
106 * @return true if we have to cope with another platform variation
108 public static boolean isWindowsAndNotJS()
110 return (isNoJSWin == null ? (isNoJSWin = !isJS && isWin()) : isNoJSWin);
115 * @return true if we are running in non-interactive no UI mode
117 public static boolean isHeadless()
119 if (isHeadless == null)
121 isHeadless = "true".equals(System.getProperty("java.awt.headless"));
128 * @return nominal maximum command line length for this platform
130 public static int getMaxCommandLineLength()
132 // TODO: determine nominal limits for most platforms.
133 return 2046; // this is the max length for a windows NT system.
137 * escape a string according to the local platform's escape character
140 * @return escaped file
142 public static String escapeString(String file)
144 StringBuffer f = new StringBuffer();
145 int p = 0, lastp = 0;
146 while ((p = file.indexOf('\\', lastp)) > -1)
148 f.append(file.subSequence(lastp, p));
152 f.append(file.substring(lastp));
157 * Answers true if the mouse event has Meta-down (Command key on Mac) or
158 * Ctrl-down (on other o/s). Note this answers _false_ if the Ctrl key is
159 * pressed instead of the Meta/Cmd key on Mac. To test for Ctrl-pressed on
160 * Mac, you can use e.isPopupTrigger().
165 public static boolean isControlDown(MouseEvent e)
167 return isControlDown(e, isMac());
171 * Overloaded version of method (to allow unit testing)
177 protected static boolean isControlDown(MouseEvent e, boolean aMac)
181 return e.isControlDown();
183 // answer false for right mouse button
184 // shortcut key will be META for a Mac
185 return !e.isPopupTrigger()
186 && (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
187 & e.getModifiers()) != 0;
188 // could we use e.isMetaDown() here?
191 // BH: I don't know about that previous method. Here is what SwingJS uses.
192 // Notice the distinction in mouse events. (BUTTON3_MASK == META)
194 // private static boolean isPopupTrigger(int id, int mods, boolean isWin) {
195 // boolean rt = ((mods & InputEvent.BUTTON3_MASK) != 0);
197 // if (id != MouseEvent.MOUSE_RELEASED)
200 //// // Oddly, Windows returns InputEvent.META_DOWN_MASK on release, though
201 //// // BUTTON3_DOWN_MASK for pressed. So here we just accept both.
203 //// actually, we can use XXX_MASK, not XXX_DOWN_MASK and avoid this issue,
205 //// J2S adds the appropriate extended (0x3FC0) and simple (0x3F) modifiers.
209 // // mac, linux, unix
210 // if (id != MouseEvent.MOUSE_PRESSED)
212 // boolean lt = ((mods & InputEvent.BUTTON1_MASK) != 0);
213 // boolean ctrl = ((mods & InputEvent.CTRL_MASK) != 0);
214 // return rt || (ctrl && lt);
220 * Windows (not Mac, Linux, or Unix) and right button to test for the
221 * right-mouse pressed event in Windows that would have opened a menu or a
227 public static boolean isWinRightButton(MouseEvent e)
229 // was !isAMac(), but that is true also for Linux and Unix and JS,
231 return isWin() && SwingUtilities.isRightMouseButton(e);
235 * Windows (not Mac, Linux, or Unix) and middle button -- for mouse wheeling
236 * without pressing the button.
241 public static boolean isWinMiddleButton(MouseEvent e)
243 // was !isAMac(), but that is true also for Linux and Unix and JS
244 return isWin() && SwingUtilities.isMiddleMouseButton(e);
247 public static boolean allowMnemonics()
252 public final static int TIME_RESET = 0;
254 public final static int TIME_MARK = 1;
256 public static final int TIME_SET = 2;
258 public static final int TIME_GET = 3;
260 public static long time, mark, set, duration;
262 public static void timeCheck(String msg, int mode)
264 long t = System.currentTimeMillis();
271 System.err.println("Platform: timer reset\t\t\t" + msg);
277 duration += (t - set);
287 System.err.println("Platform: timer mark\t" + ((t - time) / 1000f)
288 + "\t" + ((t - mark) / 1000f) + "\t" + msg);
299 System.err.println("Platform: timer dur\t" + ((t - time) / 1000f)
300 + "\t" + ((duration) / 1000f) + "\t" + msg);
307 public static void cacheFileData(String path, byte[] data)
316 * swingjs.JSUtil.cacheFileData$S$O(path, data);
321 public static byte[] getFileBytes(File f)
323 return /** @j2sNative f && f._bytes || */
327 public static byte[] getFileAsBytes(String fileStr)
329 // BH 2018 hack for no support for access-origin
330 return /** @j2sNative swingjs.JSUtil.getFileAsBytes$O(fileStr) || */
334 public static String getFileAsString(String data)
336 return /** @j2sNative swingjs.JSUtil.getFileAsString$S(data) || */
340 public static boolean setFileBytes(File f, String urlstring)
346 @SuppressWarnings("unused")
347 byte[] bytes = getFileAsBytes(urlstring);
349 * @j2sNative f._bytes = bytes;
354 public static void addJ2SBinaryType(String ext)
359 * J2S._binaryTypes.push("." + ext + "?");
365 * Encode the URI using JavaScript encodeURIComponent
368 * @return encoded value
370 public static String encodeURI(String value)
373 * @j2sNative value = encodeURIComponent(value);
379 * Open the URL using a simple window call if this is JavaScript
382 * @return true if window has been opened
384 public static boolean openURL(String url)
399 public static String getUniqueAppletID()
401 @SuppressWarnings("unused")
402 ThreadGroup g = Thread.currentThread().getThreadGroup();
404 * @j2sNative return g.html5Applet._uniqueId;
412 * Read the Info block for this applet.
417 * @return unique id for this applet
419 public static void readInfoProperties(String prefix, Properties p)
421 @SuppressWarnings("unused")
422 ThreadGroup g = Thread.currentThread().getThreadGroup();
423 String id = getUniqueAppletID();
424 String key = "", value = "";
426 * @j2sNative var info = g.html5Applet.__Info || {}; for (var key in info) {
427 * if (key.indexOf(prefix) == 0) { value = "" + info[key];
431 "Platform id=" + id + " reading Info." + key + " = " + value);
432 p.put(id + "_" + key, value);
442 public static void setAjaxJSON(URL url)
450 public static Object parseJSON(InputStream response)
451 throws IOException, ParseException
455 return JSON.getJSONReader(response);
458 BufferedReader br = null;
461 br = new BufferedReader(new InputStreamReader(response, "UTF-8"));
462 return parseJSON(br);
470 } catch (IOException e)
478 public static Object parseJSON(String json) throws ParseException
480 return (isJS() ? JSON.parse(json)
481 : new JSONParser().parse(json));
484 public static Object parseJSON(Reader r)
485 throws IOException, ParseException
494 return new JSONParser().parse(r);
496 // Using a file reader is not currently supported in SwingJS JavaScript
498 if (r instanceof FileReader)
500 throw new IOException(
501 "StringJS does not support FileReader parsing for JSON -- but it could...");
503 return JSON.parse(r);