- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想在 JavaFX 中创建一个简单的可重用自定义控件,它只不过是 ComboBox
头上有一个标签,可以设置文本。
我希望它可以在 JavaFX Scene Builder 中使用。
我还希望它能够采用单个通用参数 <T>
能够尽可能模仿标准的行为 ComboBox
这是可用的。
我遇到的问题是,当我尝试将控制 Controller 设置为Controller<T>
时在 SceneBuilder 中,我收到一条错误消息:Controller<T> is invalid for Controller class
.
当您调用 FXMLLoader.load()
时,这是有道理的(在设置根、类加载器和位置之后),(我可以找到)没有办法告诉加载器“哦,这是一个自定义控件。”
这是我的控件代码:
public class LabeledComboBox<T> extends VBox {
private final LCBController<T> Controller;
public LabeledComboBox(){
this.Controller = this.Load();
}
private LCBController Load(){
final FXMLLoader loader = new FXMLLoader();
loader.setRoot(this);
loader.setClassLoader(this.getClass().getClassLoader());
loader.setLocation(this.getClass().getResource("LabeledComboBox.fxml"));
try{
final Object root = loader.load();
assert root == this;
} catch (IOException ex){
throw new IllegalStateException(ex);
}
final LCBController ctrlr = loader.getController();
assert ctrlr != null;
return ctrlr;
}
/*Methods*/
}
这是 Controller 类:
public class LCBController<T> implements Initializable {
//<editor-fold defaultstate="collapsed" desc="Variables">
@FXML private ResourceBundle resources;
@FXML private URL location;
@FXML private Label lbl; // Value injected by FXMLLoader
@FXML private ComboBox<T> cbx; // Value injected by FXMLLoader
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Initialization">
@Override public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
this.location = fxmlFileLocation;
this.resources = resources;
//<editor-fold defaultstate="collapsed" desc="Assertions" defaultstate="collapsed">
assert lbl != null : "fx:id=\"lbl\" was not injected: check your FXML file 'LabeledComboBox.fxml'.";
assert cbx != null : "fx:id=\"cbx\" was not injected: check your FXML file 'LabeledComboBox.fxml'.";
//</editor-fold>
}
//</editor-fold>
/*Methods*/
}
显然我在这里缺少一些东西。我真的希望这是可能的,而不必提出我自己的 FXMLLoader 类实现(真的,真的,真的真的希望)。
有人可以告诉我我缺少什么吗,或者这是否可能?
在有人向我指出一个链接后,我可能知道如何做到这一点,但我仍然没有百分百了解。对我来说,感觉 Controller 类本身无法使用通用参数创建(即:public class Controller<T>{...}
= 不好)这有点烦人,但我想这是有道理的。
那么如何将通用参数应用于自定义控件 Controller 内的方法,并使控件本身(而不是 Controller )成为通用的:就像这样?
控制:
public class LabeledComboBox<T> extends VBox {...}
Controller :
public class LCBController implements Initializable {
/*Stuff...*/
/**
* Set the ComboBox selected value.
* @param <T>
* @param Value
*/
public <T> void setValue(T Value){
this.cbx.setValue(Value);
}
/**
* Adds a single item of type T to the ComboBox.
* @param <T> ComboBox Type
* @param Item
*/
public <T> void Add(T Item){
this.cbx.getItems().add(Item);
}
/**
* Adds a list of items of type T to the ComboBox.
* @param <T> ComboBox Type
* @param Items
*/
public <T> void Add(ObservableList<T> Items){
this.cbx.getItems().addAll(Items);
}
/**
* Removes an item of type T from the ComboBox.
* @param <T> ComboBox Type
* @param Item
* @return True if successful(?)
*/
public <T> boolean Remove(T Item){
return this.cbx.getItems().remove(Item);
}
}
这行得通吗?这是否更符合正确的轨道?再说一次,我的愿望只不过是一个带有标签的组合框,告诉用户它的全部内容。
最佳答案
这对我有用,当我将库导入到 SceneBuilder 中时,它工作得很好:
(非常基本)FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ComboBox?>
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="VBox"
fx:controller="application.LabeledComboBoxController">
<Label fx:id="label" />
<ComboBox fx:id="comboBox" />
</fx:root>
Controller :
package application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.SingleSelectionModel;
public class LabeledComboBoxController<T> {
@FXML
private Label label ;
@FXML
private ComboBox<T> comboBox ;
public void setText(String text) {
label.setText(text);
}
public String getText() {
return label.getText();
}
public StringProperty textProperty() {
return label.textProperty();
}
public ObservableList<T> getItems() {
return comboBox.getItems();
}
public void setItems(ObservableList<T> items) {
comboBox.setItems(items);
}
public boolean isWrapText() {
return label.isWrapText();
}
public void setWrapText(boolean wrapText) {
label.setWrapText(wrapText);
}
public BooleanProperty wrapTextProperty() {
return label.wrapTextProperty();
}
public SingleSelectionModel<T> getSelectionModel() {
return comboBox.getSelectionModel();
}
}
控制:
package application;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.layout.VBox;
public class LabeledComboBox<T> extends VBox {
private final LabeledComboBoxController<T> controller ;
public LabeledComboBox(ObservableList<T> items, String text) {
controller = load();
if (controller != null) {
setText(text);
setItems(items);
}
}
public LabeledComboBox(ObservableList<T> items) {
this(items, "");
}
public LabeledComboBox(String text) {
this(FXCollections.observableArrayList(), text);
}
public LabeledComboBox() {
this("");
}
private LabeledComboBoxController<T> load() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource(
"LabeledComboBox.fxml"));
loader.setRoot(this);
loader.load();
return loader.getController() ;
} catch (Exception exc) {
Logger.getLogger("LabeledComboBox").log(Level.SEVERE,
"Exception occurred instantiating LabeledComboBox", exc);
return null ;
}
}
// Expose properties, but just delegate to controller to manage them
// (by delegating in turn to the underlying controls):
public void setText(String text) {
controller.setText(text);
}
public String getText() {
return controller.getText();
}
public StringProperty textProperty() {
return controller.textProperty();
}
public boolean isWrapText() {
return controller.isWrapText();
}
public void setWrapText(boolean wrapText) {
controller.setWrapText(wrapText);
}
public BooleanProperty wrapTextProperty() {
return controller.wrapTextProperty();
}
public ObservableList<T> getItems() {
return controller.getItems();
}
public void setItems(ObservableList<T> items) {
controller.setItems(items);
}
public SingleSelectionModel<T> getSelectionModel() {
return controller.getSelectionModel();
}
}
测试代码:
package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
LabeledComboBox<String> comboBox = new LabeledComboBox<String>(
FXCollections.observableArrayList("One", "Two", "Three"), "Test");
root.setTop(comboBox);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
关于JavaFX 自定义控件<T> : Is this possible?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26206632/
我对这个错误很困惑: Cannot implicitly convert type 'System.Func [c:\Program Files (x86)\Reference Assemblies\
考虑这段代码: pub trait Hello { fn hello(&self); } impl Hello for Any { fn hello(&self) {
问题很简单。是否可以构造这样一个类型 T,对于它下面的两个变量声明会产生不同的结果? T t1 = {}; T t2{}; 我已经研究 cppreference 和标准一个多小时了,我了解以下内容:
Intellij idea 给我这个错误:“Compare (T, T) in Comparator cannot be applied to (T, T)” 对于以下代码: public class
任何人都可以告诉我 : n\t\t\t\t\n\t\t\t 在以下来自和 dwr 服务的响应中的含义和用途是什么. \r\n\t\t\t \r\n\t\t\t
让 T 成为一个 C++ 类。 下面三个指令在行为上有什么区别吗? T a; T a(); T a = T(); T 为不带参数的构造函数提供了显式定义这一事实是否对问题有任何改变? 后续问题:如果
Rust中的智能指针是什么 智能指针(smart pointers)是一类数据结构,是拥有数据所有权和额外功能的指针。是指针的进一步发展 指针(pointer)是一个包含内存地
比如我有一个 vector vector > v={{true,1},{true,2},{false,3},{false,4},{false,5},{true,6},{false,7},{true,8
我有一个来自 .xls 电子表格的数据框,我打印了 print(df.columns.values) 列,输出包含一个名为:Poll Responses\n\t\t\t\t\t。 我查看了 Excel
This question already has answers here: What are good reasons for choosing invariance in an API like
指针类型作为类型前缀与在类型前加斜杠作为后缀有什么区别。斜线到底是什么意思? 最佳答案 语法 T/~ 和 T/& 基本上已被弃用(我什至不确定编译器是否仍然接受它)。在向新向量方案过渡的初始阶段,[T
我正在尝试找到一种方法来获取模板参数的基类。 考虑以下类: template class Foo { public: Foo(){}; ~Foo(){};
这是一个让我感到困惑的小问题。我不知道如何描述它,所以只看下面的代码: struct B { B() {} B(B&) { std::cout ::value #include
为什么有 T::T(T&) 而 T::T(const T&) 更适合 copy ? (大概是用来实现move语义的???) 原始描述(被melpomene证明是错误的): 在C++11中,支持了一种新
在 Java 7 中使用 eclipse 4.2 并尝试实现 List 接口(interface)的以下方法时,我收到了警告。 public T[] toArray(T[] a) { ret
假设有三个函数: def foo[T](a:T, b:T): T = a def test1 = foo(1, "2") def test2 = foo(List(), ListBuffer()) 虽
我对柯里化(Currying)和非柯里化(Currying)泛型函数之间类型检查的差异有点困惑: scala> def x[T](a: T, b: T) = (a == b) x: [T](a: T,
考虑一个类A,我如何编写一个具有与相同行为的模板 A& pretty(A& x) { /* make x pretty */ return x; } A pretty(A&& x) {
Eclipse 表示由于泛型类型橡皮擦,类型参数不允许使用 instanceof 操作。 我同意在运行时不会保留任何类型信息。但是请考虑以下类的通用声明: class SomeClass{ T
在 C++14 中: 对于任何整数或枚举类型 T 以及对于任何表达式 expr: 有没有区别: struct S { T t { expr }; }; 和 struct S { T t = { exp
我是一名优秀的程序员,十分优秀!