Repository: kotcrab/vis-ui
Issue: Crash on opening plugins folder from settings dialog

Editor crashs at the time when the 'Open Plugin Folder' button has been clicked in Settings dialog.

I got this error message with stacktrace:

```
java.lang.IllegalArgumentException: The file: home/stquote/Downloads/VisUIEditor doesn't exist.
    at java.awt.Desktop.checkFileValidation(Desktop.java:210)
    at java.awt.Desktop.open(Desktop.java:270)
    at com.kotcrab.vis.editor.util.FileUtils.browse(FileUtils.java:74)
    at com.kotcrab.vis.editor.module.editor.PluginLoaderModule$PluginSettingsModule.lambda$buildTable$163(PluginLoaderModule.java:235)
    at com.kotcrab.vis.editor.module.editor.PluginLoaderModule$PluginSettingsModule$$Lambda$55/1845515247.changed(Unknown Source)
    at com.kotcrab.vis.editor.util.gdx.VisChangeListener.changed(VisChangeListener.java:35)
    at com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.handle(ChangeListener.java:28)
    at com.badlogic.gdx.scenes.scene2d.Actor.notify(Actor.java:181)
    at com.badlogic.gdx.scenes.scene2d.Actor.fire(Actor.java:146)
    at com.badlogic.gdx.scenes.scene2d.ui.Button.setChecked(Button.java:123)
    at com.badlogic.gdx.scenes.scene2d.ui.Button$1.clicked(Button.java:91)
    at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:89)
    at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:58)
    at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:348)
    at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:306)
    at com.badlogic.gdx.backends.lwjgl.LwjglCanvas$3.run(LwjglCanvas.java:234)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
[22:51][Fatal] java.lang.RuntimeException: No OpenGL context found in the current thread.
    at org.lwjgl.opengl.GLContext.getCapabilities(GLContext.java:124)
    at org.lwjgl.opengl.GL11.glDeleteTextures(GL11.java:732)
    at com.badlogic.gdx.backends.lwjgl.LwjglGL20.glDeleteTexture(LwjglGL20.java:248)
    at com.badlogic.gdx.graphics.GLTexture.delete(GLTexture.java:170)
    at com.badlogic.gdx.graphics.Texture.dispose(Texture.java:194)
    at com.kotcrab.vis.ui.widget.color.ColorPicker.dispose(ColorPicker.java:468)
    at com.kotcrab.vis.editor.module.editor.ColorPickerModule.dispose(ColorPickerModule.java:35)
    at com.kotcrab.vis.editor.module.ModuleContainer.dispose(ModuleContainer.java:191)
    at com.kotcrab.vis.editor.Editor.dispose(Editor.java:250)
    at com.badlogic.gdx.backends.lwjgl.LwjglCanvas$4.run(LwjglCanvas.java:309)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
```

In my case I have a path to plugins folder ''/home/lalala/vis/viseditor/Editor/target/plugins/", but in `PluginLoaderModule` class at [this line](https://github.com/kotcrab/VisEditor/blob/master/Editor/src/com/kotcrab/vis/editor/module/editor/PluginLoaderModule.java#L235) used `PLUGINS_FOLDER_PATH` constant with  "home/lalala/vis/viseditor/Editor/target/plugins/" value which which has not start with slash symbol.

It seems like a typo in [JarUtils.java](https://github.com/kotcrab/VisEditor/blob/master/Editor/src/com/kotcrab/vis/editor/util/JarUtils.java#L33) because `PluginLoaderModule` class uses this util method for initialize constant. I think substring method should have 0 in first argument. Like this: `path = path.substring(0, path.lastIndexOf('/'));`

I'm using Linux Mint, but I think this is not working in windows too.

So if I'm right, and all agree with me, I can make pull request for this :)


Changed files:
Editor/src/com/kotcrab/vis/editor/util/JarUtils.java

diff --git a/Editor/src/com/kotcrab/vis/editor/util/JarUtils.java b/Editor/src/com/kotcrab/vis/editor/util/JarUtils.java
index 57e5160b..bd576cfa 100644
--- a/Editor/src/com/kotcrab/vis/editor/util/JarUtils.java
+++ b/Editor/src/com/kotcrab/vis/editor/util/JarUtils.java
@@ -16,6 +16,7 @@
 
 package com.kotcrab.vis.editor.util;
 
+import com.kotcrab.vis.ui.util.OsUtils;
 import java.io.File;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
@@ -30,7 +31,12 @@ public class JarUtils {
 		try {
 			URL url = caller.getProtectionDomain().getCodeSource().getLocation();
 			String path = URLDecoder.decode(url.getFile(), "UTF-8");
-			path = path.substring(1, path.lastIndexOf('/')); // remove jar name from path
+
+			// remove jar name from path
+			if (OsUtils.isWindows())
+				path = path.substring(1, path.lastIndexOf('/')); // cut first '/' for Windows
+			else
+				path = path.substring(0, path.lastIndexOf('/'));
 
 			if (path.endsWith("target/classes")) //launched from ide, remove classes from path
 				path = path.substring(0, path.length() - "/classes".length());