java - 使用 FXML 将鼠标单击操作事件添加到 JavaFX 中的标签

标签 java model-view-controller javafx fxml label

我在 JavaFX 中制作了 Risk 的一个版本。现在,为了显示游戏数据,我正在使用标签网格来显示有关每个领土的信息。目前,我想在标签上设置鼠标单击监听器,这样我就可以通过单击它们来测试游戏功能,直到制作出完整的游戏板。除非我尝试在 FXML 文档中添加监听器,否则会出现错误。现在,我在 Controller 中声明标签,将它们添加到集合中,以便我可以使用循环来绑定(bind)每个标签的 textProperty,然后将每个标签添加到网格中。然后在 FXML 中我为每个定义 onMouseClicked。 这是 Controller 代码:

@FXML
private GridPane tGrid = new GridPane();

@FXML Label label1 = new Label();
@FXML Label label2 = new Label();
@FXML Label label3 = new Label();
@FXML Label label4 = new Label();
@FXML Label label5 = new Label();
@FXML Label label6 = new Label();
@FXML Label label7 = new Label();
@FXML Label label8 = new Label();
@FXML Label label9 = new Label();
@FXML Label label10 = new Label();
@FXML Label label11 = new Label();
@FXML Label label12 = new Label();
@FXML Label label13 = new Label();
@FXML Label label14 = new Label();
@FXML Label label15 = new Label();
@FXML Label label16 = new Label();
@FXML Label label17 = new Label();
@FXML Label label18 = new Label();
@FXML Label label19 = new Label();
@FXML Label label20 = new Label();
@FXML Label label21 = new Label();
@FXML Label label22 = new Label();
@FXML Label label23 = new Label();
@FXML Label label24 = new Label();
@FXML Label label25 = new Label();
@FXML Label label26 = new Label();
@FXML Label label27 = new Label();
@FXML Label label28 = new Label();
@FXML Label label29 = new Label();
@FXML Label label30 = new Label();
@FXML Label label31 = new Label();
@FXML Label label32 = new Label();
@FXML Label label33 = new Label();
@FXML Label label34 = new Label();
@FXML Label label35 = new Label();
@FXML Label label36 = new Label();
@FXML Label label37 = new Label();
@FXML Label label38 = new Label();
@FXML Label label39 = new Label();
@FXML Label label40 = new Label();
@FXML Label label41 = new Label();
@FXML Label label42 = new Label();


