1

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.

3
  • I edited your question title based upon what I thought the question was asking, if the edit is incorrect, please re-edit it to make to clarify the specific question intent. Commented Aug 6, 2014 at 18:31
  • Downvoter, please give your reason. thanks. Commented Aug 6, 2014 at 19:30
  • I downvoted because the question was unclear to me as to whether it was referring to lookups in the JavaFX scene graph or HTML DOM model. From the conflicting answers to the question, it also confused others. I tried to clarify the question by editing the title, but I am not unsure if my edit truly reflects the intent of what the question was asking. If the edited question title is accurate, I am unclear if you wish a Java only solution or a solution which uses JavaScript, for example looking up a CSS class using jQuery. Commented Aug 6, 2014 at 19:42

4 Answers 4

1

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!

Sign up to request clarification or add additional context in comments.

Comments

1

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!

1 Comment

-1 Because this is not what the question title asks for. Looks like the title was, at one time, ambiguous - making this answer a reasonable one during that ambiguity. Now that the title is specific, this answer is unrelated. :( I don't have enough rep to actually downvote, but I tried!
0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.