Я хочу создать простой настраиваемый элемент управления многократного использования в JavaFX, который представляет собой не что иное, как ComboBox
с меткой над головой, в которой может быть установлен текст.
Я бы хотел, чтобы его можно было использовать в JavaFX Scene Builder.
Я также хотел бы, чтобы он мог использовать один общий параметр <T>
, чтобы иметь возможность как можно точнее имитировать поведение доступного стандартного ComboBox
.
Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь установить Controls Controller на Controller<T>
в SceneBuilder, я получаю сообщение об ошибке: Controller<T> is invalid for Controller class
.
Это имеет смысл, поскольку когда вы вызываете FXMLLoader.load()
(после установки root, classLoader и Location), нет способа (который я могу найти) сказать загрузчику: «О, это CustomControl».
Это код, который у меня есть для Control:
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*/
}
Это класс контроллера:
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 (ДЕЙСТВИТЕЛЬНО, ДЕЙСТВИТЕЛЬНО, ДЕЙСТВИТЕЛЬНО надеясь).
Может ли кто-нибудь сказать мне, что мне не хватает, или возможно ли это?
РЕДАКТИРОВАТЬ 1:
После того, как кто-то указал мне на ссылку, я могу понять, как это сделать, но я все еще не на сто процентов. Мне кажется, что сам класс Controller не может быть создан с помощью универсального параметра (I.E .: public class Controller<T>{...}
= No Good) Это немного раздражает, но, думаю, имеет смысл.
Тогда как насчет применения общих параметров к методам внутри настраиваемого контроллера управления и превращения самого элемента управления (а не контроллера) в универсальный: вот так?
Контроль:
public class LabeledComboBox<T> extends VBox {...}
Контроллер:
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);
}
}
Это сработает? Это больше в правильном направлении? Опять же, мое желание - не что иное, как ComboBox с меткой на нем, чтобы рассказать пользователям, что это такое.
FXMLLoader
в коде Java вместо использования атрибутаfx:controller
в FXML. - person James_D   schedule 06.10.2014