我需要的是让用户能够点击网页上的任何标签。点击代码后,GridPane
会显示一个新按钮。当我单击GridPane
中的新按钮时,会出现一个包含标签中所有属性的小对话框。
一步一步:
出现一个较小的窗口,列出:
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
然后我关闭这个较小的窗口并单击Business
Business xpath: id("fsl")/A[2] class: _Gs href: //www.google.com/services/?fg=1
这个想法。
问题是当我点击商家时,关于的xpath
会被商家的xpath
所取代。当我在gridpane中打开About的内容时,除了xpath现在id("fsl")/A[2]
而不是id("fsl")/A[3]
一切都从工人开始
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方法
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];" +
"}");
}
javabridge类
public class JavaBridge extends Amz
{
public String text = "EMPTY STRING";
public void log(String text){
this.text = text;
}
}
指令方法
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++;
}
答案 0 :(得分:2)
你的代码不是很容易理解 - 许多引用被声明并且没有被使用,或者没有被声明然后被引用(后者意味着它不会被编译) - 但据我所知它你只需要为每个按钮创建一次对话框,而不是每次按下按钮时重新创建它:
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++;
}
答案 1 :(得分:2)
终于找到了解决方案。我最终使用javascript在加载页面时将XPath插入到SQLite DB中,并在数据库中使用XPath的ID为标记分配新属性。
像这样:<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());
}