Java Engineer
- Language
- Java
- Kotlin
- Ruby
- Framework
- Spring
- Quarkus
- Ruby on Rails
- 2017- pixiv
- 2021- DeNA
- email [email protected]
- Twitter @orekyuu
Javaビーム工房
Java Engineer
Plugin連携のために実装以外からもServiceを登録できるようにする
JavatterAPIではLookupを使ってインターフェイスに紐付けされた実装の取得や注入をしているが、Serviceとして提供するためのインターフェイスかを調べる方法がない。
関係無いインターフェイスでLookupしないようにするために@serviceアノテーションを作成する。
Lookup時にServiceではないクラスを指定された時LookupExceptionをスローする
JavadocへServiceであることを明記する
設定から以下の表示方法を選択できるようにする
name
@ screenname
@ screenname / name
name / @ screenname
バージョン情報ウィンドウを開いて、適当なところをクリックしてフォーカスを外す
Mac yosemite
Java8 update 45
以下の機能が必要
ブラウザでツイートを開く
ツイートをコピー
お気に入り&RT
ブロック
バージョン情報の背景を作成
RT、お気に入り、リプライなどのボタンを画像に変更
例外などの状況がわからないのでログをファイルに吐き出すようにする
logs/error.log info.logのように保存するのがよさげ
お気に入り・RT・フォロー・リスト追加の通知を行う
アカウントの追加と削除を行えるようにする
Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: com/sun/javafx/Utils
at org.controlsfx.tools.Platform.getCurrentPlatform(Platform.java:65)
at org.controlsfx.tools.Platform.(Platform.java:41)
at org.controlsfx.control.ButtonBar$3.(ButtonBar.java:369)
at org.controlsfx.control.ButtonBar.(ButtonBar.java:369)
at org.controlsfx.control.ButtonBar.(ButtonBar.java:355)
at org.controlsfx.control.action.ActionUtils.createButtonBar(ActionUtils.java:429)
at impl.org.controlsfx.skin.NotificationBar.updatePane(NotificationBar.java:164)
at impl.org.controlsfx.skin.NotificationBar.(NotificationBar.java:160)
at org.controlsfx.control.Notifications$NotificationPopupHandler$1.(Notifications.java:332)
at org.controlsfx.control.Notifications$NotificationPopupHandler.show(Notifications.java:332)
at org.controlsfx.control.Notifications$NotificationPopupHandler.show(Notifications.java:317)
at org.controlsfx.control.Notifications.show(Notifications.java:263)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.sun.javafx.Utils
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 19 more
タイムラインのテキストに含まれるURLをハイパーリンクにする
Exception in thread "JavaFX Application Thread" java.lang.StringIndexOutOfBoundsException: String index out of range: -22
at java.lang.String.substring(String.java:1955)
at net.orekyuu.javatter.core.control.TweetText.addTextEntity(TweetText.java:124)
at net.orekyuu.javatter.core.control.TweetText.updateText(TweetText.java:112)
at net.orekyuu.javatter.core.control.TweetText.lambda$tweetProperty$29(TweetText.java:143)
at net.orekyuu.javatter.core.control.TweetText$$Lambda$319/2002011287.changed(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at net.orekyuu.javatter.core.control.TweetText.setTweet(TweetText.java:150)
at net.orekyuu.javatter.core.control.TweetCellController.onChange(TweetCellController.java:68)
at net.orekyuu.javatter.core.control.TweetCellController$$Lambda$315/1659528110.changed(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.access$000(ObjectPropertyBase.java:51)
at javafx.beans.property.ObjectPropertyBase$Listener.invalidated(ObjectPropertyBase.java:233)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.beans.property.ObjectProperty.setValue(ObjectProperty.java:69)
at net.orekyuu.javatter.core.control.TweetCell.updateItem(TweetCell.java:38)
at net.orekyuu.javatter.core.control.TweetCell.updateItem(TweetCell.java:15)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)
at javafx.scene.control.ListCell.lambda$new$163(ListCell.java:167)
at javafx.scene.control.ListCell$$Lambda$310/1990104953.onChanged(Unknown Source)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at net.orekyuu.javatter.core.column.HomeTimeLineColumn.lambda$onStatus$6(HomeTimeLineColumn.java:82)
at net.orekyuu.javatter.core.column.HomeTimeLineColumn$$Lambda$307/798283172.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$50/1495074952.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$49/1692488255.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/314821582.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
今はfollow(User)とfollowAsync(User)のように2つメソッドを用意しているが、CompletableFuture follow(User)のようにすることでシンプルにできる。
削除することは出来ないので現在のメソッドを非推奨にしてこれを追加するのが良い。
指定されたAPIバージョン以下のjarファイルは読み込まないようにする必要がある
Min-API-Version: 1.0.0
のような形式で指定する
必須項目なので、これが指定されていない場合はプラグインとして認識しない。
TODOコメントがいくつか残っているので、その対応を行う
Javadocが書かれていないAPIのクラスがあるので記述する
実行時に例外が出て起動しない
データをプラグインごとに保存できるようにするAPI
Serialize可能なクラスを保存できるようにする
下のような形が良い?
@ Inject
PluginDataStorage storage;
storage.find(PLUGIN_ID, KEY);
storage.save(PLUGIN_ID, KEY, DATA);
storage.delete(PLUGIN_ID, KEY);
呼び出されるタイミングの変更
OnInit: DIの設定が終わった直後
OnPostInit: アカウントの設定が終了し、ウィンドウが表示された後
RT元アイコンの表示とテキストをRT元のものを使うように変更
ダイレクトメッセージなどがまだ出来てないので作る
フォロー/アンフォローボタン
相互フォロー状態表示
ずっと貯めこんでしまうのでソフト参照に置き換える
アス比を保ちつつモニタの大きさに収まるようにウィンドウの大きさをリサイズ
javafx.fxml.LoadException: xxx/layout/about.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2605)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2583)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2413)
at net.orekyuu.javatter.core.controller.CurrentController.openAbout(CurrentController.java:226)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1767)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$341(ContextMenuContent.java:1358)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer$$Lambda$351/731396389.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3758)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$304/2129332258.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:927)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$38/1780450367.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: net.orekyuu.javatter.api.service.ServiceException: net.orekyuu.javatter.api.service.EnvironmentService
at net.orekyuu.javatter.core.JavaBeamStudio$1.lookup(JavaBeamStudio.java:139)
at net.orekyuu.javatter.api.util.lookup.Lookup.lookup(Lookup.java:44)
at net.orekyuu.javatter.core.controller.AboutController.initialize(AboutController.java:24)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
... 59 more
テキストエリアへD&Dで画像を設定する
プラグインごとにメニューバーにアクションをまとめるようにする。
ショートカットからもアクションを実行できるように、設定でショートカットを変更可能にする。
お気に入りタブ
フォロータブ
フォロワータブ
ツイートタブ
通知にはテキスト、タイトル、画像、音、色、タイプ、クリック時のアクションを指定できる。
多分ビルダーを使ってやるのが良い
強参照になるので、リスナを削除するメソッドの追加とColumnやTabのインターフェイスにonCloseのような後処理用メソッドが必要になる。
普通にメソッドを追加するとこれまでのコードがコンパイルエラーになるため、defaultでメソッドを追加する
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.