私が取り組んでいるプロジェクトでは、いくつかのメソッドをpackageoneに実装して抽象クラスを定義する必要があります。パッケージでは、抽象メソッドの残りの部分は、クラスがインスタンス化されるときに実装されます。その後、インスタンスはJavaFX WebviewでJavascriptコードに公開されます。 (Oracleのオンライン例 - https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx)Javafx WebViewは修飾子 "public"を使用して...のクラスにアクセスできない
私の問題は、packagetwoで実装されているメソッドがJavascript環境から呼び出せないことです。次のエラーが表示されます。
Exception in thread "JavaFX Application Thread" netscape.javascript.JSException: java.lang.IllegalAccessException: Class sun.reflect.misc.Trampoline can not access a member of class packagetwo.MainWindow$1 with modifiers "public"
at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
at com.sun.webkit.WebPage.executeScript(WebPage.java:1439)
at javafx.scene.web.WebEngine.executeScript(WebEngine.java:982)
at packagetwo.MainWindow.makeUpCall(MainWindow.java:130)
at packagetwo.MainWindow.access$000(MainWindow.java:22)
at packagetwo.MainWindow$2.changed(MainWindow.java:83)
at packagetwo.MainWindow$2.changed(MainWindow.java:68)
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.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:1260)
at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1371)
at javafx.scene.web.WebEngine$LoadWorker.access$1200(WebEngine.java:1253)
at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1240)
at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2400)
at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2244)
at com.sun.webkit.network.URLLoader.twkDidFinishLoading(Native Method)
at com.sun.webkit.network.URLLoader.notifyDidFinishLoading(URLLoader.java:838)
at com.sun.webkit.network.URLLoader.lambda$didFinishLoading$96(URLLoader.java:829)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalAccessException: Class sun.reflect.misc.Trampoline can not access a member of class packagetwo.MainWindow$1 with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Method.invoke(Method.java:491)
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:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at com.sun.webkit.Utilities.lambda$fwkInvokeWithContext$55(Utilities.java:94)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.webkit.Utilities.fwkInvokeWithContext(Utilities.java:94)
... 29 more
packageoneで実装されている呼び出しメソッドは正常ですが。 Javaから両方のメソッドセットを呼び出すこともうまくいきます。以下は私のクラスとJavascriptコールです。
Packagetwo
package packagetwo;
import packageone.Calls;
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
public class MainWindow implements Initializable
{
@FXML
private BorderPane mainWindow;
@FXML
private WebView mainWebView;
@FXML
private AnchorPane mainWebViewLayout;
@Override
public void initialize(URL url, ResourceBundle rb)
{
Calls jc = new Calls()
{
@Override
public void aMethod1()
{
System.out.printf("Calls: Abstract Method Impl 1 Called.\n");
}
};
// Add new load complete listener.
ChangeListener<Worker.State> onLoadComplete = buildOnLoadCompleteListener(mainWebView, jc);
mainWebView.getEngine()
.getLoadWorker()
.stateProperty()
.addListener(
onLoadComplete);
// Attempt to load the current web package.
mainWebView.getEngine().load("file:///" + new File("index.html").getAbsolutePath());
}
private ChangeListener<Worker.State> buildOnLoadCompleteListener(
WebView webview, Calls javaUpCalls)
{
return new ChangeListener<Worker.State>()
{
@Override
public void changed(
ObservableValue<? extends Worker.State> ov,
Worker.State lastState, Worker.State currentState)
{
if (currentState == Worker.State.SUCCEEDED)
{
// Hook up Java up calls in the Javascript environment.
JSObject jsEnvironment = (JSObject) webview.getEngine().executeScript("window");
jsEnvironment.setMember("JavaUpCalls", javaUpCalls);
makeUpCall(webview);
}
}
};
}
private void makeUpCall(WebView webview)
{
String setUpUpCall =
"function makeAnUpCall()" +
"{" +
"if(typeof JavaUpCalls !== \"undefined\")" +
"{" +
"JavaUpCalls.method2();" +
"JavaUpCalls.aMethod1();" +
"}" +
"}";
webview.getEngine().executeScript(setUpUpCall);
webview.getEngine().executeScript("makeAnUpCall()");
}
}
Packageone
package packageone;
public abstract class Calls()
{
public abstract void aMethod1();
public void method2()
{
System.out.printf("Calls: Method 1 Called.\n");
}
}
Index.htmlとは、ページがロードされたと言う<p>
タグを正常にロードだけで、標準のHTMLページです。
Javascript環境がpackagetwoに実装されたメソッドを呼び出せない理由は何ですか?
EDIT:
私はオンラインビットを調査し、このStackOverflowの質問が見つかりました:
を私はpackagetwo法にsetAccessible(true)を呼び出して(そこに記載されているソリューションを試みましたインスタンス)、エラーはスローされました。
また、packageoneからJavascriptメソッドを初期化して呼び出すことも試みましたが、まだエラーが発生しています。
今や意味をなさない。答えてくれてありがとう。 – MrJman006