问题的核心是我无法从另一个类(在此为NamePriceCell)刷新或更改场景节点(在此为TablesMain)的内容。

我正在使用包含其他节点(其中一些是ListView)的主StackPane(TableMainController扩展了StackPane)构建和应用程序。在特定的ListView中(例如'readitemslistview'),我创建了一个自定义ListCell(公共类NamePriceCell扩展了ListCell),并且此NamePriceCell列表单元包含一个按钮(plusbtn)。当用户单击plusbtn时,数组列表(例如“ chosenitemslist”)被特定单元格中显示的项目填充,同时应触发堆栈窗格中的另一个列表视图(例如“ ordereditemslist”)以显示内容“ chosenitemslist”数组列表的名称。

我还没有找到从主控制器引用NamePriceCell的plusbtn的方法。而且这个帖子
Get ListCell via ListView


  不幸的是,目前没有API可以通过索引或
  获取所有儿童的(listcells)的ListView。


使我无法进行这种尝试(我无法理解那里提供的解决方案是否适合我的需求,因为我不希望刷新相同的列表视图,而是希望刷新同一场景中的另一个列表视图)。

因此,我发现从plusbtn获得鼠标单击操作的唯一方法是使用同一类(NamePriceCell)中的EventHandler。即使我可以根据对NamePriceCell按钮的单击来填充一个数组列表(NamePriceCell在另一个类中带有静态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());
    }

...
}

最佳答案

由于将近5个月没有其他捐款,我想将我的解决方案作为答案。这不是我的,而是由我的问题中提到的帖子(或另一帖子,现在我不记得了,请原谅我可能的学分错放)启发(或复制)的。
更准确地说,我在TableMain文件(主Controller类)中创建了一个静态StringProperty。每次单击plusbtn(扩展ListCell的NamePriceCell类)时,都会在TableMain控制器类的静态StringProperty中强制转换为字符串的随机数。在此类内,StringProperty添加了一个ChangeListener,它依次触发了(从主控制器内部-这就是线索)刷新了orderedlist(必须使用添加的项目来刷新listview)。

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);
}

09-05 09:06