javafx 无法访问自定义列表单元格中的按钮
javafx cannot access button in custom listcell
问题的核心是我无法刷新或更改场景节点(此处为TablesMain)的内容class(此处为NamePriceCell)。
我正在使用包含其他节点(其中一些是 ListView)的主 StackPane(TableMainController 扩展 StackPane)构建和应用程序。在特定的 ListView(比如 'readitemslistview')中,我创建了一个自定义 ListCell(public class NamePriceCell extends ListCell)并且这个 NamePriceCell listcell 包含一个按钮(plusbtn)。当用户单击 plusbtn 时,数组列表(比如 'chosenitemslist')会被特定单元格中显示的项目填满,同时堆栈窗格中的另一个列表视图(比如 'ordereditemslist')应该触发显示'chosenitemslist'数组列表的内容。
我还没有找到从主控制器引用 NamePriceCell 的 plusbtn 的方法。而且这个post
Get ListCell via ListView
Unfortunately right now there is no API to get List Cell by index or
to get All children's(listcells) for ListView.
让我放弃了这样的尝试(我无法理解那里提供的解决方案是否适合我的需要,因为我不想刷新同一个列表视图,而是从另一个同一场景)。
所以我发现从 plusbtn 获得鼠标点击动作的唯一方法是在同一个 class (NamePriceCell) 中使用 EventHandler。即使我可以根据 NamePriceCell 按钮上的点击得到一个数组列表(NamePriceCell 在另一个 class 中调用一个静态方法,里面有一个静态数组列表),我可以通过让用户单击 TableMain StackPane 的另一个按钮节点,当用户单击 NamePriceCell 按钮时,我找不到执行该操作的方法。
我尝试的事情之一是在 TablesMainController 中设置一个静态方法,我可以从 NamePriceCell EventHandler 访问它(但后来我必须使 ordereditemslist 的持有者节点静态,即使如此,它也没有用),
为包含带有相应单独控制器的 ordereditemslist 的 VBox 编写一个单独的 fxml,以便我可以在那里有一个方法来创建 ordereditemslist 并设置 cellFactory(但即使 fxml 文件正确显示并从 NamePriceCell 的 EventHandler 调用方法也有效- 显示 System.out - 它不会影响屏幕上的任何内容,除了 ordereditemslist,甚至是我测试过的标签。
我相对来说是一个 java 新手,在 javafx 方面更是如此。非常需要和感谢您的帮助。
我最后一个方法的代码如下:
VboxList.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.VBox?>
<VBox>
<Label text="Label" id="label1"/>
<Label text="Label" id="label2"/>
<Label text="sdfsdf" id="label3"/>
<ListView nodeOrientation="LEFT_TO_RIGHT" id="orderedlist" prefHeight="200.0" prefWidth="200.0" />
</VBox>
VboxListController.java
public class VboxListController extends VBox{
FXMLLoader fxmlLoader;
@FXML
private Label label1;
@FXML
private Label label2;
@FXML
private ListView<OrderItem> orderedlist;
public VboxListController() {
fxmlLoader = new FXMLLoader(getClass().getResource("fxml/VboxList.fxml"));
//fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public void getorderedlist(ArrayList<OrderItem> chosenitems){
ObservableList<OrderItem> myObservableList = FXCollections.observableList(chosenitems);
this.getChildren().remove(orderedlist);
orderedlist = new ListView<>();
orderedlist.setItems(myObservableList);
orderedlist.setCellFactory(new Callback<ListView<OrderItem>, ListCell<OrderItem>>() {
@Override
public ListCell<OrderItem> call(ListView<OrderItem> p) {
ListCell<OrderItem> cell = new ListCell<OrderItem>() {
@Override
protected void updateItem(OrderItem dataobj, boolean bln) {
super.updateItem(dataobj, bln);
if (dataobj != null) {
setText(dataobj.read_item_name);
}
}
};
return cell;
}
});
this.getChildren().add(orderedlist);
orderedlist.setItems(null);
orderedlist.setItems(myObservableList);
label1 = null;
this.getChildren().remove(label1);
label1 = new Label();
label1.setText("oooops!");
System.out.println("sdf");
this.getChildren().add(label1);
}
}
NamePriceCell.java
public class NamePriceCell extends ListCell<ReadItemChoiceObj> {
int count=0;
@FXML
Label namelbl;
@FXML
Label pricelbl;
@FXML
Button plusbtn;
@FXML
Region spacer;
@FXML
HBox cellHbox;
FXMLLoader mLLoader;
ReadItemChoiceObj readitem;
ArrayList<ReadItemChoiceObj> chosenreaditems;
@Override
protected void updateItem(ReadItemChoiceObj readitem, boolean empty) {
super.updateItem(readitem, empty);
chosenreaditems = new ArrayList<>();
if(empty || readitem == null) {
setText(null);
setGraphic(null);
} else {
this.readitem = readitem;
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getResource("fxml/NamePriceCell.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
namelbl.setText(readitem.getname());
namelbl.setMaxWidth(500);
pricelbl.setText(String.format("%.2f", readitem.getprice()));
pricelbl.setStyle("-fx-font: 8pt \"Arial\";");
pricelbl.setMaxWidth(40);
spacer.setMaxWidth(10);
spacer.setMinWidth(10);
plusbtn.setMaxWidth(20);
cellHbox.setHgrow(namelbl, Priority.ALWAYS);
cellHbox.setAlignment(Pos.BASELINE_LEFT);
setText(null);
setGraphic(cellHbox);
plusbtn.setOnMouseClicked(whattodohandler);
}
}
EventHandler<MouseEvent> whattodohandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
ChosenItemsStat.getplusbtnclicked(readitem);
ChosenItemsStat chos = new ChosenItemsStat();
count+=1;
plusbtn.setText(String.valueOf(count));
new VboxListController().getorderedlist(chos.sendchosenlist());
}
};
}
和TablesMain.java
的一部分
@FXML
Label label1;
@FXML
BorderPane borderpane;
@FXML
Pane tablepane;
@FXML
ListView<DataObj> tabcatlist;
@FXML
VBox VboxList;
@FXML
VboxListController vboxListController;
/* @FXML
ListView<OrderItem> orderedlist;*/
@FXML
VBox leftVbox;
public TablesMain(Order order) {
this.order = order;
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/tablesmain.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
ObservableList<DataObj> myObservableList = FXCollections.observableList(gettable_categories());
tabcatlist.setItems(myObservableList);
tabcatlist.setCellFactory(new Callback<ListView<DataObj>, ListCell<DataObj>>() {
@Override
public ListCell<DataObj> call(ListView<DataObj> p) {
ListCell<DataObj> cell = new ListCell<DataObj>() {
@Override
protected void updateItem(DataObj dataobj, boolean bln) {
super.updateItem(dataobj, bln);
if (dataobj != null) {
setText(dataobj.getname());
}
}
};
return cell;
}
});
if (table_categoryID == 0) table_categoryID = tablecategories.get(0).getid();
gettables(table_categoryID);
}
private void make_readitemlist(int itemcategoryID) {
readitems = new ArrayList<>();
.... the readitems arraylist gets filled up...
ObservableList<ReadItemChoiceObj> myObservableList = FXCollections.observableList(readitems);
readitemlist.setItems(myObservableList);
readitemlist.setCellFactory(new Callback<ListView<ReadItemChoiceObj>,
ListCell<ReadItemChoiceObj>>() {
@Override
public ListCell<ReadItemChoiceObj> call(ListView<ReadItemChoiceObj> list) {
readitemlistcell = new NamePriceCell();
return readitemlistcell;
}
}
);
readitemlist.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
ReadItemChoiceObj dataobj = (ReadItemChoiceObj) readitemlist.getSelectionModel().getSelectedItem();
System.out.println(String.valueOf(dataobj.getid()));
// showorderedlist(new ChosenItemsStat().sendchosenlist());
}
});
System.out.println(readitemlist.cellFactoryProperty().getClass().toString());
}
...
}
由于已经将近 5 个月没有其他贡献,我想 post 我的解决方案作为答案。这不是我的,而是受到我问题中提到的 post 的启发(或复制)(或另一个,现在我不记得了,请原谅我可能错位的学分)。
更准确地说,我在 TableMain 文件(主控制器 class)中创建了一个静态 StringProperty。每次单击 plusbtn(扩展 ListCell 的 NamePriceCell class)时,都会在 TableMain 控制器 class 的静态 StringProperty 中强制转换为字符串的随机数。在这个 class 中,StringProperty 添加了一个 ChangeListener,它依次触发(现在从主控制器内部 - 这就是线索)有序列表的刷新(必须使用添加的项目刷新的列表视图) .
NamePriceCell.java
public class NamePriceCell extends ListCell<ReadItemChoiceObj> {
@FXML
Label namelbl;
@FXML
Label pricelbl;
@FXML
Button plusbtn;
@FXML
Region spacer;
@FXML
HBox cellHbox;
FXMLLoader mLLoader;
ReadItemChoiceObj readitem;
@Override
protected void updateItem(ReadItemChoiceObj readitem, boolean empty) {
super.updateItem(readitem, empty);
if(empty || readitem == null) {
setText(null);
setGraphic(null);
} else {
this.readitem = readitem;
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getResource("fxml/NamePriceCell.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
namelbl.setText(readitem.getname());
namelbl.setMaxWidth(500);
pricelbl.setText(String.format("%.2f", readitem.getprice()));
pricelbl.setStyle("-fx-font: 8pt \"Arial\";");
pricelbl.setMaxWidth(40);
spacer.setMaxWidth(10);
spacer.setMinWidth(10);
plusbtn.setMaxWidth(20);
cellHbox.setHgrow(namelbl, Priority.ALWAYS);
cellHbox.setAlignment(Pos.BASELINE_LEFT);
setText(null);
setGraphic(cellHbox);
plusbtn.setOnMouseClicked(whattodohandler);
}
}
EventHandler<MouseEvent> whattodohandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
OrderItem orderitem = new OrderItem();
orderitem.read_item_name = readitem.getname();
orderitem.read_item_price=readitem.getprice();
orderitem.read_itemID=readitem.getid();
orderitem.choice_name_list = new ArrayList<String>();
orderitem.choice_price_list = new ArrayList<Float>();
orderitem.choice_id_list = new ArrayList<Integer>();
ChosenItemsStat.getplusbtnclicked(orderitem);
Random rand = new Random();
TablesMain.stringProperty.setValue(String.valueOf(rand));
}
};
}
ChosenItemsStat.java(静态 class 接收列表的添加项)
public class ChosenItemsStat {
static ArrayList<OrderItem> chosenorderitemsstat = new ArrayList<>();
static void getplusbtnclicked(OrderItem orderitem){
chosenorderitemsstat.add(orderitem);
}
}
我没有使用 VboxList.fxml 或 VboxListController.java,因为我将其包含在 TablesMain.java 中(见下文)
TablesMain.java(与问题相同,但添加了此内容)
stringProperty = new SimpleStringProperty();
stringProperty.setValue("");
tablelbl.setText(stringProperty.getValue());
stringProperty.addListener(new ChangeListener(){
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
showselectedlist();
}
});
而通过更改 StringProperty 值调用的 showselectedlist() 是下面的那个(在此方法中,单元格的构造与删除的 class (VboxListController)
private void showselectedlist(){
orderitems.addAll(ChosenItemsStat.chosenorderitemsstat);
ChosenItemsStat.chosenorderitemsstat.clear();
ListView<OrderItem> selectedlist = new ListView<>();
ObservableList<OrderItem> myObservableList = FXCollections.observableList(orderitems);
selectedlist.setItems(myObservableList);
selectedlist.setMaxWidth(220);
selectedlist.setCellFactory(new Callback<ListView<OrderItem>, ListCell<OrderItem>>() {
@Override
public ListCell<OrderItem> call(ListView<OrderItem> p) {
ListCell<OrderItem> cell = new ListCell<OrderItem>(){
OrderedCell ordcell= new OrderedCell();
@Override
protected void updateItem(OrderItem orderitem, boolean bln) {
super.updateItem(orderitem, bln);
if (orderitem != null) {
Float price = ordcell.getitemTempPrice(orderitem,orderitem.read_item_price);
HBox namepriceHbox = new HBox();
Label lblprice= new Label(String.format("%.2f",price));
Region betweenregion = new Region();
Label lblname = new Label();
lblname.setText(orderitem.read_item_name );
lblname.setStyle("-fx-font: 10pt \"Arial\";-fx-font-weight:bold");
namepriceHbox.setHgrow(betweenregion, Priority.ALWAYS);
namepriceHbox.getChildren().addAll(lblname,betweenregion,lblprice);
VBox allVbox = new VBox();
Text lblchoices = new Text();
String choices = ordcell.choicestostring(orderitem);
lblchoices.setText(choices);
lblchoices.setWrappingWidth(listpane.getLayoutBounds().getWidth());
if (choices.equals("")) allVbox.getChildren().addAll(namepriceHbox);
else allVbox.getChildren().addAll(namepriceHbox, lblchoices);
double namepricewidth = listpane.getLayoutBounds().getWidth();
System.out.println("namepricewidth is "+String.valueOf(namepricewidth));
//allVbox.setPadding(new Insets(10,0,10,0));
setGraphic(allVbox);
}
}
};
return cell;
}
});
listpane.getChildren().add(selectedlist);
}
问题的核心是我无法刷新或更改场景节点(此处为TablesMain)的内容class(此处为NamePriceCell)。
我正在使用包含其他节点(其中一些是 ListView)的主 StackPane(TableMainController 扩展 StackPane)构建和应用程序。在特定的 ListView(比如 'readitemslistview')中,我创建了一个自定义 ListCell(public class NamePriceCell extends ListCell)并且这个 NamePriceCell listcell 包含一个按钮(plusbtn)。当用户单击 plusbtn 时,数组列表(比如 'chosenitemslist')会被特定单元格中显示的项目填满,同时堆栈窗格中的另一个列表视图(比如 'ordereditemslist')应该触发显示'chosenitemslist'数组列表的内容。
我还没有找到从主控制器引用 NamePriceCell 的 plusbtn 的方法。而且这个post Get ListCell via ListView
Unfortunately right now there is no API to get List Cell by index or to get All children's(listcells) for ListView.
让我放弃了这样的尝试(我无法理解那里提供的解决方案是否适合我的需要,因为我不想刷新同一个列表视图,而是从另一个同一场景)。
所以我发现从 plusbtn 获得鼠标点击动作的唯一方法是在同一个 class (NamePriceCell) 中使用 EventHandler。即使我可以根据 NamePriceCell 按钮上的点击得到一个数组列表(NamePriceCell 在另一个 class 中调用一个静态方法,里面有一个静态数组列表),我可以通过让用户单击 TableMain StackPane 的另一个按钮节点,当用户单击 NamePriceCell 按钮时,我找不到执行该操作的方法。 我尝试的事情之一是在 TablesMainController 中设置一个静态方法,我可以从 NamePriceCell EventHandler 访问它(但后来我必须使 ordereditemslist 的持有者节点静态,即使如此,它也没有用), 为包含带有相应单独控制器的 ordereditemslist 的 VBox 编写一个单独的 fxml,以便我可以在那里有一个方法来创建 ordereditemslist 并设置 cellFactory(但即使 fxml 文件正确显示并从 NamePriceCell 的 EventHandler 调用方法也有效- 显示 System.out - 它不会影响屏幕上的任何内容,除了 ordereditemslist,甚至是我测试过的标签。
我相对来说是一个 java 新手,在 javafx 方面更是如此。非常需要和感谢您的帮助。
我最后一个方法的代码如下:
VboxList.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.VBox?>
<VBox>
<Label text="Label" id="label1"/>
<Label text="Label" id="label2"/>
<Label text="sdfsdf" id="label3"/>
<ListView nodeOrientation="LEFT_TO_RIGHT" id="orderedlist" prefHeight="200.0" prefWidth="200.0" />
</VBox>
VboxListController.java
public class VboxListController extends VBox{
FXMLLoader fxmlLoader;
@FXML
private Label label1;
@FXML
private Label label2;
@FXML
private ListView<OrderItem> orderedlist;
public VboxListController() {
fxmlLoader = new FXMLLoader(getClass().getResource("fxml/VboxList.fxml"));
//fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public void getorderedlist(ArrayList<OrderItem> chosenitems){
ObservableList<OrderItem> myObservableList = FXCollections.observableList(chosenitems);
this.getChildren().remove(orderedlist);
orderedlist = new ListView<>();
orderedlist.setItems(myObservableList);
orderedlist.setCellFactory(new Callback<ListView<OrderItem>, ListCell<OrderItem>>() {
@Override
public ListCell<OrderItem> call(ListView<OrderItem> p) {
ListCell<OrderItem> cell = new ListCell<OrderItem>() {
@Override
protected void updateItem(OrderItem dataobj, boolean bln) {
super.updateItem(dataobj, bln);
if (dataobj != null) {
setText(dataobj.read_item_name);
}
}
};
return cell;
}
});
this.getChildren().add(orderedlist);
orderedlist.setItems(null);
orderedlist.setItems(myObservableList);
label1 = null;
this.getChildren().remove(label1);
label1 = new Label();
label1.setText("oooops!");
System.out.println("sdf");
this.getChildren().add(label1);
}
}
NamePriceCell.java
public class NamePriceCell extends ListCell<ReadItemChoiceObj> {
int count=0;
@FXML
Label namelbl;
@FXML
Label pricelbl;
@FXML
Button plusbtn;
@FXML
Region spacer;
@FXML
HBox cellHbox;
FXMLLoader mLLoader;
ReadItemChoiceObj readitem;
ArrayList<ReadItemChoiceObj> chosenreaditems;
@Override
protected void updateItem(ReadItemChoiceObj readitem, boolean empty) {
super.updateItem(readitem, empty);
chosenreaditems = new ArrayList<>();
if(empty || readitem == null) {
setText(null);
setGraphic(null);
} else {
this.readitem = readitem;
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getResource("fxml/NamePriceCell.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
namelbl.setText(readitem.getname());
namelbl.setMaxWidth(500);
pricelbl.setText(String.format("%.2f", readitem.getprice()));
pricelbl.setStyle("-fx-font: 8pt \"Arial\";");
pricelbl.setMaxWidth(40);
spacer.setMaxWidth(10);
spacer.setMinWidth(10);
plusbtn.setMaxWidth(20);
cellHbox.setHgrow(namelbl, Priority.ALWAYS);
cellHbox.setAlignment(Pos.BASELINE_LEFT);
setText(null);
setGraphic(cellHbox);
plusbtn.setOnMouseClicked(whattodohandler);
}
}
EventHandler<MouseEvent> whattodohandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
ChosenItemsStat.getplusbtnclicked(readitem);
ChosenItemsStat chos = new ChosenItemsStat();
count+=1;
plusbtn.setText(String.valueOf(count));
new VboxListController().getorderedlist(chos.sendchosenlist());
}
};
}
和TablesMain.java
的一部分 @FXML
Label label1;
@FXML
BorderPane borderpane;
@FXML
Pane tablepane;
@FXML
ListView<DataObj> tabcatlist;
@FXML
VBox VboxList;
@FXML
VboxListController vboxListController;
/* @FXML
ListView<OrderItem> orderedlist;*/
@FXML
VBox leftVbox;
public TablesMain(Order order) {
this.order = order;
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/tablesmain.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
ObservableList<DataObj> myObservableList = FXCollections.observableList(gettable_categories());
tabcatlist.setItems(myObservableList);
tabcatlist.setCellFactory(new Callback<ListView<DataObj>, ListCell<DataObj>>() {
@Override
public ListCell<DataObj> call(ListView<DataObj> p) {
ListCell<DataObj> cell = new ListCell<DataObj>() {
@Override
protected void updateItem(DataObj dataobj, boolean bln) {
super.updateItem(dataobj, bln);
if (dataobj != null) {
setText(dataobj.getname());
}
}
};
return cell;
}
});
if (table_categoryID == 0) table_categoryID = tablecategories.get(0).getid();
gettables(table_categoryID);
}
private void make_readitemlist(int itemcategoryID) {
readitems = new ArrayList<>();
.... the readitems arraylist gets filled up...
ObservableList<ReadItemChoiceObj> myObservableList = FXCollections.observableList(readitems);
readitemlist.setItems(myObservableList);
readitemlist.setCellFactory(new Callback<ListView<ReadItemChoiceObj>,
ListCell<ReadItemChoiceObj>>() {
@Override
public ListCell<ReadItemChoiceObj> call(ListView<ReadItemChoiceObj> list) {
readitemlistcell = new NamePriceCell();
return readitemlistcell;
}
}
);
readitemlist.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
ReadItemChoiceObj dataobj = (ReadItemChoiceObj) readitemlist.getSelectionModel().getSelectedItem();
System.out.println(String.valueOf(dataobj.getid()));
// showorderedlist(new ChosenItemsStat().sendchosenlist());
}
});
System.out.println(readitemlist.cellFactoryProperty().getClass().toString());
}
...
}
由于已经将近 5 个月没有其他贡献,我想 post 我的解决方案作为答案。这不是我的,而是受到我问题中提到的 post 的启发(或复制)(或另一个,现在我不记得了,请原谅我可能错位的学分)。 更准确地说,我在 TableMain 文件(主控制器 class)中创建了一个静态 StringProperty。每次单击 plusbtn(扩展 ListCell 的 NamePriceCell class)时,都会在 TableMain 控制器 class 的静态 StringProperty 中强制转换为字符串的随机数。在这个 class 中,StringProperty 添加了一个 ChangeListener,它依次触发(现在从主控制器内部 - 这就是线索)有序列表的刷新(必须使用添加的项目刷新的列表视图) .
NamePriceCell.java
public class NamePriceCell extends ListCell<ReadItemChoiceObj> {
@FXML
Label namelbl;
@FXML
Label pricelbl;
@FXML
Button plusbtn;
@FXML
Region spacer;
@FXML
HBox cellHbox;
FXMLLoader mLLoader;
ReadItemChoiceObj readitem;
@Override
protected void updateItem(ReadItemChoiceObj readitem, boolean empty) {
super.updateItem(readitem, empty);
if(empty || readitem == null) {
setText(null);
setGraphic(null);
} else {
this.readitem = readitem;
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getResource("fxml/NamePriceCell.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
namelbl.setText(readitem.getname());
namelbl.setMaxWidth(500);
pricelbl.setText(String.format("%.2f", readitem.getprice()));
pricelbl.setStyle("-fx-font: 8pt \"Arial\";");
pricelbl.setMaxWidth(40);
spacer.setMaxWidth(10);
spacer.setMinWidth(10);
plusbtn.setMaxWidth(20);
cellHbox.setHgrow(namelbl, Priority.ALWAYS);
cellHbox.setAlignment(Pos.BASELINE_LEFT);
setText(null);
setGraphic(cellHbox);
plusbtn.setOnMouseClicked(whattodohandler);
}
}
EventHandler<MouseEvent> whattodohandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
OrderItem orderitem = new OrderItem();
orderitem.read_item_name = readitem.getname();
orderitem.read_item_price=readitem.getprice();
orderitem.read_itemID=readitem.getid();
orderitem.choice_name_list = new ArrayList<String>();
orderitem.choice_price_list = new ArrayList<Float>();
orderitem.choice_id_list = new ArrayList<Integer>();
ChosenItemsStat.getplusbtnclicked(orderitem);
Random rand = new Random();
TablesMain.stringProperty.setValue(String.valueOf(rand));
}
};
}
ChosenItemsStat.java(静态 class 接收列表的添加项)
public class ChosenItemsStat {
static ArrayList<OrderItem> chosenorderitemsstat = new ArrayList<>();
static void getplusbtnclicked(OrderItem orderitem){
chosenorderitemsstat.add(orderitem);
}
}
我没有使用 VboxList.fxml 或 VboxListController.java,因为我将其包含在 TablesMain.java 中(见下文)
TablesMain.java(与问题相同,但添加了此内容)
stringProperty = new SimpleStringProperty();
stringProperty.setValue("");
tablelbl.setText(stringProperty.getValue());
stringProperty.addListener(new ChangeListener(){
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
showselectedlist();
}
});
而通过更改 StringProperty 值调用的 showselectedlist() 是下面的那个(在此方法中,单元格的构造与删除的 class (VboxListController)
private void showselectedlist(){
orderitems.addAll(ChosenItemsStat.chosenorderitemsstat);
ChosenItemsStat.chosenorderitemsstat.clear();
ListView<OrderItem> selectedlist = new ListView<>();
ObservableList<OrderItem> myObservableList = FXCollections.observableList(orderitems);
selectedlist.setItems(myObservableList);
selectedlist.setMaxWidth(220);
selectedlist.setCellFactory(new Callback<ListView<OrderItem>, ListCell<OrderItem>>() {
@Override
public ListCell<OrderItem> call(ListView<OrderItem> p) {
ListCell<OrderItem> cell = new ListCell<OrderItem>(){
OrderedCell ordcell= new OrderedCell();
@Override
protected void updateItem(OrderItem orderitem, boolean bln) {
super.updateItem(orderitem, bln);
if (orderitem != null) {
Float price = ordcell.getitemTempPrice(orderitem,orderitem.read_item_price);
HBox namepriceHbox = new HBox();
Label lblprice= new Label(String.format("%.2f",price));
Region betweenregion = new Region();
Label lblname = new Label();
lblname.setText(orderitem.read_item_name );
lblname.setStyle("-fx-font: 10pt \"Arial\";-fx-font-weight:bold");
namepriceHbox.setHgrow(betweenregion, Priority.ALWAYS);
namepriceHbox.getChildren().addAll(lblname,betweenregion,lblprice);
VBox allVbox = new VBox();
Text lblchoices = new Text();
String choices = ordcell.choicestostring(orderitem);
lblchoices.setText(choices);
lblchoices.setWrappingWidth(listpane.getLayoutBounds().getWidth());
if (choices.equals("")) allVbox.getChildren().addAll(namepriceHbox);
else allVbox.getChildren().addAll(namepriceHbox, lblchoices);
double namepricewidth = listpane.getLayoutBounds().getWidth();
System.out.println("namepricewidth is "+String.valueOf(namepricewidth));
//allVbox.setPadding(new Insets(10,0,10,0));
setGraphic(allVbox);
}
}
};
return cell;
}
});
listpane.getChildren().add(selectedlist);
}