All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dorkbox.util.swt.Swt Maven / Gradle / Ivy

/*
 * Copyright 2016 dorkbox, llc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dorkbox.util.swt;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;

import dorkbox.os.OS;

/**
 * Utility methods for SWT. SWT is always available for compiling, so it is not necessary to use reflection to compile it.
 * 

* SWT system tray types are GtkStatusIcon trays (so we don't want to use them) */ public class Swt { public final static boolean isLoaded; public final static boolean isGtk3; private static final int version; private static final Display currentDisplay; private static final Thread currentDisplayThread; static { // There is a silly amount of redirection, simply because we have to be able to access SWT, but only if it's in use. // Since this class is the place other code interacts with, we can use SWT stuff if necessary without loading/linking // the SWT classes by accident boolean isSwtLoadable_ = isLoadable(); version = SWT.getVersion(); isLoaded = isSwtLoadable_; isGtk3 = isSwtLoadable_ && isGtk3(); // we MUST save this on init, otherwise it is "null" when methods are run from the swing EDT. currentDisplay = org.eclipse.swt.widgets.Display.getCurrent(); currentDisplayThread = currentDisplay.getThread(); } /** * This uses reflection to check if SWT is loadable and if certain classes are available. * @return true if SWT is loadable */ static boolean isLoadable() { Class swtErrorClass = AccessController.doPrivileged(new PrivilegedAction>() { @Override public Class run() { try { return Class.forName("org.eclipse.swt.SWTError", true, ClassLoader.getSystemClassLoader()); } catch (Exception ignored) { } try { return Class.forName("org.eclipse.swt.SWTError", true, Thread.currentThread().getContextClassLoader()); } catch (Exception ignored) { } return null; } }); if (null != swtErrorClass) { try { return org.eclipse.swt.SWT.isLoadable(); } catch (Exception ignored) { } } return false; } /** * This is only necessary for linux. * * @return true if SWT is GTK3. False if SWT is GTK2. If for some reason we DO NOT KNOW, then we return false (GTK2). */ static boolean isGtk3() { if (!OS.isLinux()) { return false; } final String SWT_INTERNAL_CLASS = "org.eclipse.swt.internal.gtk.OS"; Class osClass = AccessController.doPrivileged(new PrivilegedAction>() { @Override public Class run() { try { return Class.forName(SWT_INTERNAL_CLASS, true, ClassLoader.getSystemClassLoader()); } catch (Exception ignored) { } try { return Class.forName(SWT_INTERNAL_CLASS, true, Thread.currentThread().getContextClassLoader()); } catch (Exception ignored) { } return null; } }); if (osClass == null) { return false; } final Class clazz = osClass; Method method = AccessController.doPrivileged(new PrivilegedAction() { @Override public Method run() { try { return clazz.getMethod("gtk_major_version"); } catch (Exception e) { return null; } } }); if (method == null) { return false; } int version = 0; try { version = ((Number)method.invoke(osClass)).intValue(); } catch (Exception ignored) { // this method doesn't exist. } return version == 3; } public static class SwtOverride { static void onShutdown(final Display currentDisplay, final Runnable runnable) { // currentDisplay.getShells() must only be called inside the event thread! org.eclipse.swt.widgets.Shell shell = currentDisplay.getShells()[0]; shell.addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() { @Override public void handleEvent(final org.eclipse.swt.widgets.Event event) { runnable.run(); } }); } } public static int getVersion() { return version; } public static void dispatch(final Runnable runnable) { currentDisplay.syncExec(runnable); } public static boolean isEventThread() { return Thread.currentThread() == currentDisplayThread; } public static void onShutdown(final Runnable runnable) { // currentDisplay.getShells() must only be called inside the event thread! if (isEventThread()) { SwtOverride.onShutdown(currentDisplay, runnable); } else { dispatch(new Runnable() { @Override public void run() { SwtOverride.onShutdown(currentDisplay, runnable); } }); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy