检测添加到javafx列表视图中的按钮的按钮单击情况

时间:2019-12-21 20:04:45

标签: javafx

我对Java非常陌生,所以请耐心等待。我已经成功地将按钮,标签甚至进度条添加到了列表视图单元格中。我需要能够检测到何时单击了按钮之一。将控件添加到我设法从几篇文章中获得的listview内容中,下面显示了我正在使用的代码

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ProgressBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.Stage;



public class ListViewDemo extends Application {

  public static class lvCell extends VBox {

    Label labelName = new Label();
    Label labelPath = new Label();
    Label labelElapse = new Label();
    Button buttonPlayPause = new Button();
    Button buttonStop = new Button();
    ImageView ivStop = new ImageView();
    ImageView ivPlay = new ImageView();
    Pane buttonSpacer = new Pane();
    Pane progressBarSpacer = new Pane();

    HBox hbDetail = new HBox();
    HBox hbProgress = new HBox();

    ProgressBar pbProgress = new ProgressBar();

    File filePlay;
    File fileStop;

    double prefWidth = 10;
    double prefHeight = 10;

    lvCell(String labelText) {
      super();

      labelName.setText(labelText);
      labelName.setMaxWidth(Double.MAX_VALUE);
      labelPath.setMaxWidth(0);
      labelPath.setText("Path");

      pbProgress.setMaxWidth(Double.MAX_VALUE);

      HBox.setHgrow(labelName, Priority.ALWAYS);
      HBox.setHgrow(pbProgress, Priority.ALWAYS);

      HBox.setMargin(labelName, new Insets(5, 0, 0, 0));
      HBox.setMargin(pbProgress, new Insets(0, 0, 0, 0));

      labelPath.setVisible(false);

      buttonSpacer.setPrefSize(prefWidth, prefHeight);

      labelElapse.setPrefSize(50, prefHeight);
      labelElapse.setText("Time");;

      progressBarSpacer.setPrefSize(prefWidth * 6, prefHeight);

      filePlay = new File("src/image/play.png");
      fileStop = new File("src/image/stop.png");

      Image imagePlay = new Image(filePlay.toURI().toString());
      Image imageStop = new Image(fileStop.toURI().toString());

      ivPlay.setImage(imagePlay);
      ivStop.setImage(imageStop);

      ivPlay.setFitHeight(prefHeight);
      ivPlay.setFitWidth(prefWidth);
      ivStop.setFitHeight(prefHeight);
      ivStop.setFitWidth(prefWidth);

      buttonPlayPause.setGraphic(ivPlay);
      buttonStop.setGraphic(ivStop);

      buttonPlayPause.setMaxSize(prefWidth, prefHeight);
      buttonStop.setMaxSize(prefWidth, prefHeight);

      pbProgress.setMaxHeight(2);
      pbProgress.setPrefHeight(2);

      hbDetail.getChildren().addAll(buttonPlayPause, buttonStop, buttonSpacer, labelName, labelPath);
      hbProgress.getChildren().addAll(progressBarSpacer, pbProgress, labelElapse);
      this.getChildren().addAll(hbDetail, hbProgress);
    }

  }

  public Parent createContent() {
    BorderPane layout = new BorderPane();

    List < lvCell > list = new ArrayList < > ();
    for (int i = 0; i < 10; i++) {
      list.add(new lvCell("Item " + i));
    }

    ListView < lvCell > listView = new ListView < lvCell > ();
    ObservableList < lvCell > myObservableList = FXCollections.observableList(list);
    listView.setItems(myObservableList);

    layout.setCenter(listView);

    return layout;
  }

  @Override
  public void start(Stage stage) throws Exception {
    stage.setScene(new Scene(createContent()));
    stage.setWidth(300);
    stage.setHeight(200);
    stage.show();
  }

  public static void main(String args[]) {
    launch(args);
  }
}

屏幕如下所示:

reulting screen

任何帮助将不胜感激。

预先感谢,并祝您旅途愉快。

2 个答案:

答案 0 :(得分:1)

这不是一个专门设计用于放入ListView的类。 ListView中用作项目的对象应包含数据; ListCell产生的cellFactory实现负责确定ListView中数据的可视表示。这样,您可以避免为每个对象创建节点,从而减少了内存占用,这正是ListView的目标。

简化示例

这里的数据仅包含进度和一些文本;它显示在单元格的ProgressBartext中;单元格中的一个附加按钮允许每次单击将进度增加0.25,并删除进度为1的所有项目。

数据类

public class Data {

    private final DoubleProperty progress = new SimpleDoubleProperty();

    private final String text;

    public Data(String text) {
        this.text = text;
    }

    public double getProgress() {
        return progress.get();
    }

    public void setProgress(double value) {
        progress.set(value);
    }

    public String getText() {
        return text;
    }

    public ObservableValue<? extends Number> progressProperty() {
        return progress;
    }

}

ListView代码

ListView<Data> listView = new ListView<>(someData);
listView.setCellFactory(l -> new ListCell<Data>() {

    private final ProgressBar progressBar = new ProgressBar();
    private final Button button = new Button("increase");
    private final HBox content = new HBox(progressBar, button);

    {
        button.setOnAction(evt -> {
            Data item = getItem();
            int index = getIndex();
            double progress = item.getProgress() + 0.25;
            item.setProgress(progress);
            if (progress >= 1) {
                getListView().getItems().remove(index);
            }
        });
    }

    @Override
    protected void updateItem(Data item, boolean empty) {
        super.updateItem(item, empty);
        progressBar.progressProperty().unbind();

        if (item == null) {
            setGraphic(null);
            setText("");
        } else {
            setGraphic(content);
            setText(item.getText());
            progressBar.progressProperty().bind(item.progressProperty());
        }
    } 

});

答案 1 :(得分:0)

发布问题后,我做了一些进一步的挖掘,并添加了以下侦听器:

buttonPlayPause.setOnAction(event -> {
    System.out.println("play button clicked");
});

虽然这告诉我单击了一个按钮,但没有告诉我哪个按钮。我将继续进行挖掘,但是非常感谢您的帮助。

祝你旅途平安