JavaFX TableView从按钮单元格获取行

JavaFX TableView从按钮单元格获取行,javafx,tableview,javafx-8,Javafx,Tableview,Javafx 8,关于这个问题,我能够在每一行中呈现分割菜单按钮。我已经按照和的建议更新了代码。 问题是关于在单击之前不选择行而获取拆分菜单所在行的值 更新:添加图像以查看输出 下面的图像显示了我单击的每个按钮的输出 更新了SplitMenuCellFactory.java package com.example.splimenubtn; import java.util.List; import javafx.scene.control.ContentDisplay; import javafx.scen

关于这个问题,我能够在每一行中呈现分割菜单按钮。我已经按照和的建议更新了代码。 问题是关于在单击之前不选择行而获取拆分菜单所在行的值

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

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

更新了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());
     }
    }
   }
  };
 }
}
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;
 }
}
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() + " ***");
   }
  };
 }
}
package com.example.splimenubtn;
导入java.util.List;
导入javafx.scene.control.ContentDisplay;
导入javafx.scene.control.TableCell;
导入javafx.scene.control.TableColumn;
导入javafx.util.Callback;
公共类SplitMenuCellFactory实现回调{
私有列表菜单项;
公共SplitMenuCellFactory(){}
公共拆分工厂(列表项){
菜单项=项目;
}
@凌驾
公共TableCell调用(TableColumn参数){
返回新的TableCell(){
@凌驾
public void updateItem(T项,布尔值为空){
super.updateItem(项,空);
if(空){
设置图形(空);
setText(空);
}否则{
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
如果(getTableRow()!=null){
setGraphic(新的SplitMenuButtonFactory(menuItems,getTableRow().getIndex()).buildButton());
}
}
}
};
}
}
更新,添加缺少的类

SplitMenuButtonFactory.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());
     }
    }
   }
  };
 }
}
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;
 }
}
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() + " ***");
   }
  };
 }
}
package com.example.splimenubtn;
导入java.util.List;
导入javafx.scene.control.MenuItem;
导入javafx.scene.control.SplitMenuButton;
公共类SplitMenuButtonFactory{
私有列表菜单项;
私有int-rIndex=0;
公共拆分菜单按钮工厂(列表项){
菜单项=项目;
}
公共SplitMenuButtonFactory(列表项,int-rI){
菜单项=项目;
rIndex=rI;
}
公共拆分菜单按钮buildButton(){
SplitMenuButton menuBtn=新的SplitMenuButton();
//menuBtn.getItems().addAll(menuItems);
用于(MenuItemFactory mIF:menuItems){
MenuItem btn=mIF.setRowIndex(rIndex.buildMenuItem();
if(mIF.isDefault()){
menuBtn.setText(btn.getText());
menuBtn.setOnAction(btn.getOnAction());
}
menuBtn.getItems().add(btn);
}
返回菜单;
}
}
MenuItemsFactory.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());
     }
    }
   }
  };
 }
}
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;
 }
}
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() + " ***");
   }
  };
 }
}
package com.example.splimenubtn;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.control.MenuItem;
导入javafx.scene.control.TableView;
公共类菜单工厂{
私有菜单项类型;
私有字符串itemLbl;
私有表视图表;
私人行为;
私有int-rIndex=0;
公共MenuItemFactory(MenuItemActions项类型、字符串项标签、布尔值dA){
this.itemType=itemType;
itemLbl=itemLabel;
defaultAction=dA;
}
公共MenuItemFactory(MenuItemActions itemType、String itemLabel、TableView t、布尔dA){
this.itemType=itemType;
itemLbl=itemLabel;
defaultAction=dA;
表=t;
}
公共菜单工厂设置数据列表(TableView t){
表=t;
归还这个;
}
公共布尔值isDefault(){
返回默认操作;
}
公共菜单工厂设置行索引(int rI){
rIndex=rI;
归还这个;
}
公共菜单项buildMenuItem(){
MenuItem mI=新的MenuItem();
开关(项目类型){
案件详情:
mI.setText(itemLbl);
mI.setOnAction(handleDetails());
打破
案例编辑:
mI.setText(itemLbl);
mI.setOnAction(handleEdit());
打破
案例删除:
mI.setText(itemLbl);
mI.setOnAction(handleDelete());
打破
违约:
打破
}
返回mI;
}
私有EventHandler handleDetails(){
返回新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent aE){
System.out.println(“***详细请求***”);
}
};
}
私有EventHandler handleEdit(){
返回新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent aE){
System.out.println(“***请编辑***”);
table.getSelectionModel().select(rIndex);
System.out.println(“***”+table.getSelectionModel().getSelectedItem().toString()+“***”);
}
};
}
私有EventHandler handleDelete(){
返回新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent aE){
System.out.println(“***删除请求***”);
System.out.println(“***”+table.getSelectionModel().getSelectedItem().toString()+“***”);
}
};
}
}
但当我点击按钮时,我总是得到最后一个值

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


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

只需使用
TableCell
检索
onAction
事件处理程序中的值(或您在
SplitMenuButtonFactory
产品中使用的任何内容)

简化示例 此外,最好在单元格中重用
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);
            }
        }
    };
}
@覆盖
公共TableCell调用(TableColumn参数){
返回新的TableCell(){
私有最终SplitMenuButton按钮=CreateSpilitMenuButton(此按钮);
{
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
}
@凌驾
public void updateItem(T项,布尔值为空){
super.updateItem(项,空);
if(空){
设置图形(空);
}否则{
UpdateNuButton(按钮,项目);//用于根据新项目更新按钮的占位符
设置图形(按钮);
}
}
};
}

您可以在链接的问题中查看SplitMenuButtonFactory