第一个Java问题(可能是很多!)。我使用Eclipse和e(fx)clispse插件和Scene Builder 2.0学习Java和JavaFX。我在AnchorPane中构建了一个带有几个按钮的小窗口,一个TableView和一个ImageView。到目前为止一切都很好。
如果我只为所有按钮注册了一个方法(在我的情况下都是两个方法!),我原来的问题是如何识别被选中的按钮。我可以看到系统拥有所有信息(通过为event.getSource()和event.PickResult()执行System.out.println)。但是,在发布这个问题之前,我克服了这些问题,但这又带来了一些问题;
1)对于getSource()问题,我想了解按钮源信息,我希望能够在一行中完成。即event.getSource()。[期望Eclipse为我提供在提案列表中由getSource()返回的Type的方法]。但是,在event.getSource()....之后,方法的提议列表是我认为从对象方法继承的方法。我必须做的是将声明分解如下:
EventObject evo = new EventObject(event.getSource());
Object obj = evo.getSource();
Button btnMirror = (Button)obj;
System.out.println("Button id is:" + btnMirror.getId());
为什么在第一个event.getSource()..之后,getSource()不能再作为提案使用?
我的理解中明显存在差距。毕竟,我在System.out。[方法列表]之后获得的方法列表与System.in。[方法列表]不同。有人可以澄清吗?
2)第二个问题是关于getPickResult()。当使用event.getPickResult()。getIntersectedNode()。getId()时,我得到一个null结果?不能正确我认为打印event.getPickResult()显示它具有我需要的所有信息。然后我尝试了event.getPickResult()。getIntersectedNode()。getParent()。getId(),并且工作正常!啊哈,我想,但唉,太早了。我发现的是,我是否得到一个null结果,按钮id或Anchor Pane id(!)取决于我点击按钮的确切位置。按钮文本中间的Bang产生了一个null结果,稍微偏离中心产生按钮id和按钮的外部区域(但鼠标光标仍然完全在按钮内)产生了AnchorPane id。这对我来说使得PickResult非常不可靠。必须有允许这种情况发生的属性。任何人都可以启发我。
还与问题1有关,event.getPickResult()。getandSoOn ....总是在每个句点之后生成一个正确可用方法的列表。由于getPickResult返回PickResult并且以类似的方式,getSource返回一个EventType,因此很困惑为什么会发生这种情况。
感谢所有见解。
附件是Controller的代码。很多System.out可以看看发生了什么。 Main是FX项目的标准生成代码。如果要完全复制窗口布局,还会生成FXML代码。
控制器代码:
package myapplication;
import java.net.URL;
import java.util.EventObject;
import java.util.ResourceBundle;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.scene.layout.AnchorPane;
public class IrfController implements Initializable {
@FXML private AnchorPane myAnchorPane;
@FXML private Button btnClickMe;
@FXML private Button btnAddRow;
@FXML private TableView<Person> myTV;
@FXML private TableColumn<Person, String> myCol1;
@FXML private TableColumn<Person, String> myCol2;
final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("John","Smith"),
new Person("Adam", "West"));
@FXML protected void btnClick(MouseEvent event) {
/**Get source and get Pick Result both have the info**/
System.out.println( "Event GetSource: " + event.getSource());
System.out.println( "Event PickResult:" + event.getPickResult());
/** the id's of the button **/
System.out.println("Add Row buton id: " + btnAddRow.getId());
System.out.println("Click Me button id: " + btnClickMe.getId());
/**get the Node of the pick result - a direct click returns null **/
System.out.println("Pick Result Node id: " + event.getPickResult().getIntersectedNode().getId());
EventObject evo = new EventObject(event.getSource());
Object obj = evo.getSource();
Button btnMirror = (Button)obj;
System.out.println("Button id is:" + btnMirror.getId());
System.out.println( "Pick Result: " + event.getPickResult().getIntersectedNode().getParent().getId());
PickResult pkr = event.getPickResult();
Node nd = pkr.getIntersectedNode().getParent();
System.out.println("Parent Node id: " + nd.getId());
switch (btnMirror.getId()) {
case "btnClickMe": System.out.println("You selected the Click Me Button"); break;
case "btnAddRow": System.out.println("You selected the Add Row Button"); break;
default: System.out.println("No button registered"); break;
}
System.out.println("Event Type: " + event.getEventType().getName());
}
@FXML
public void onActionFired(ActionEvent event){
System.out.println("In ActionFired - Start");
System.out.println(event.getClass().toGenericString());
System.out.println(event.toString());
System.out.println(event.getEventType().toString());
System.out.println("In ActionFired - End");
}
@FXML protected void clickAnchor(MouseEvent event) {
System.out.println(event.toString());
System.out.println("Hello Click Anchor!");
System.out.println(event.getEventType().toString());
}
和FXML文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="myAnchorPane" onMouseClicked="#clickAnchor" prefHeight="441.0" prefWidth="578.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="myapplication.IrfController">
<children>
<Button fx:id="btnClickMe" layoutX="481.0" layoutY="135.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onMouseClicked="#btnClick" prefHeight="50.0" prefWidth="83.0" text="ClickMe" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="135.0">
<opaqueInsets>
<Insets />
</opaqueInsets>
<effect>
<Glow />
</effect></Button>
<ImageView fitHeight="100.0" fitWidth="143.0" layoutX="35.0" layoutY="22.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="344.0" AnchorPane.topAnchor="22.0">
<image>
<Image url="@../../../../../Users/Ayesha/Pictures/2014-03-06/IMG_0324.JPG" />
</image>
</ImageView>
<TableView fx:id="myTV" layoutX="35.0" layoutY="135.0" prefHeight="264.0" prefWidth="396.0" AnchorPane.bottomAnchor="42.0" AnchorPane.leftAnchor="35.0" AnchorPane.rightAnchor="147.0" AnchorPane.topAnchor="135.0">
<columns>
<TableColumn fx:id="myCol1" prefWidth="75.0" text="First Name" />
<TableColumn fx:id="myCol2" prefWidth="100.0" text="Last Name" />
<TableColumn fx:id="myCol3" prefWidth="140.0" text="Something Else" />
</columns>
</TableView>
<Button fx:id="btnAddRow" layoutX="481.0" layoutY="204.0" mnemonicParsing="false" onMouseClicked="#btnClick" prefHeight="50.0" prefWidth="83.0" text="Add Row" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="204.0" />
</children>
</AnchorPane>
答案 0 :(得分:0)
我不熟悉JavaFX和所有的东西。但是点击听众的小按钮我可以帮到你。这是一个正常的impl。 eventlisteners的模式和一个通用的解决方案。
首先,根据每种小部件都可以发送相同类型的事件,事件的来源必须是对象。 但这不是问题,您是开发人员,并且您知道哪个侦听器已连接到哪个窗口小部件。如果只有一个侦听器正在侦听一个窗口小部件(例如内联),则可以始终忽略源,因为您知道唯一的一个。 当您重复使用一个侦听器(例如,包含小部件的类)时,您必须检查源以确定谁调用了该事件。
最简单的方法是
widgetObject == event.getSource()
所以第一个意图是,将对象与“==”进行比较。但在这种情况下这不是问题,因为event.getSource()与发送事件的widgetObject是同一个实例。因此可以对对象进行比较。
另一方面,如果您的侦听器更复杂或者动画小部件实例是动态的,您可以通过“instanceof”检查对象的类型,然后转换为所需的实现。 在GUI框架中,Normaly任何小部件都有一个setData / getData实现,您可以在其中放置任何您想要的内容。所以线索是:
if (event.getSource() instanceof Button) {
Button eventBtn = (Button) event.getSource();
Enum kindOfButton = (Enum) eventBtn.getData();
switch (kindOfButton) {
case SAVE:
doSave();
break;
...
}
}
通过组合“instanceof”和小部件中的数据poket,您可以根据需要实现复杂的侦听器。动态生成小部件也不是问题,界面保持干净。
注意:上面的代码是伪代码然后是真实代码。例如,枚举应该是Enum impl。你提供;)
希望有所帮助。