How to set a tableview in JavaFX in initialize method - tableview

Hi I'm new to JavaFX and want to populate a tableview with data
I use not the programmatic way I create the tableview with scene builder and have a controller file . I have a data file for the getters and setters already and created a observable list
public class Controller implements Initializable {
#FXML TableView<Bew> tableV;
#FXML TableColumn<Bew, String> nameCol =new TableColumn<>("Name");
#FXML TableColumn<Bew, String> dateCol =new TableColumn<>("Datum");
#FXML TableColumn<Bew, String> actionCol =new TableColumn<>("Aktivität");
#FXML TableColumn<Bew, String> infoCol =new TableColumn<>("Info");
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
SQLiteDB DB = new SQLiteDB();
ObservableList<Bew> list = DB.getData();
tableV.setItems(list);
}
public ObservableList<Bew> getData() {
ObservableList<Bew> bewList = FXCollections.observableArrayList();
bewList.add(new Bew("Rita", "01.12.1920", "Gespräch", "gud"));
bewList.add(new Bew("Marc", "14.03.1930", "Spaziergang", "gud"));
bewList.add(new Bew("Peter", "27.01.1901", "dfdsfdsfdsfdsf", "gud"));
bewList.add(new Bew("John", "12.12.1912", "dfdsfdsfdsfdsf", "gud"));
return bewList;
}
When I run the code no error appears but no data in tableview
Any help?

Related

Can i create a list using a renderer in Hybris?

