【发布时间】:2017-03-12 13:24:04
【问题描述】:
问题的核心是我无法从另一个类(此处为 NamePriceCell)刷新或更改场景节点(此处为 TablesMain)的内容。
我正在使用包含其他节点的主 StackPane(TableMainController 扩展 StackPane)构建和应用程序,其中一些是 ListViews。在特定的 ListView(比如“readitemslistview”)中,我创建了一个自定义 ListCell(公共类 NamePriceCell 扩展 ListCell),并且这个 NamePriceCell listcell 包含一个按钮(plusbtn)。当用户点击 plusbtn 时,arraylist(比如“chosenitemslist”)会被特定单元格中显示的项目填满,同时堆栈窗格中的另一个列表视图(比如“ordereditemslist”)应该是 em> 触发显示 'chosenitemslist' 数组列表的内容。
我还没有找到从主控制器引用 NamePriceCell 的 plusbtn 的方法。而且这个帖子 Get ListCell via ListView
不幸的是,现在没有 API 可以通过索引或获取 List Cell 获取 ListView 的所有子项(listcells)。
让我远离了这种尝试(我无法理解那里提供的解决方案是否适合我的需求,因为我不想刷新同一个列表视图,而是从同一场景中的另一个)。
因此,我发现从 plusbtn 获得鼠标单击操作的唯一方法是使用同一类 (NamePriceCell) 中的 EventHandler。即使我可以根据对 NamePriceCell 按钮的点击来填充数组列表(NamePriceCell 调用另一个类中的静态方法,其中包含静态数组列表),并且我可以通过让用户单击另一个来在我的有序列表视图中获得结果TableMain StackPane 的按钮节点,当用户单击 NamePriceCell 按钮时,我找不到这样做的方法。 我尝试过的事情之一是在 TablesMainController 中设置一个静态方法,我可以从 NamePriceCell EventHandler 访问它(但是我必须使ordereditemslist的持有者节点静态,即使这样,它也没有工作), 为包含ordereditemslist的VBox编写一个单独的fxml,并使用相应的单独控制器,这样我就可以有一个方法来创建ordereditemslist并设置cellFactory(但即使fxml文件正确显示并从NamePriceCell的EventHandler调用该方法也可以- 显示 System.out - 它不会影响屏幕上的任何内容,而不是有序项目列表,甚至不会影响我测试的标签。
相对而言,我是 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());
}
...
}
【问题讨论】:
-
我得到了 StringProperty 的解决方案,它可以从我的问题中提到的帖子连接到监听器。我知道这不是最好的东西,更像是一个黑客,所以如果有更好的解决方案,请分享。我很乐意接受任何好主意作为答案。