първият въпрос за Java (вероятно от много!). Уча Java и JavaFX с помощта на Eclipse и плъгина e(fx)clispse със Scene Builder 2.0. Създадох малък прозорец с няколко бутона, TableView и ImageView в AnchorPane. Всичко добре досега.
Първоначалният ми въпрос щеше да бъде как да идентифицирам избрания бутон, ако имам само един регистриран метод за всички бутони (и двата в моя случай!). Можех да видя, че системата разполага с цялата информация (като направих System.out.println за event.getSource() и event.PickResult()). Въпреки това, преди да публикувам този въпрос, преодолях проблемите, но това доведе до още няколко въпроса;
1) За проблема с getSource() исках да стигна до информацията за източника на бутона и очаквах да мога да го направя в един ред. т.е. event.getSource().[ очаквам Eclipse да ми даде методи за Типа, върнат от getSource() в списъка с предложения]. Въпреки това, след 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.[method list] е различен от System.in.[method list]. Може ли някой да изясни?
2) Вторият въпрос беше относно getPickResult(). Когато използвах event.getPickResult().getIntersectedNode().getId(), получавах нулев резултат? Не може да е прав, помислих си, че отпечатването на event.getPickResult() показа, че има цялата информация, от която мога да се нуждая. След това опитах event.getPickResult().getIntersectedNode().getParent().getId() и това проработи! Аха, помислих си, но уви, твърде рано. Това, което открих е, че дали съм получил нулев резултат, идентификаторът на бутона или идентификаторът на закотвящия панел (!) зависи от това къде точно върху бутона, който съм щракнал. Ударът в средата на текста на бутона доведе до нулев резултат, леко извън центъра създаде идентификатора на бутона, а външните области на бутона (но с курсор на мишката все още изцяло вътре в бутона) дадоха идентификатора на AnchorPane. Това за мен прави PickResult изключително ненадежден. Трябва да има свойства, които позволяват това да се случи. Може ли някой да ме просветли.
Също свързано с въпрос 1, event.getPickResult().getandSoOn....винаги създава списък с правилните налични методи след всеки период. Объркан съм защо това се случва, защото getPickResult връща PickResult и в подобен дух getSource връща EventType.
Благодаря за всякакви прозрения.
Приложен е код за контролера. Много System.out, за да видите какво се случва. Основният е стандартно генериран код за 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>
onAction
вместоonMouseClicked
за бутон. - person James_D   schedule 19.08.2014EventHandler
, когато използвате различни манипулатори) с превключвател (или еквивалентна последователност отif
/else
конструкции). Това просто като цяло е лоша практика (ще стане грозно, когато имате 200 елемента от менюто) и на теория производителността е по-лоша (макар че във всяко реално приложение няма да забележите разлика). - person James_D   schedule 20.08.2014