I am able to get an element by Id like this in JavaFX.
Element nameField = engine.getDocument().getElementById( "name" );
How do I do the same given element's classname?
Thanks.
You can access any component by using: the lookUp method.
For Example:
Button has class: specialClazz
and your mainPane is a StackPane: rootPane
So you just do:
rootPane.lookUp(".specialClazz"); // .-selector!
For an ID:
rootPane.lookUp("#specialID"); // #-selector!
I came across this and saw there wasn't much for answers. The way I found way to work with dom classes is not great but it gets the job done.
To add a class on a Node you obtained, use the setAttribute()
method. Be careful to maintain any classes that might already exist on the Node
.
Document doc = engine.getDocument();
if (doc != null){
Element elem = doc.getElementById('someID');
String classNames = elem.getAttribute("class");
classNames += " someClass"; //note the whitespace!
elem.setAttribute("class", classNames);
}
Then, if you wish to search the DOM by class you can execute javascript to do so using the executeScript
on the WebEngine
. The return type depends on what you're asking the script to do.
Small note: disabling javascript via engine.setJavaScriptEnabled(false);
does not prohibit use of the engine.executeScript()
method.
HTMLCollection result = (HTMLCollection)engine.executeScript("document.getElementsByClassName('someClass')");
However inefficient, I did this to determine what I would be getting back from executeScript()
before writing any further code:
Object result = engine.executeScript("document.getElementsByClassName('someClass')");
System.out.println(result.getClass().getName());
Like I said it isn't great, but you can write some wrapper functions to make it easier to work with. Hope this helps!
I'd use javax.xml.xpath
. See XPath Tutorial - Example 6 : Values of attributes can be used as selection criteria.
Note also that there is not necessarily a (single) element's class name . id
is unique in a Document whereas class
is not. So it should rather read elements' class name . (Subtle, but important. :-) In other words: there is not necessarily just one Element returned when searching for a given class.
The above answer:
"HTMLCollection result = (HTMLCollection)engine.executeScript("document.getElementsByClassName('someClass')");"
is bad. Because executeScript return's JSObject but not HTMLCollection; it cannot be casted.
The corrent is below java9 modular code sample (java14 has var): and you should add vm options to project:
--add-exports javafx.web/com.sun.webkit.dom=atools
var doc = webEngine.getDocument();
if (doc instanceof HTMLDocument htmlDocument) { //actually htmlDoc is HTMLDocumentImpl but java9 have to reflect
try {
Method method = null;
var clazz = htmlDocument.getClass();
method = clazz.getSuperclass().getMethod("getElementsByClassName", String.class);
HTMLCollection collection = (HTMLCollection) method.invoke(htmlDocument,"button");
//if collection not only 1
//you should special the document more deeply
for (int i = 0; i < collection.getLength(); i++) {
var btn = collection.item(i);
//actual is HTMLButtonElementImpl
//HTMLButtonElement htmlButtonElement = (HTMLButtonElement) btn;
var method1 = btn.getClass().getMethod("click");
method1.invoke(btn);
Log.d("");
break;
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
If you are not using java9+ modular, these reflects can replace with HTMLButtonElementImpl,HTMLDocumentImpl.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.