多个 FXML 变量到 1 个控制器句柄

Posted

技术标签:

【中文标题】多个 FXML 变量到 1 个控制器句柄【英文标题】:Multiple FXML variables to 1 controller handle 【发布时间】:2016-03-01 04:34:01 【问题描述】:

如何制作适用于每个按钮的句柄,这样我就不必为每个按钮制作几乎相同的句柄?

所以我有一个包含 9 个联系人的 FXML 文件,每个联系人如下所示:

<Button fx:id="id1" mnemonicParsing="false" onAction="#handleContactEmailButtonAction" prefHeight="60.0" prefWidth="380.0" style="-fx-background-color: white;">
    <graphic>
        <VBox style="-fx-background-color: white; -fx-border-color: white;">
            <children>
                <Label prefHeight="30.0" prefWidth="334.0" text="Jane Doe" />
                <Label prefHeight="17.0" prefWidth="349.0" text="jdoe@britishschool.sch.ae" textAlignment="CENTER" />
            </children>
        </VBox>
    </graphic>
</Button>

这是控制器:

@FXML
private Button id1; 
@FXML 
private Button id2;
@FXML 
private Button id3;
@FXML 
private Button id4;
@FXML 
private Button id5;
@FXML 
private Button id6;
@FXML 
private Button id7;
@FXML 
private Button id8;
@FXML 
private Button id9;


@FXML
protected void handleContactEmailButtonAction(ActionEvent event) 

    try 
        Desktop desktop = Desktop.getDesktop();
        String message = "mailto:"+emailvariable+"?subject=Music%20Bookings";
        URI uri = URI.create(message);
        desktop.mail(uri);

     catch (Exception e) 
        e.printStackTrace();
    

因此,如果单击带有 fx:id="id1" 的按钮,则电子邮件变量会更改为相关标签中的电子邮件,并且全部使用一个控制器?

感谢您的任何帮助,谢谢!

【问题讨论】:

【参考方案1】:

创建一个地图,您可以在其中从事件源获取按钮,例如:

@FXML
private Button id1;
@FXML
private Button id2;
@FXML
private Button id3;
@FXML
private Button id4;
@FXML
private Button id5;
@FXML
private Button id6;
@FXML
private Button id7;
@FXML
private Button id8;
@FXML
private Button id9;

private Map<Button, String> emailVariables;

@Override
public void initialize(URL location, ResourceBundle resources)

    emailVariables = new HashMap<Button, String>();
    emailVariables.put(id1, "id1@example.com");
    emailVariables.put(id2, "id2@example.com");
    emailVariables.put(id3, "id3@example.com");
    emailVariables.put(id4, "id4@example.com");
    emailVariables.put(id5, "id5@example.com");
    emailVariables.put(id6, "id6@example.com");
    emailVariables.put(id7, "id7@example.com");
    emailVariables.put(id8, "id8@example.com");
    emailVariables.put(id9, "i91@example.com");


@FXML
protected void handleContactEmailButtonAction(ActionEvent event)


try

    Desktop desktop = Desktop.getDesktop();
    String message = "mailto:" + emailvariables.get((Button) event.getSource()) + "?subject=Music%20Bookings";
    URI uri = URI.create(message);
    desktop.mail(uri);


catch (Exception e)

    e.printStackTrace();


代码未经测试。

【讨论】:

【参考方案2】:

考虑创建一个自定义组件:

package application;

import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

public class EmailButton extends Button 

    @FXML
    private Label nameLabel ;
    @FXML
    private Label addressLabel ;

    private final StringProperty name = new SimpleStringProperty();
    private final StringProperty emailAddress = new SimpleStringProperty();

    public EmailButton() throws IOException 

        FXMLLoader loader = new FXMLLoader(getClass().getResource("emailButton.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        loader.load();
    

    public void initialize() 
        nameLabel.textProperty().bind(name);
        addressLabel.textProperty().bind(emailAddress);
    

    @FXML
    private void sendEmail() 
        try 
            Desktop desktop = Desktop.getDesktop();
            String message = "mailto:"+getEmailAddress()+"?subject=Music%20Bookings";
            URI uri = URI.create(message);
            desktop.mail(uri);

         catch (Exception e) 
            e.printStackTrace();
        
    

    public StringProperty nameProperty() 
        return name ;
    

    public final String getName() 
        return nameProperty().get();
    

    public final void setName(String name) 
        nameProperty().set(name);
    

    public StringProperty emailAddressProperty() 
        return emailAddress ;
    

    public final String getEmailAddress() 
        return emailAddressProperty().get();
    

    public final void setEmailAddress(String emailAddress) 
        emailAddressProperty().set(emailAddress);
    

和 emailButton.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>


<fx:root xmlns:fx="http://javafx.com/fxml/1" type="Button" mnemonicParsing="false" onAction="#sendEmail" prefHeight="60.0" prefWidth="380.0" style="-fx-background-color: white;">

    <graphic>
        <VBox style="-fx-background-color: white; -fx-border-color: white;">
            <children>
                <Label fx:id="nameLabel" prefHeight="30.0" prefWidth="334.0" />
                <Label fx:id="addressLabel" prefHeight="17.0" prefWidth="349.0" textAlignment="CENTER" />
            </children>
        </VBox>
    </graphic>
</fx:root>

现在在你的主 FXML 中你可以这样做:

<?import application.EmailButton?>

<!-- ... -->

<EmailButton name="Jane Doe" emailAddress="jdoe@britishschool.sch.ae"/>
<EmailButton name="..." emailAddress="..." />
<EmailButton name="..." emailAddress="..."/>

【讨论】:

以上是关于多个 FXML 变量到 1 个控制器句柄的主要内容,如果未能解决你的问题,请参考以下文章

一个控制器到 2 个 fxmls (JavaFX)

带有控制器的多个 FXML,共享对象

如何使用不同的 fxml 文件创建多个 javafx 控制器?

无法在 javafx 中链接 fxml 和控制器文件变量 [重复]

JavaFx 元素未绑定到 fx:id 上的控制器变量 [重复]

在 JavaFX FXML 控制器中实现构造函数