Salim
Salim

Reputation: 199

How to make Javafx remember form values?

What I need is for a user to be able to click any tag on a web page. Once they click the tag a new button appears in a GridPane. When I click the new button in the GridPane a small dialog box appears with all the attributes that exist in the tag.

Step by step:

  1. I load google.com
  2. I click the link at the foot "About"
  3. A button appears in the GridPane
  4. I click the button that just appeared
  5. A smaller window appears that lists:

    About
    xpath: id("fsl")/A[3] //this is a the xpath of the click which I use js
    class: _Gs
    href: //www.google.com/intl/en/about.html?fg=1
    
  6. Then I close this smaller window and click Business

  7. A new button appears in the gridpane
  8. I click the button that just appeared
  9. A smaller window appears with new list of attributes:
    Business
    xpath: id("fsl")/A[2]
    class: _Gs
    href: //www.google.com/services/?fg=1
    

That's the idea.

The issue is when I click Business, the xpath of About is replaced with the xpath for Business. When I open the content of About in the gridpane everything is still the same except xpath is now id("fsl")/A[2] instead of id("fsl")/A[3]

It all starts in the worker

    engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>(){
        public void changed(ObservableValue ov, State oldState, State newState){

            if(newState == javafx.concurrent.Worker.State.SUCCEEDED){

                //attach listener to all tags "*" 
                EventListener listener = new EventListener(){

                    public void handleEvent(org.w3c.dom.events.Event evt) {
                        addNewInstruction(evt);
                        setXPath();

                    }
                };

                setListenerByTagNames(listener, "a");
            }
        }
    });

//xpath method

private void setXPath(){
    JSObject hrefWindow = (JSObject) engine.executeScript("window");
    hrefWindow.setMember("java", bridge);
    engine.executeScript("var links = document.getElementsByTagName(\"*\");"+
                        "for (var i = 0; i < links.length; i++) {"+
                        "links[i].addEventListener(\"click\", function(){"+
                            "document.onclick = function(event) {" +
                                "if (event===undefined) event= window.event;" +                     
                                "var target= 'target' in event? event.target : event.srcElement; " +

                                "var root= document.compatMode==='CSS1Compat'? document.documentElement : document.body;" +
                                "var mxy= [event.clientX+root.scrollLeft, event.clientY+root.scrollTop];" +

                                "var path= getPathTo(target);" +
                                "var txy= getPageXY(target);" +
                                "java.log(path);" +
                            "}" +
                        "});"+
                    "}"+

                        "function getPathTo(element) {" +
                            "if (element.id!=='')" +
                                "return 'id(\"'+element.id+'\")';" +
                            "if (element===document.body)" +
                                "return element.tagName;" +

                            "var ix= 0;" +
                            "var siblings= element.parentNode.childNodes;" +
                            "for (var i= 0; i<siblings.length; i++) {" +
                                "var sibling= siblings[i];" +
                                "if (sibling===element)" +
                                    "return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';" +
                                "if (sibling.nodeType===1 && sibling.tagName===element.tagName)" +
                                    "ix++;" +
                            "}" +
                        "}" +

                        "function getPageXY(element) {" +
                            "var x= 0, y= 0;" +
                            "while (element) {" +
                                "x+= element.offsetLeft;" +
                                "y+= element.offsetTop;" +
                                "element= element.offsetParent;" +
                            "}" +
                            "return [x, y];" +
                        "}");
}

The javabridge class

public class JavaBridge extends Amz
{
    public String text = "EMPTY STRING";

    public void log(String text){
        this.text = text;
    }

}

The instruction method