@Override
public void initialize(URL url, ResourceBundle rb) {
    anchor.setLeftAnchor(tGrid, 10.0);
    anchor.setRightAnchor(pGrid, 10.0);
    tGrid.setVisible(false);
    pGrid.setVisible(false);
    labels.add(label1);
    labels.add(label2);
    labels.add(label3);
    labels.add(label4);
    labels.add(label5);
    labels.add(label6);
    labels.add(label7);
    labels.add(label8);
    labels.add(label9);
    labels.add(label10);
    labels.add(label11);
    labels.add(label12);
    labels.add(label13);
    labels.add(label14);
    labels.add(label15);
    labels.add(label16);
    labels.add(label17);
    labels.add(label18);
    labels.add(label19);
    labels.add(label20);
    labels.add(label21);
    labels.add(label22);
    labels.add(label23);
    labels.add(label24);
    labels.add(label25);
    labels.add(label26);
    labels.add(label27);
    labels.add(label28);
    labels.add(label29);
    labels.add(label30);
    labels.add(label31);
    labels.add(label32);
    labels.add(label33);
    labels.add(label34);
    labels.add(label35);
    labels.add(label36);
    labels.add(label37);
    labels.add(label38);
    labels.add(label39);
    labels.add(label40);
    labels.add(label41);
    labels.add(label42);
    int k = 0;
    for(int i = 0; i < 6; i++) {
        for(int j = 0; j < game.getContinent(i).getTerritoryNum(); j++) {
            labels.get(k).textProperty().bind(game.getContinent(i).getTerritory(j).getProperty());
            k += 1;
        }//for
    }//for
    for (int i = 0; i < 42; i++) {
        tGrid.add(labels.get(i), 0, i);
    }//for

这是 FXML 代码(除了所有标签都有 onMouseClicked):

         <Label fx:id="label1"onMouseClicked="#labelAction" />
            <Label fx:id="label2"/>
            <Label fx:id="label3"/>
            <Label fx:id="label4"/>
            <Label fx:id="label5"/>
            <Label fx:id="label6"/>
            <Label fx:id="label7"/>
            <Label fx:id="label8"/>
            <Label fx:id="label9"/>
            <Label fx:id="label10"/>
            <Label fx:id="label11"/>
            <Label fx:id="label12"/>
            <Label fx:id="label13"/>
            <Label fx:id="label14"/>
            <Label fx:id="label15"/>
            <Label fx:id="label16"/>
            <Label fx:id="label17"/>
            <Label fx:id="label18"/>
            <Label fx:id="label19"/>
            <Label fx:id="label20"/>
            <Label fx:id="label21"/>
            <Label fx:id="label22"/>
            <Label fx:id="label23"/>
            <Label fx:id="label24"/>
            <Label fx:id="label25"/>
            <Label fx:id="label26"/>
            <Label fx:id="label27"/>
            <Label fx:id="label28"/>
            <Label fx:id="label29"/>
            <Label fx:id="label30"/>
            <Label fx:id="label31"/>
            <Label fx:id="label32"/>
            <Label fx:id="label33"/>
            <Label fx:id="label34"/>
            <Label fx:id="label35"/>
            <Label fx:id="label36"/>
            <Label fx:id="label37"/>
            <Label fx:id="label38"/>
            <Label fx:id="label39"/>
            <Label fx:id="label40"/>
            <Label fx:id="label41"/>
            <Label fx:id="label42"/>

这是错误:

Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl$$Lambda$50/1343441044.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException:
file:/C:/Users/Brent/Documents/NetBeansProjects/RiskFXML/dist/run1282679996/RiskFXML.jar!/riskfxml/FXML.fxml:34

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2605)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2547)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
at riskfxml.RiskFXML.start(RiskFXML.java:22)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$53/1527242123.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$45/355629945.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1753953479.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1915503092.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/1963387170.run(Unknown Source)
... 1 more
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[34,38]
Message: Element type "Label" must be followed by either attribute specifications, ">" or "/>".
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:601)
at javax.xml.stream.util.StreamReaderDelegate.next(StreamReaderDelegate.java:88)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2517)
... 22 more
Exception running application riskfxml.RiskFXML
Java Result: 1

更新

好的,所以我删除了所有 '= new Label()',从而消除了错误,因为问题是通过在 fxml 和 Controller 中定义它们我试图添加重复的元素。现在我的问题是如何将标签添加到 fxml 中的网格 Pane 中,其位置与我在示例 Controller 代码底部的循环中执行此操作时的位置相同?是否有一种方法可以将它们添加到 fxml 中的数组列表中,然后添加它?我知道我能做到

<Label fx:id="label1" onMouseClicked="#labelAction" GridPane.columnIndex="0" GridPane.rowIndex="0" />

对于每个标签,但必须有一种比手动键入和放置每个标签更好的方法,对吧?它们只需要在同一列中增加行数即可。

最佳答案

我遇到了与您类似的问题并以不同的方式解决了它: 在标签顶部创建一个按钮并将不透明度指定为 0。

这样,按钮不会向最终用户显示,但当他们单击标签时,底层按钮会执行操作。由于它是一个标准的 javafx 按钮,因此您只需使用 onAction="#yourAction"即可,甚至无需更改 Label 中的任何内容。

希望这有帮助!

关于java - 使用 FXML 将鼠标单击操作事件添加到 JavaFX 中的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29379351/

相关文章:

java - 如何集成不同编程语言编写的程序?

c# - MVC : Binding CKEditor textarea value to the model

javafx - 在 JavaFX 中使用 Unicode 字符

javascript - Javafx:如何定位场景的元素

c# - 系统.InvalidOperationException : The model item passed into the dictionary is of type

java - ReadOnlyStringWrapper.ReadOnlyPropertyImpl 从哪里获取 ChangeListener 的 oldValue ?

java - 使用 Java 实现字符串数组 "is in"方法的有效方法

java - 在java中从APNG中提取png文件

java - 使用 Java 线程创建一个简单的队列

model-view-controller - Grails无法添加对象属性。如何实现?