リビジョン | 181 (tree) |
---|---|
日時 | 2019-10-16 10:05:41 |
作者 | hirukawa_ryo |
* fx-util 0.2.0
全面的に作り直しました。fx-util 0.1.1 との互換性はありません。
@@ -14,7 +14,7 @@ | ||
14 | 14 | set APP_HOME=%DIRNAME% |
15 | 15 | |
16 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
17 | -set DEFAULT_JVM_OPTS= | |
17 | +set DEFAULT_JVM_OPTS="-Xmx64m" | |
18 | 18 | |
19 | 19 | @rem Find java.exe |
20 | 20 | if defined JAVA_HOME goto findJavaFromJavaHome |
@@ -0,0 +1,268 @@ | ||
1 | +package net.osdn.util.javafx.concurrent; | |
2 | + | |
3 | +import javafx.concurrent.Task; | |
4 | + | |
5 | +import java.util.concurrent.Callable; | |
6 | +import java.util.concurrent.Executor; | |
7 | +import java.util.concurrent.Executors; | |
8 | +import java.util.concurrent.ThreadFactory; | |
9 | + | |
10 | +public class Async<V> implements AsyncRunnable, AsyncCallable<V> { | |
11 | + | |
12 | + /** | |
13 | + * タスク完了時の状態 | |
14 | + * | |
15 | + */ | |
16 | + public enum State { | |
17 | + /** | |
18 | + * タスクがキャンセルされたことを示します。 | |
19 | + */ | |
20 | + CANCELLED, | |
21 | + /** | |
22 | + * タスクが正常に終了したことを示します。 | |
23 | + */ | |
24 | + SUCCEEDED, | |
25 | + /** | |
26 | + * 通常は予期しない条件が発生したことによって、タスクが失敗したことを示します。 | |
27 | + */ | |
28 | + FAILED | |
29 | + } | |
30 | + | |
31 | + private static ThreadFactory defaultThreadFactory; | |
32 | + | |
33 | + /** | |
34 | + * 新規スレッドの作成に使用するデフォルトのスレッド・ファクトリーを返します。 | |
35 | + * | |
36 | + * @return スレッド・ファクトリー | |
37 | + */ | |
38 | + public static ThreadFactory getDefaultThreadFactory() { | |
39 | + return defaultThreadFactory; | |
40 | + } | |
41 | + | |
42 | + /** | |
43 | + * 新規スレッドの作成に使用するデフォルトのスレッド・ファクトリーを設定します。 | |
44 | + * スレッド・ファクトリーを設定するとエグゼキューターは再初期化されます。 | |
45 | + * | |
46 | + * @param factory スレッド・ファクトリー | |
47 | + */ | |
48 | + public static void setDefaultThreadFactory(ThreadFactory factory) { | |
49 | + defaultThreadFactory = factory; | |
50 | + executor = null; | |
51 | + } | |
52 | + | |
53 | + private static Executor executor; | |
54 | + | |
55 | + /** | |
56 | + * タスクを実行するエグゼキューターを返します。 | |
57 | + * エグゼキューターが明示的に設定されていない場合、 | |
58 | + * 既定のスレッド・ファクトリーを使ってスレッドをプールして再利用するエグゼキューターが新たに作成されます。 | |
59 | + * 既定のスレッド・ファクトリーが設定されていない場合、デーモン・スレッドを作成するファクトリーが使われます。 | |
60 | + * | |
61 | + * @return エグゼキューター | |
62 | + */ | |
63 | + public static Executor getExecutor() { | |
64 | + if(executor == null) { | |
65 | + ThreadFactory factory = getDefaultThreadFactory(); | |
66 | + if(factory == null) { | |
67 | + factory = new ThreadFactory() { | |
68 | + @Override | |
69 | + public Thread newThread(Runnable r) { | |
70 | + Thread thread = new Thread(r); | |
71 | + thread.setDaemon(true); | |
72 | + return thread; | |
73 | + } | |
74 | + }; | |
75 | + } | |
76 | + executor = Executors.newCachedThreadPool(factory); | |
77 | + } | |
78 | + return executor; | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * タスクを実行するエグゼキューターを設定します。 | |
83 | + * エグゼキューターが明示的に設定された場合、既定のスレッド・ファクトリーは使われません。 | |
84 | + * | |
85 | + * @param executor エグゼキューター | |
86 | + */ | |
87 | + public static void setExecutor(Executor executor) { | |
88 | + Async.executor = executor; | |
89 | + } | |
90 | + | |
91 | + /** | |
92 | + * 指定したRunnableを非同期で実行します。 | |
93 | + * | |
94 | + * @param runnable 非同期で実行する処理 | |
95 | + * @return メソッドチェーンでハンドラーを設定できます。 | |
96 | + */ | |
97 | + public static AsyncRunnable execute(Runnable runnable) { | |
98 | + Async<Void> async = new Async<Void>(() -> { | |
99 | + runnable.run(); | |
100 | + return null; | |
101 | + }); | |
102 | + getExecutor().execute(async.task); | |
103 | + return async; | |
104 | + } | |
105 | + | |
106 | + /** | |
107 | + * 指定したCallableを非同期で実行します。 | |
108 | + * 処理は値を返すことができます。 | |
109 | + * | |
110 | + * @param callable 非同期で実行する処理 | |
111 | + * @param <V> 処理の戻り値の型 | |
112 | + * @return メソッドチェーンでハンドラーを設定できます。 | |
113 | + */ | |
114 | + public static <V> AsyncCallable<V> execute(Callable<V> callable) { | |
115 | + Async<V> async = new Async<V>(callable); | |
116 | + getExecutor().execute(async.task); | |
117 | + return async; | |
118 | + } | |
119 | + | |
120 | + private Task<V> task; | |
121 | + private Cancel cancel; | |
122 | + private AsyncRunnable.Success runnableSuccess; | |
123 | + private AsyncCallable.Success<V> callableSuccess; | |
124 | + private Failure failure; | |
125 | + private Complete complete; | |
126 | + | |
127 | + private Async(Callable<V> callable) { | |
128 | + task = new Task<V>() { | |
129 | + @Override | |
130 | + protected V call() throws Exception { | |
131 | + return callable.call(); | |
132 | + } | |
133 | + | |
134 | + @Override | |
135 | + protected void cancelled() { | |
136 | + Async.this.cancelled(); | |
137 | + } | |
138 | + | |
139 | + @Override | |
140 | + protected void succeeded() { | |
141 | + Async.this.succeeded(); | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + protected void failed() { | |
146 | + Async.this.failed(); | |
147 | + } | |
148 | + }; | |
149 | + } | |
150 | + | |
151 | + protected void cancelled() { | |
152 | + if(cancel != null) { | |
153 | + cancel.onCancelled(); | |
154 | + } | |
155 | + if(complete != null) { | |
156 | + complete.onCompleted(Async.State.CANCELLED); | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + protected void succeeded() { | |
161 | + if(runnableSuccess != null) { | |
162 | + runnableSuccess.onSucceeded(); | |
163 | + } else if(callableSuccess != null) { | |
164 | + callableSuccess.onSucceeded(task.getValue()); | |
165 | + } | |
166 | + if(complete != null) { | |
167 | + complete.onCompleted(Async.State.SUCCEEDED); | |
168 | + } | |
169 | + } | |
170 | + | |
171 | + protected void failed() { | |
172 | + if(failure != null) { | |
173 | + failure.onFailed(task.getException()); | |
174 | + } | |
175 | + if(complete != null) { | |
176 | + complete.onCompleted(Async.State.FAILED); | |
177 | + } | |
178 | + } | |
179 | + | |
180 | + /** | |
181 | + * タスクを返します。 | |
182 | + * | |
183 | + * @return タスク | |
184 | + */ | |
185 | + public Task<V> getTask() { | |
186 | + return this.task; | |
187 | + } | |
188 | + | |
189 | + /** | |
190 | + * タスクがキャンセルされたときに実行されるハンドラーを設定します。 | |
191 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
192 | + * | |
193 | + * @param callback タスクがキャンセルされたときに呼び出されるハンドラー | |
194 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
195 | + */ | |
196 | + public Async<V> onCancelled(Cancel callback) { | |
197 | + this.cancel = callback; | |
198 | + return this; | |
199 | + } | |
200 | + | |
201 | + /** | |
202 | + * タスクが正常に終了したときに呼び出されるハンドラーを設定します。 | |
203 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
204 | + * | |
205 | + * @param callback タスクが正常に終了したときに呼び出されるハンドラー | |
206 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
207 | + */ | |
208 | + public Async<V> onSucceeded(AsyncRunnable.Success callback) { | |
209 | + this.callableSuccess = null; | |
210 | + this.runnableSuccess = callback; | |
211 | + return this; | |
212 | + } | |
213 | + | |
214 | + /** | |
215 | + * タスクが正常に終了したときに呼び出されるハンドラーを設定します。 | |
216 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
217 | + * | |
218 | + * @param callback タスクが正常に終了したときに呼び出されるハンドラー | |
219 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
220 | + */ | |
221 | + public Async<V> onSucceeded(AsyncCallable.Success<V> callback) { | |
222 | + this.runnableSuccess = null; | |
223 | + this.callableSuccess = callback; | |
224 | + return this; | |
225 | + } | |
226 | + | |
227 | + /** | |
228 | + * 例外がスローされてタスクが失敗したときに呼び出されるハンドラーを設定します。 | |
229 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
230 | + * | |
231 | + * @param callback タスクが失敗したときに呼び出されるハンドラー | |
232 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
233 | + */ | |
234 | + public Async<V> onFailed(Failure callback) { | |
235 | + this.failure = callback; | |
236 | + return this; | |
237 | + } | |
238 | + | |
239 | + /** | |
240 | + * タスクが完了したときに呼び出されるハンドラーを設定します。 | |
241 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
242 | + * | |
243 | + * タスクがキャンセルされた場合、タスクが正常に終了した場合、タスクが失敗した場合、 | |
244 | + * いずれの場合でも、最期にこのハンドラーが呼び出されます。 | |
245 | + * | |
246 | + * @param callback タスクが完了したときに呼び出されるハンドラー | |
247 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
248 | + */ | |
249 | + public Async<V> onCompleted(Complete callback) { | |
250 | + this.complete = callback; | |
251 | + return this; | |
252 | + } | |
253 | + | |
254 | + @FunctionalInterface | |
255 | + public interface Cancel { | |
256 | + void onCancelled(); | |
257 | + } | |
258 | + | |
259 | + @FunctionalInterface | |
260 | + public interface Failure { | |
261 | + void onFailed(Throwable exception); | |
262 | + } | |
263 | + | |
264 | + @FunctionalInterface | |
265 | + public interface Complete { | |
266 | + void onCompleted(State state); | |
267 | + } | |
268 | +} |
@@ -0,0 +1,47 @@ | ||
1 | +package net.osdn.util.javafx.concurrent; | |
2 | + | |
3 | +public interface AsyncCallable<V> { | |
4 | + /** | |
5 | + * タスクがキャンセルされたときに実行されるハンドラーを設定します。 | |
6 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
7 | + * | |
8 | + * @param callback タスクがキャンセルされたときに呼び出されるハンドラー | |
9 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
10 | + */ | |
11 | + AsyncCallable<V> onCancelled(Async.Cancel callback); | |
12 | + | |
13 | + /** | |
14 | + * タスクが正常に終了したときに呼び出されるハンドラーを設定します。 | |
15 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
16 | + * | |
17 | + * @param callback タスクが正常に終了したときに呼び出されるハンドラー | |
18 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
19 | + */ | |
20 | + AsyncCallable<V> onSucceeded(Success<V> callback); | |
21 | + | |
22 | + /** | |
23 | + * 例外がスローされてタスクが失敗したときに呼び出されるハンドラーを設定します。 | |
24 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
25 | + * | |
26 | + * @param callback タスクが失敗したときに呼び出されるハンドラー | |
27 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
28 | + */ | |
29 | + AsyncCallable<V> onFailed(Async.Failure callback); | |
30 | + | |
31 | + /** | |
32 | + * タスクが完了したときに呼び出されるハンドラーを設定します。 | |
33 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
34 | + * | |
35 | + * タスクがキャンセルされた場合、タスクが正常に終了した場合、タスクが失敗した場合、 | |
36 | + * いずれの場合でも、最期にこのハンドラーが呼び出されます。 | |
37 | + * | |
38 | + * @param callback タスクが完了したときに呼び出されるハンドラー | |
39 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
40 | + */ | |
41 | + AsyncCallable<V> onCompleted(Async.Complete callback); | |
42 | + | |
43 | + @FunctionalInterface | |
44 | + public interface Success<T> { | |
45 | + void onSucceeded(T result); | |
46 | + } | |
47 | +} |
@@ -0,0 +1,49 @@ | ||
1 | +package net.osdn.util.javafx.concurrent; | |
2 | + | |
3 | +import javafx.concurrent.Task; | |
4 | + | |
5 | +public interface AsyncRunnable { | |
6 | + /** | |
7 | + * タスクがキャンセルされたときに実行されるハンドラーを設定します。 | |
8 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
9 | + * | |
10 | + * @param callback タスクがキャンセルされたときに呼び出されるハンドラー | |
11 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
12 | + */ | |
13 | + AsyncRunnable onCancelled(Async.Cancel callback); | |
14 | + | |
15 | + /** | |
16 | + * タスクが正常に終了したときに呼び出されるハンドラーを設定します。 | |
17 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
18 | + * | |
19 | + * @param callback タスクが正常に終了したときに呼び出されるハンドラー | |
20 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
21 | + */ | |
22 | + AsyncRunnable onSucceeded(Success callback); | |
23 | + | |
24 | + /** | |
25 | + * 例外がスローされてタスクが失敗したときに呼び出されるハンドラーを設定します。 | |
26 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
27 | + * | |
28 | + * @param callback タスクが失敗したときに呼び出されるハンドラー | |
29 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
30 | + */ | |
31 | + AsyncRunnable onFailed(Async.Failure callback); | |
32 | + | |
33 | + /** | |
34 | + * タスクが完了したときに呼び出されるハンドラーを設定します。 | |
35 | + * ハンドラーはJavaFXアプリケーションスレッドで呼び出されます。 | |
36 | + * | |
37 | + * タスクがキャンセルされた場合、タスクが正常に終了した場合、タスクが失敗した場合、 | |
38 | + * いずれの場合でも、最期にこのハンドラーが呼び出されます。 | |
39 | + * | |
40 | + * @param callback タスクが完了したときに呼び出されるハンドラー | |
41 | + * @return メソッドチェーンで他のハンドラーの設定を続けられます。 | |
42 | + */ | |
43 | + AsyncRunnable onCompleted(Async.Complete callback); | |
44 | + | |
45 | + @FunctionalInterface | |
46 | + public interface Success { | |
47 | + void onSucceeded(); | |
48 | + } | |
49 | +} |
@@ -0,0 +1,30 @@ | ||
1 | +package net.osdn.util.javafx.event; | |
2 | + | |
3 | +import javafx.event.Event; | |
4 | +import javafx.event.EventHandler; | |
5 | + | |
6 | +@FunctionalInterface | |
7 | +public interface Silent<T extends Event> { | |
8 | + void handle(T event) throws Exception; | |
9 | + | |
10 | + static <T extends Event> EventHandler<T> wrap(Silent<T> handler) { | |
11 | + return event -> { | |
12 | + try { | |
13 | + handler.handle(event); | |
14 | + } catch (Exception e) { | |
15 | + Thread.UncaughtExceptionHandler ueh = Thread.currentThread().getUncaughtExceptionHandler(); | |
16 | + if(ueh != null) { | |
17 | + ueh.uncaughtException(Thread.currentThread(), e); | |
18 | + return; | |
19 | + } | |
20 | + throw new Silent.WrappedException(e); | |
21 | + } | |
22 | + }; | |
23 | + } | |
24 | + | |
25 | + class WrappedException extends RuntimeException { | |
26 | + public WrappedException(Exception cause) { | |
27 | + super(cause); | |
28 | + } | |
29 | + } | |
30 | +} |
@@ -0,0 +1,38 @@ | ||
1 | +package net.osdn.util.javafx.scene.input; | |
2 | + | |
3 | +import javafx.scene.input.KeyCombination; | |
4 | +import javafx.scene.input.KeyEvent; | |
5 | + | |
6 | +public class KeyCombinations extends KeyCombination { | |
7 | + | |
8 | + private Object obj = new Object(); | |
9 | + private KeyCombination[] keyCombinations; | |
10 | + | |
11 | + public KeyCombinations(KeyCombination... keyCombinations) { | |
12 | + this.keyCombinations = keyCombinations; | |
13 | + } | |
14 | + | |
15 | + @Override | |
16 | + public boolean match(KeyEvent event) { | |
17 | + if(keyCombinations == null) { | |
18 | + return false; | |
19 | + } | |
20 | + for(KeyCombination keyCombination : keyCombinations) { | |
21 | + boolean match = keyCombination.match(event); | |
22 | + if(match) { | |
23 | + return true; | |
24 | + } | |
25 | + } | |
26 | + return false; | |
27 | + } | |
28 | + | |
29 | + @Override | |
30 | + public int hashCode() { | |
31 | + return obj.hashCode(); | |
32 | + } | |
33 | + | |
34 | + @Override | |
35 | + public boolean equals(Object obj) { | |
36 | + return (obj == this); | |
37 | + } | |
38 | +} |