问题的核心是我无法从另一个类(此处为NamePriceCell)刷新或更改场景节点(此处为TablesMain)的内容。
我正在使用主StackPane(TableMainController扩展StackPane)构建和应用程序,其中包含其他节点,其中一些是ListView。在一个特定的ListView(比如'readitemslistview')中,我创建了一个自定义ListCell(公共类NamePriceCell extends ListCell),这个NamePriceCell listcell包含一个按钮(plusbtn)。当用户点击plusbtn时,一个arraylist(比如'selecteditemslist')会填满特定单元格中显示的项目,同时堆栈窗口中的另一个listview(比如'ordereditemslist')应该触发显示'selecteditemslist'arraylist的内容。
我还没有找到从主控制器引用NamePriceCell的plusbtn的方法。而且这篇文章 Get ListCell via ListView
不幸的是,现在没有API可以通过索引获取List Cell 获取ListView的所有子项(listcells)。
让我远离了这种尝试(我无法理解那里提供的解决方案是否适合我的需求,因为我不想刷新相同的列表视图而是来自同一场景中的另一个)。
因此,我发现从plusbtn获取鼠标单击操作的唯一方法是使用同一类中的EventHandler(NamePriceCell)。即使我可以根据NamePriceCell按钮的点击(NamePriceCell在另一个类中使用静态arraylist调用静态方法)来填充arraylist,我可以通过让用户点击另一个来获得我的orderedlistview中的结果TableMain StackPane的按钮节点,当用户点击NamePriceCell按钮时,我找不到办法。 我试过的事情是在TablesMainController中设置一个静态方法,我可以从NamePriceCell EventHandler访问它(但是我必须使ordereditemslist的holder节点静态,即便如此,它还没有工作), 为包含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());
}
...
}
答案 0 :(得分:1)
由于已经差不多5个月没有其他贡献,我想发布我的解决方案作为答案。这不是我的,而是受到我的问题中提到的帖子的启发(或复制)(或另一个,现在我不记得了,请原谅我可能的错误信用)。 更准确地说,我在TableMain文件(主要的Controller类)中创建了一个静态StringProperty。每次点击plusbtn(扩展ListCell的NamePriceCell类)时,在TableMain控制器类的静态StringProperty中强制转换为字符串的随机数。在这个类中,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(接收列表添加内容的静态类)
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()是下面的那个(在此方法中,单元格正在被删除的类中被构造(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);
}