I have a renderer with one object(OrderEntryModel) that contains a list of objects and i want to create a list in backoffice with that objects(OrderEntryItemModel). It can be possible?
public class *Renderer implements WidgetComponentRenderer<Listcell, ListColumn, OrderEntryModel> {
#Override
public void render(final Listcell listcell, final ListColumn configuration, final OrderEntryModel orderEntryModel,
final DataType dataType, final WidgetInstanceManager widgetInstanceManager) {
}

Vaadin Spring Boot #autowired field returns null in a view

First off, please excuse my question due to my being new to spring boot ecosystem. In my application, I've a vaadin page, where I want to submit user details to DB, using repository. In my view class, I've added them as #autowired fields, however, during the runtime, I see that their values are run so the operation fails. I know that to benefit from #autowired, the instances should not be created newly during constructing but I couldn't figure out how I should do it on my own. Here are my classes:
#SuppressWarnings("serial")
public class LoginAwareComposite extends Composite<Div> {
#Autowired
private ApplicationEventPublisher publisher;
public LoginAwareComposite() {
}
#Override
protected void onAttach(AttachEvent event) {
super.onAttach(event);
UserCredentials userPrincipal = UI.getCurrent().getSession().getAttribute(UserCredentials.class);
if (userPrincipal != null) {
// --- NOT LOGGED IN
UI.getCurrent().navigate(AddressBookManagementView.class);
}
}
}
#SuppressWarnings("serial")
#Route(value = "account")
#Theme(value = Lumo.class, variant = Lumo.LIGHT)
public class AddressBookManagementView extends LoginAwareComposite {
private VerticalLayout pageLayout = new VerticalLayout();
public AddressBookManagementView() {
getContent().setSizeFull();
getContent().add(initPage());
}
private Component initPage() {
pageLayout.getStyle().set("padding-left", "0px");
pageLayout.getStyle().set("padding-bottom", "0px");
pageLayout.getStyle().set("padding-right", "0px");
pageLayout.getStyle().set("overflow", "auto");
pageLayout.setSizeFull();
pageLayout.add(new HeaderLayout(), new BodyLayout(), new FooterLayout());
return pageLayout;
}
}
#SuppressWarnings("serial")
#SpringComponent
public class BodyLayout extends VerticalLayout {
// some fields
#Autowired
EmailRepository emailRepository;
#Autowired
FaxRepository faxRepository;
public BodyLayout() {
init(); //this function inits the view, and eventually inits the on click event for submit button , which then calls my function
}
private void myFunction() {
//here i use the repository entities but they do return null although they are autowired
}
So what happens is, in BodyLayout's constructor we call init() function which is used to init the layout and give functionality buttons etc, one of subfunctions inside the init method gives functionality to submit button using myFunction. MyFuction uses the repository entity but it returns null.
Since you are using springboot with vaadin ensure the following :
Make sure that the #Repository annotation is used on your repository interfaces like on EmailRepository.
Try using constructor injection for your repository classes like :
Try like below :
#SuppressWarnings("serial")
#SpringComponent
#UIScope
public class BodyLayout extends VerticalLayout {
// some fields
private final EmailRepository emailRepository;
private final FaxRepository faxRepository;
#Autowired
public BodyLayout(EmailRepository emailRepository, FaxRepository faxRepository) {
this.emailRepository = emailRepository;
this.faxRepository = faxRepository;
init(); //this function inits the view, and eventually inits the on click event for submit button , which then calls my function
}
private void myFunction() {
//here i use the repository entities but they do return null although they are autowired
}
I was able to get it working as follows:
#SuppressWarnings("serial")
#Route(value = "account")
#Theme(value = Lumo.class, variant = Lumo.LIGHT)
#UIScope
#SpringComponent
public class AddressBookManagementView extends LoginAwareComposite {
private VerticalLayout pageLayout = new VerticalLayout();
#Autowired
BodyLayout bodyLayout;
public AddressBookManagementView(BodyLayout bodyLayout) {
this.bodyLayout = bodyLayout;
getContent().setSizeFull();
getContent().add(initPage());
}
private Component initPage() {
pageLayout.getStyle().set("padding-left", "0px");
pageLayout.getStyle().set("padding-bottom", "0px");
pageLayout.getStyle().set("padding-right", "0px");
pageLayout.getStyle().set("overflow", "auto");
pageLayout.setSizeFull();
pageLayout.add(new HeaderLayout(), bodyLayout, new FooterLayout());
return pageLayout;
}
Then BodyLayout is
#SuppressWarnings("serial")
#UIScope
#SpringComponent
public class BodyLayout extends VerticalLayout {
private final EmailRepository emailRepository;
private final FaxRepository faxRepository;
#Autowired
public BodyLayout(EmailRepository emailRepository, FaxRepository faxRepository) {
this.emailRepository = emailRepository;
this.faxRepository = faxRepository;
init();
}
Roughly only #Route, layouts, and the vaadin init listener takes part in automatic dependency injection (that is: the vaadin spring integration asks the spring context to build them). If you do new MyClass() it never takes part in DI. Using field based injection with #Autowired hides this problem - so using constructor based injection is the "industry standard". The other way around is to not build your own instances, if you want to take part in DI but ask the spring context to build an instance for you.

MVC javafx Application, when to inject model

I've got an application which i try to keep the mvc rule. I've got a model
public class CarTableView {
SimpleIntegerProperty id = new SimpleIntegerProperty();
SimpleStringProperty brand = new SimpleStringProperty();
SimpleStringProperty engine = new SimpleStringProperty();
SimpleBooleanProperty navi = new SimpleBooleanProperty();
SimpleBooleanProperty available = new SimpleBooleanProperty();
SimpleDoubleProperty liters = new SimpleDoubleProperty();
SimpleIntegerProperty power = new SimpleIntegerProperty();
ObservableList<CarTableView> observableList = FXCollections.observableArrayList();
public CarTableView()
{
}
public CarTableView(int id,String brand,String engine,Boolean navi,Boolean available,double liters,int power)
{
this.id.set(id);
this.brand.set(brand);
this.engine.set(engine);
this.navi.set(navi);
this.available.set(available);
this.liters.set(liters);
this.power.set(power);
}
Which I need to use in my two controllers in order to get referance to ObservableList. And here is where lie my problem. Where to create the Model? I need him to be created before the initialize() method will invoked
public class MainController {
private CarTableView model = new CarTableView();
#FXML
private Button addVehicleButton;
#FXML
private Button showClientDatabaseButton;
#FXML
public void initialize()
{
(...)
model.getObservableList().add(new CarTableView(213,"FIAT","1.9 JTD",true,true,32.4,132)); // HERE I use model (it's fine here because its created in this class)
tableView.setItems(model.getObservableList());
#FXML
public void addNewVehicleButtonClicked() throws IOException
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/AddNewCar.fxml"));
Stage stage = new Stage();
Scene scene = new Scene((Pane)loader.load());
stage.setScene(scene);
stage.show();
AddNewCarController addNewCarController = loader.getController();
addNewCarController.initData(model); // HERE i try to initialize model in second controller
}
But I need him also in initialize() method from another controller
public class AddNewCarController {
private ObservableList<String> choiceBoxList = FXCollections.observableArrayList("YES","NO");
#FXML
public void initialize()
{
autoIncrementChekBox.setSelected(true);
if(autoIncrementChekBox.isSelected())
{
idTextField.setText(Integer.toString((model.getObservableList().size()+1))); // HERE I NEED HIM TOO!! But it is null... he havent been load yet!
idTextField.setDisable(true);
}
comboBox.setItems(choiceBoxList);
comboBox.setValue("YES");
}
In this situation even if I will pass the data throw function initModel() in second controller. Where I should have create model, and pass to both controller?
I will also add my Main() file to clear situation
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Managment System");
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene((Pane)loader.load(),1800,900);
MainController mainController = loader.getController();
stage.setScene(scene);
stage.show();
}
}
You can create the controller so that the model is passed to the constructor:
public class MainController {
private final CarTableView model ;
public MainController(CarTableView model) {
this.model = model ;
}
// existing code ...
}
To use this version of the controller, do
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Managment System");
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
CarTableView model = new CarTableView();
MainController mainController = new MainController(model);
loader.setController(mainController);
Scene scene = new Scene((Pane)loader.load(),1800,900);
stage.setScene(scene);
stage.show();
}
}
And remove the fx:controller attribute from the FXML file.
You can then do the same when you load the other FXML file, using the same instance of the model.
A related approach is to use a controller factory:
CarTableView model = new CarTableView() ;
Callback<Class<?>, Object> controllerFactory = controllerType -> {
if (controllerType == MainController.class) {
return new MainController(model);
} else {
throw new IllegalStateException("Unexpected controller class: "+controllerType.getName());
}
};
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
loader.setControllerFactory(controllerFactory);
Scene scene = new Scene(loader.load(), 1800, 900);
// ...
In this version, you keep the fx:controller attribute in the FXML file.
The basic idea here is that the controller factory is a function that maps the type of the controller to the controller instance, so you can use the controller factory to configure how the controller is created. You can use reflection to make this reusable (get the constructors for the class, check if any of them take a single parameter whose type is the model type, and invoke that constructor if so, otherwise just invoke the default constructor).
You can also use this technique to use a dependency injection framework such as Spring to create your controllers: see Dependency Injection and JavaFX. This, of course, means you can use Spring to inject the model into the controllers, which becomes very nice.
Finally, note that there is a JavaFX-specific dependency injection framework, afterburner.fx. This basically uses this technique under the hood to allow you to simply use javax.inject annotations directly in the controllers, so you just have to annotate the model in order to automatically inject it. If you have a medium-large scale application with lots of injection required, this is a very good option.

How to bind BeanItemContainer to Combobox

I have BeanItemContainer, which i load from database via jdbc:
BeanItemContainer myBeans = new BeanItemContainer<>(MyBean.class, mybeanDao.findAll());
and this is how i attach it to combobox:
Combobox combo = new Combobox();
combobox.setContainerDataSource(myBeans);
So far, so good. I received what i want, but for now i have a problem -
How do i get actual id that has been selected? This must be synchronized (id selected in combobox is actual entry in database).
I have no idea, how to solve this problem
Please help
P.S MyBean class
public class MyBean {
private Long id;
private String field1;
*** getters /setters ***
and toString() {} method
}
Here is the code:
#Theme("mytheme")
public class MyUI extends UI {
#Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
layout.setSpacing(true);
setContent(layout);
BeanItemContainer myBeans = new BeanItemContainer<>(MyBean.class, getBeans());
ComboBox combo = new ComboBox();
combo.setContainerDataSource(myBeans);
combo.setItemCaptionMode(AbstractSelect.ItemCaptionMode.PROPERTY);
combo.setItemCaptionPropertyId("field");
combo.addValueChangeListener(new Property.ValueChangeListener() {
#Override
public void valueChange(Property.ValueChangeEvent event) {
MyBean bean = (MyBean) combo.getValue();
Notification notif = new Notification("Selected Bean Id: "+bean.getId(), Notification.Type.TRAY_NOTIFICATION);
notif.setPosition(Position.TOP_CENTER);
notif.show(Page.getCurrent());
}
});
layout.addComponent(combo);
}
#WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
public class MyBean {
private Long id;
private String field;
public MyBean(Long id, String field) {
this.id = id;
this.field = field;
}
public Long getId() {
return id;
}
public String getField() {
return field;
}
}
public ArrayList<MyBean> getBeans() {
ArrayList<MyBean> beans = new ArrayList<>();
MyBean bean = new MyBean(1l, "Vikrant");
beans.add(bean);
bean = new MyBean(2l, "Rampal");
beans.add(bean);
bean = new MyBean(3l, "viky");
beans.add(bean);
return beans;
}
}
If I understood the question correctly combo.getValue() should give you the MyBean instance relative to the current selection (or null if no item is selected)

Adding TreeView to a TableCeell in javafx

I need to add a TreeView to each cell in a particular column of a table.I am able to add Strings but I am not able to add TreeView. How can I do this?
This is my NodeInfo class
public class NodeInfo{
private TreeView<String> nodeTree;
private TreeItem<String> root;
private final Image rootIcon=new Image(getClass().getResourceAsStream("/images/nodes.gif"));
private final Image folderIcon=new Image(getClass().getResourceAsStream("/images/folder.gif"));
public void settreeView(String s)
{
nodeTree = new TreeView<>();
nodeTree.setEditable(true);
root = new TreeItem<>("Rootnode", new ImageView(rootIcon));
root.setExpanded(false);
nodeTree.setRoot(root);
for(int i=0;i<3; i++)
{
root.getChildren().add(new TreeItem<>(sharedFolders.get(i), new ImageView(folderIcon)));
}
}
public TreeView<String> gettreeView()
{
return nodeTree;
}
}
And this is controller class for UI
public class GrapevineController implements Initializable {
#FXML
private TableView<NodeInfo> tableView;
#FXML
private TableColumn<NodeInfo, TreeView<String>> nodeTree;
#FXML
private TableColumn<NodeInfo, String> name;
#FXML
private TableColumn<NodeInfo, String> favourite;
#FXML
private TableColumn<NodeInfo, String> updates;
#FXML
public static ObservableList<NodeInfo> sourceTree = FXCollections.observableArrayList();
#Override
public void initialize(URL url, ResourceBundle r){
tableView.setEditable(true);
nodeTree.setCellValueFactory(new PropertyValueFactory<NodeInfo, TreeView<String>> ("treeView"));
name.setCellValueFactory(new PropertyValueFactory<NodeInfo, String>("MacAddress"));
favourite.setCellValueFactory(new PropertyValueFactory<NodeInfo, String>("favourites"));
updates.setCellValueFactory(new PropertyValueFactory<NodeInfo, String>("update"));
tableView.setItems(sourceTree);
}

Resources