【问题标题】:JavaFX TableView get row from button cellJavaFX TableView从按钮单元格获取行
【发布时间】:2017-11-19 02:31:34
【问题描述】:

参考问题JavaFX TableView custom cell rendering split menu button,我能够在每一行中呈现拆分菜单按钮。我已经按照James_D 的建议和Keyur Bhanderi 的回答更新了我的代码。 问题是关于在点击前不选择行的情况下获取拆分菜单所在行的值。

更新:添加图像以查看输出

下面的图片显示了我单击的每个按钮的输出。

更新了 SplitMenuCellFactory.java

package com.example.splimenubtn;

import java.util.List;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;

public class SplitMenuCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {

 private List<MenuItemFactory<T>> menuItems;

 public SplitMenuCellFactory() {}

 public SplitMenuCellFactory(List<MenuItemFactory<T>> items) {
  menuItems = items;
 }

 @Override
 public TableCell<S, T> call(TableColumn<S, T> param) {
  return new TableCell<S, T>() {
   @Override
   public void updateItem(T item, boolean empty) {
    super.updateItem(item, empty);
    if (empty) {
     setGraphic(null);
     setText(null);
    } else {
     setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
     if (getTableRow() != null) {
      setGraphic(new SplitMenuButtonFactory<>(menuItems, getTableRow().getIndex()).buildButton());
     }
    }
   }
  };
 }
}

更新,添加缺失的类

SplitMenuButtonFactory.java

package com.example.splimenubtn;

 import java.util.List;
 import javafx.scene.control.MenuItem;
 import javafx.scene.control.SplitMenuButton;

 public class SplitMenuButtonFactory<T> {

  private List<MenuItemFactory<T>> menuItems;
  private int rIndex = 0;

  public SplitMenuButtonFactory(List<MenuItemFactory<T>> items) {
   menuItems = items;
  }

  public SplitMenuButtonFactory(List<MenuItemFactory<T>> items, int rI) {
   menuItems = items;
   rIndex = rI;
  }

  public SplitMenuButton buildButton() {
   SplitMenuButton menuBtn = new SplitMenuButton();
   // menuBtn.getItems().addAll(menuItems);
   for (MenuItemFactory<?> mIF : menuItems) {
    MenuItem btn = mIF.setRowIndex(rIndex).buildMenuItem();
     if (mIF.isDefault()) {
     menuBtn.setText(btn.getText());
     menuBtn.setOnAction(btn.getOnAction());
    }
    menuBtn.getItems().add(btn);
   }
  return menuBtn;
 }
}

MenuItemsFactory.java

package com.example.splimenubtn;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableView;

public class MenuItemFactory<S> {

 private MenuItemActions itemType;
 private String itemLbl;
 private TableView<S> table;
 private boolean defaultAction;
 private int rIndex = 0;

 public MenuItemFactory(MenuItemActions itemType, String itemLabel, boolean dA) {
  this.itemType = itemType;
  itemLbl = itemLabel;
  defaultAction = dA;
 }

 public MenuItemFactory(MenuItemActions itemType, String itemLabel, TableView<S> t, boolean dA) {
  this.itemType = itemType;
  itemLbl = itemLabel;
  defaultAction = dA;
  table = t;
 }

 public MenuItemFactory<S> setDataList(TableView<S> t) {
  table = t;
  return this;
 }

 public boolean isDefault() {
  return defaultAction;
 }

 public MenuItemFactory<S> setRowIndex(int rI) {
  rIndex = rI;
  return this;
 }

 public MenuItem buildMenuItem() {
  MenuItem mI = new MenuItem();
  switch (itemType) {
   case DETAILS:
    mI.setText(itemLbl);
    mI.setOnAction(handleDetails());
   break;
  case EDIT:
    mI.setText(itemLbl);
    mI.setOnAction(handleEdit());
   break;
   case DELETE:
    mI.setText(itemLbl);
    mI.setOnAction(handleDelete());
   break;
   default:
   break;
  }
  return mI;
 }

 private EventHandler<ActionEvent> handleDetails() {
  return new EventHandler<ActionEvent>() {
   @Override
   public void handle(ActionEvent aE) {
    System.out.println("*** DETAIL REQUEST ***");
   }
  };
 }

 private EventHandler<ActionEvent> handleEdit() {
  return new EventHandler<ActionEvent>() {
   @Override
   public void handle(ActionEvent aE) {
    System.out.println("*** EDIT REQUESTED ***");
    table.getSelectionModel().select(rIndex);
    System.out.println("*** " + table.getSelectionModel().getSelectedItem().toString() + " ***");
   }
  };
 }

 private EventHandler<ActionEvent> handleDelete() {
  return new EventHandler<ActionEvent>() {
   @Override
   public void handle(ActionEvent aE) {
    System.out.println("*** DELETE REQUESTED ***");
    System.out.println("*** " + table.getSelectionModel().getSelectedItem().toString() + " ***");
   }
  };
 }
}

但是当我点击按钮时,我总是得到最后一个值。

如何获取按钮所在行中的对象?

感谢任何可以为我指明正确方向的帮助或建议。

【问题讨论】:

    标签: javafx tableview javafx-8


    【解决方案1】:

    只需使用TableCell 来检索onAction 事件处理程序中的值(或您在SplitMenuButtonFactory 的产品中使用的任何东西,您没有向我们显示)。

    简化示例

    public static SplitMenuButton createSplitMenuButton(final TableCell cell) {
        SplitMenuButton result = new SplitMenuButton();
    
        result.setOnAction(evt -> {
            TableRow row = cell.getTableRow();
            System.out.println("row item: " +row.getItem());
        });
    
        return result;
    }
    

    此外,最好在单元格中重复使用 SplitMenuButton 并更新它,而不是在每次单元格项目更改时重新使用它。

    @Override
    public TableCell<S, T> call(TableColumn<S, T> param) {
        return new TableCell<S, T>() {
    
            private final SplitMenuButton button = createSplitMenuButton(this);
    
            {
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            }
    
            @Override
            public void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
    
                if (empty) {
                    setGraphic(null);
                } else {
                    updateMenuButton(button, item); // placeholder for updating the button according to the new item
    
                    setGraphic(button);
                }
            }
        };
    }
    

    【讨论】:

    猜你喜欢
    • 2020-10-20
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    相关资源
    最近更新 更多