【问题标题】:Adding mouse click action events to labels in JavaFX with FXML使用 FXML 将鼠标单击动作事件添加到 JavaFX 中的标签
【发布时间】:2015-03-31 22:00:42
【问题描述】:

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

@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 和控制器中定义它们。现在我的问题是如何将标签添加到 fxml 中的网格窗格中的位置与我在示例控制器代码底部的那个循环中执行它时的位置相同?是一种将它们添加到 fxml 中的数组列表并添加它的方法吗?我知道我可以做到

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

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

【问题讨论】:

  • 你能识别出 FXML 文件中的相关行(第 34 行)吗?这不是错误的原因,但您不应该初始化@FXML-injected 字段(即删除语句的所有= new Label() 部分和= new GridPane()。(另外,不会像这样在 Java 代码中更好,带有循环,而不是在 FXML 中?)
  • &lt;Label fx:id="label1"onMouseClicked="#labelAction" /&gt;中应该有空格
  • 你听说过Scene Builder吗?尝试使用它来操作您的 fxml。它是您可以拖放组件并为您创建 FXML 代码的工具。

标签: java model-view-controller javafx fxml labels


【解决方案1】:

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

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

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多