private void addNewInstruction(org.w3c.dom.events.Event evt){
    String htmlTagName = ((Element)evt.getTarget()).getTagName();

    if(instructionIncrementCol == 10){
        instructionIncrementRow++;
        instructionIncrementCol= 0;
    }

    final Button button = new Button(htmlTagName);
    button.setOnAction(
            new EventHandler<ActionEvent>() {

                public void handle(ActionEvent event) {
                    //Grid Specs
                    GridPane primaryGrid = new GridPane();
                    Element element = ((Element)evt.getTarget());
                    primaryGrid.setVgap(4);
                    primaryGrid.setPadding(new Insets(5, 5, 5, 5));

                    TitledPane titleSlider = new TitledPane();
                    titleSlider.setText("Instructions");
                    titleSlider.setContent(primaryGrid);    
                    titleSlider.setContent(primaryGrid);

                    final GridPane secondGrid = new GridPane();
                    secondGrid.setVgap(4);
                    secondGrid.setPadding(new Insets(20));
                    secondGrid.setPrefHeight(100);

                    ScrollPane sp = new ScrollPane(secondGrid);
                    sp.setHbarPolicy(ScrollBarPolicy.ALWAYS);
                    sp.setMaxHeight(400);
                    primaryGrid.add(sp, 0, 1);
                    GridPane.setHgrow(sp, Priority.ALWAYS);
                    GridPane.setVgrow(sp, Priority.ALWAYS);

                    //Form
                    int rowOnePos = 0;
                    int rowTwoPos = 1;
                    int rowThreePos = 2;
                    int loopRowPos = 3;

                    String tagType = element.getTagName();
                    if(tagType.equals("INPUT")){
                        createInputInstructionObject(secondGrid,rowOnePos, element);
                    }else{
                        Button click = new Button("Click");
                        secondGrid.add(click, 0, rowOnePos);
                        click.setOnAction(new EventHandler<ActionEvent>(){
                            public void handle(ActionEvent e){
                                sql.insertRow("click", element.getAttribute("href"));
                                //writeToFile("click,"+((Element)evt.getTarget()).getAttribute("href"));
                            }
                        });
                        Text textLabel = new Text("Text");
                        TextField textContentValue = new TextField(element.getTextContent());
                        Button grabDataText = new Button("Grab");
                        textContentValue.setPrefWidth(300);
                        secondGrid.add(textLabel, 0, rowTwoPos);
                        secondGrid.add(textContentValue, 1, rowTwoPos);
                        secondGrid.add(grabDataText, 2, rowTwoPos);
                        textContentValue.setPrefWidth(300);
                    }

                    //xpath
                    Text xpathLabel = new Text("XPath");
                    final String stay = bridge.text+" ";
                    TextField xpathValue = new TextField(stay);
                    Button grabDataxpath = new Button("Grab");

                    secondGrid.add(xpathLabel, 0, rowThreePos);
                    secondGrid.add(xpathValue, 1, rowThreePos);
                    secondGrid.add(grabDataxpath, 2, rowThreePos);

                    //all attributes for this tag
                    NamedNodeMap attributes = element.getAttributes();

                    for(int i = 0; i < attributes.getLength(); i++){
                        //create row for each attribute
                        createInstructionObject(attributes, i, secondGrid, loopRowPos);
                    }

                    final Stage dialog = new Stage();
                    Scene dialogScene = new Scene(primaryGrid, 500, 500);
                    dialog.setScene(dialogScene);                       
                    dialog.show();
                }
             });


    instructionSecondaryGrid.add(button,instructionIncrementCol,instructionIncrementRow);
    instructionIncrementCol++;

}

Upvotes: 2

Views: 861

Answers (2)

Salim
Salim

Reputation: 199

Finally found a solution. I ended up using javascript to insert the XPath into SQLite DB, upon loading page, and assigning a new attribute to the tag with the ID of the XPath in the DB.

like so:

<a href="site.com" mycustomAttr="1">Click Me</a>

    //the JS
    var anchors = document.getElementsByTagName("a"); 
    for (var i = 0; i < anchors.length; i++) {
         java.insertIntoDB(getXPathID(anchors[i]));
         anchors[i].setAttribute("mycustomAttr", java.getMaxId());
     }

Upvotes: 2

James_D
James_D

Reputation: 209553

Your code isn't very understandable - lots of references are declared and not used, or not declared and then referred to (the latter means it won't compile) - but as far as I can understand it you just need to create the dialog once for each button, instead of recreating it every time the button is pressed:

private void addNewPane(org.w3c.dom.events.Event evt){
    final Button button = new Button(htmlTagName);

    final Stage dialog = new Stage();
    GridPane primaryGrid = new GridPane();
    Element element = ((Element)evt.getTarget());
    primaryGrid.setVgap(4);
    primaryGrid.setPadding(new Insets(5, 5, 5, 5));

    TitledPane gridTitlePane = new TitledPane();
    GridPane secondGrid = new GridPane();
    secondGrid.setVgap(4);
    secondGrid.setPadding(new Insets(20));
    secondGrid.setPrefHeight(100);
    ScrollPane sp = new ScrollPane(secondGrid);
    sp.setHbarPolicy(ScrollBarPolicy.ALWAYS);
    sp.setMaxHeight(400);

    int rowThreePos = 2;

    //text content of data                      
    secondGrid.add(new Text("XPath"), 0, rowThreePos);
    secondGrid.add(new TextField(holdXPath), 1, rowThreePos);
    secondGrid.add(new Button("Grab"), 2, rowThreePos);

    primaryGrid.add(sp, 0, 1);
    GridPane.setHgrow(sp, Priority.ALWAYS);
    GridPane.setVgrow(sp, Priority.ALWAYS);
    gridTitlePane.setText("Forms");
    gridTitlePane.setContent(primaryGrid);  

    gridTitlePane.setContent(primaryGrid);
    Scene dialogScene = new Scene(primaryGrid, 500, 500);
    dialog.setScene(dialogScene);

    button.setOnAction(
            new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    dialog.show();  
                }
             });
    SecondaryGrid.add(button,IncrementCol,IncrementRow);
    IncrementCol++;
}

Upvotes: 2

Related Questions