首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFx自定义设计按钮单击已使用应用程序中的“检测”

JavaFx自定义设计按钮单击已使用应用程序中的“检测”
EN

Stack Overflow用户
提问于 2018-06-11 05:11:39
回答 2查看 1.4K关注 0票数 0

使用带有两个文件CustomToggleSwitch.fxml和CustomToggleSwitch.java的FXML创建自定义设计。

CustomToggleSwitch.fxml有以下代码

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<fx:root type="Pane" xmlns="http://javafx.com/javafx/8"   xmlns:fx="http://javafx.com/fxml/1">
 <children>
    <Button mnemonicParsing="false" onAction="#click" text="Button" />
 </children>
</fx:root>

CustomToggleSwitch.java有代码

代码语言:javascript
复制
package com.custom;

import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;

public class CustomToggleSwitch extends Pane{
   int tick;

   public CustomToggleSwitch() {

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

       try {
          loader.load();            
       } catch (IOException e) {
          e.printStackTrace();
     }
  }

  @FXML 
  public void click(ActionEvent actionEvent){
     System.out.println(tick++);
  }
}

从这些创建jar文件,并在应用程序项目中使用此jar文件。应用程序有test.fxml:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>

<?import com.custom.*?>
<?import com.custom.CustomToggleSwitch?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-   Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"   xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
  <children>
    <CustomToggleSwitch layoutX="29.0" layoutY="48.0" />
  </children>
</AnchorPane>

控制器类(TestController.java)具有以下内容

代码语言:javascript
复制
public class TestController implements Initializable{

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {

    }

    @FXML 
    public void click(){
        System.out.println("Test");
    }
}

按钮在GUI上显示成功,按钮单击也是get,detected.Button在输出控制台上显示0,1,2,3..etc。但是测试不会被打印在屏幕上。

如何检测应用程序控制器类中按下的按钮?可以帮助我解决这个问题。

非常感谢大家。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-11 06:54:27

在组件控制器中添加带有getter和setter的侦听器属性。

Jai的例子是正确的,但与javafx的其他组件不一致。为了正确的实现,应该使用可以在FXML和手动模式下操作的属性。

这是添加了onMyAction属性的用户组件控制器。此属性用于事件通知。

代码语言:javascript
复制
public class CustomToggleSwitch extends Pane {

    private ObjectProperty<EventHandler<ActionEvent>> onMyAction = new SimpleObjectProperty<EventHandler<ActionEvent>>();

    public CustomToggleSwitch() {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("/sample/CustomToggleSwitch.fxml"));
        loader.setRoot(this);
        loader.setController(this);

        try {
            loader.load();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void initialize() {

    }

    @FXML
    private void click(ActionEvent event) {
        if(onMyAction.get() != null) {
            onMyAction.get().handle(event);
        }
    }

    public EventHandler<ActionEvent> getOnMyAction() {
        return onMyAction.get();
    }

    public ObjectProperty<EventHandler<ActionEvent>> onMyActionProperty() {
        return onMyAction;
    }

    public void setOnMyAction(EventHandler<ActionEvent> onMyAction) {
        this.onMyAction.set(onMyAction);
    }
}

有了这样一个结构化组件,onMyAction属性就可以通过FXML添加例如

代码语言:javascript
复制
<AnchorPane fx:controller="sample.Controller" xmlns:fx="http://javafx.com/fxml" >
    <CustomToggleSwitch onMyAction="#testHandler"/>
</AnchorPane>
代码语言:javascript
复制
public class Controller {

    @FXML
    private void testHandler(ActionEvent event) {

    }

}

或者用手

代码语言:javascript
复制
<AnchorPane fx:controller="sample.Controller" xmlns:fx="http://javafx.com/fxml" >
    <CustomToggleSwitch fx:id="customToggleSwitch"/>
</AnchorPane>
代码语言:javascript
复制
public class Controller {

    @FXML
    private CustomToggleSwitch customToggleSwitch;

    @FXML
    private void initialize() {
        customToggleSwitch.setOnMyAction(event -> {

        });
    }

}

更新

你不需要用财产。使getter和setter可用,应该足以从fxml中使用它。(我还没有遇到向事件处理程序属性添加listerner的情况。)

这是不使用属性的转换。

代码语言:javascript
复制
public class CustomToggleSwitch extends Pane {

    private EventHandler<ActionEvent> myEventHandler;

    public CustomToggleSwitch() {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("/sample/CustomToggleSwitch.fxml"));
        loader.setRoot(this);
        loader.setController(this);

        try {
            loader.load();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void initialize() {

    }

    @FXML
    private void click(ActionEvent event) {
        if(myEventHandler != null) {
            myEventHandler.handle(event);
        }
    }

    public EventHandler<ActionEvent> getOnMyAction() {
        return myEventHandler;
    }

    public void setOnMyAction(EventHandler<ActionEvent> onMyAction) {
        myEventHandler = onMyAction;
    }
}
票数 3
EN

Stack Overflow用户

发布于 2018-06-11 05:57:15

这是因为onAction="#click"是在CustomToggleSwitch.fxml中声明的,所以FXMLLoader将在CustomToggleSwitch.java中查找click()

click()类中添加一个TestController不会做任何事情,因为在test.fxml中没有任何带有onAction="#click"的节点。

Button在CustomToggleSwitch中与TestController类通信的一种方法是将事件转发出去。

代码语言:javascript
复制
public class CustomToggleSwitch extends Pane {
    // Same stuff

    private List<Runnable> onClickRunnables = new ArrayList<>();

    public final void addButtonOnClickRunnable(Runnable runnable) {
        Objects.requireNonNull(runnable);
        onClickRunnables.add(runnable);
    }

    @FXML 
    private void click(ActionEvent actionEvent){
        System.out.println(tick++);
        if (!onClickRunnables.isEmpty()) {
            onClickRunnables.forEach(r -> r.run());
        }
    }
}


public class TestController implements Initializable {
    // Give CustomToggleSwitch control an fx:id in FXML
    @FXML private CustomToggleSwitch customSwitch;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        customSwitch.addButtonOnClickRunnable(this::click);
    }
}

另一种方法是在Button中公开CustomToggleSwitch out。就我个人而言,我建议不要这样做,因为将“控件”的实现隐藏起来更整洁。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50790838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档