Access objects inside a dinamically created HBox - javafx

In the controller of my view, I created a list of HBoxes for the input of different values, each hbox consists of a textfield with an index number and two text boxes with information I want to retrieve. This is how I dynamically create each HBox.
void addRowToList() {
HBox hb = new HBox(50);
Text num = new Text(Integer.toString(numEdges + 1));
hb.getChildren().add(num);
TextField sep = new TextField();
makeNumeric(sep);
hb.getChildren().add(sep);
TextField area = new TextField();
makeNumeric(area);
hb.getChildren().add(area);
rows.add(hb);
}
After this, there is a point in which I need the information from those textBoxes in order to continue the execution of my program, my question is what is the method should I follow to access these since they don't have any given id? Thanks in advance.

Related

JavaFX: getChildren().addAll() argument not applicable

I have a basic question for JavaFX but coudn't figure it out. For HBox, When I'm using getChildren().addAll() for Label and ImageView, I get the following message:
The method addAll(int, Collection<? extends Node>) in the type List<Node> is not applicable for the argument (Label, ImageView[])
I'm not sure what's the issue. I can use normally if its (TextField, ImageView[]), but it doesn't work for (Label, ImageView[]).
This is my simplified code:
ImageView[] imagesRow = new ImageView[2];
Image[] img = new Image[2];
String title = "Result";
img[0] = new Image("sample1.png", 60, 35, true, true);
img[1] = new Image("sample2.png", 60, 35, true, true);
imagesRow[0] = new ImageView();
imagesRow[1] = new ImageView();
imagesRow[0].setImage (img[0]);
imagesRow[1].setImage (img[1]);
Label label = new Label();
label.setText(title + ": ");
// Create horizontal box
HBox box = new HBox();
box.setPadding(new Insets(20, 5 , 2, 50));
box.getChildren().addAll(label, imagesRow); // issue here
May I seek the reason and what should I do instead to align label and image horizontally?
Thanks in advance.
A Collection needs to be of one type (or inheriting from a common parent somewhere in the heirarchy).
A Label is a type of Node and therefore anything else you try to pass as a part of the Collection parameter must also be a Node. An array is obviously not.
In your case, you would need to use two calls to populate the children of the HBox:
box.getChildren().add(label);
box.getChildren().addAll(imagesRow);
The reason you can call addAll(imagesRow) without a problem is because with only the one argument, you're only passing in one Collection, an array.
By calling addAll(label, imagesRow), you're telling Java that you're passing a Collection of one type, but you actually passed it a Node and an array.

The button in nattable is covering half of my table, can someone explain why?

i have used the following code for the button
natTable.addOverlayPainter(new NatTableBorderOverlayPainter());
Composite panel = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 5;
layout.marginWidth = 8;
panel.setLayout(layout);
GridDataFactory.fillDefaults().grab(true, true).applyTo(panel);
Composite gridPanel = new Composite(panel, SWT.NONE);
gridPanel.setLayout(layout);
GridDataFactory.fillDefaults().grab(true, true).applyTo(gridPanel);
Composite buttonPanel = new Composite(panel, SWT.NONE);
buttonPanel.setLayout(new RowLayout());
GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonPanel);
Button addButton = new Button(gridPanel, SWT.PUSH);
addButton.setText("Export");
addButton.setSize(1, 1);
addButton.setLocation(450, 150);
addButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
natTable.doCommand(new ExportCommand(natTable
.getConfigRegistry(), null, editable));
natTable.updateResize();
}
but at the end i am getting this as a result
https://imgur.com/EFcPaqo
Your layout is broken. Probably because the NatTable instance is not created on one of your Composites. But hard to tell without seeing the creation of it.
Either have a look at Understanding layouts in SWT or even check the NatTable examples PrintExample that shows exactly the same. There you can see that NatTable is created on the gridPanel.

Howto cast List items from VBox.getChildren() in JavaFX

I have a VBox in which many nodes of type Buttonare added.
private final VBox vbox = new VBox();
private final Button b1= new Button("1");
private final Button b2= new Button("2");
private final Button b3= new Button("3");
private final Button b4= new Button("4");
vbox.getChildren().addAll(b1,b2,b3,b4);
Is there a way to cast its child items to Button type.
I need something like this:
ObservableList<Button> children = (ObservableList<Button>) vbox.getChildren();
Yes this is possible, if you use the raw type.
ObservableList<Button> children = (ObservableList)vbox.getChildren();
Note however, that this can easily lead to ClassCastExceptions at runtime, if the types are incorrect or the child list hardcodes the parameter type for a parameter that depends on the type parameter.

(JavaFX) After maximizing the window (stage), i cant select items in the tableview anymore

since my code is quite long, I'll try to only describe the issue first to see if someone has faced it before.
I have a TableView that i populate with various objects which works just fine. I created a context menu so whenever I right-click an Item i can edit certain columns. Everything works fine but when i maximize the window, I cant select any Items anymore by clicking on them.
Has anyone faced that issue before?
Thx for the help!
edit:
I added some lines of code. Im using Java 1.8.
anchorPane = new AnchorPane();
anchorPane.setMaxWidth(550.0);
tabPane = new TabPane();
tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
tabPane.setTabMinHeight(22.0);
tabPane.setPrefWidth(this.navigationWidth);
homeTableView = new TableView<Player>();
homeTableView.setEditable(true);
homeTableView.setContextMenu(homeContextMenu);
List<Player> test= mainWindow.getHomeTeamPlayer();
ObservableList<Player> homeTeamPlayer = FXCollections.observableArrayList(test);
homeTableView.setItems(homeTeamPlayer);
homeTableView.setContextMenu(homeContextMenu);
Field[] fields = Player.class.getDeclaredFields();
for(Field field: fields){
// Get column information from Metadata
ColumnMetadata columnMetadata = field.getAnnotation(ColumnMetadata.class);
if(!columnMetadata.showInTable()) continue;
TableColumn<Player, String> HomeCol = new TableColumn<>(columnMetadata.displayTitle());
HomeCol.setCellValueFactory(new PropertyValueFactory<>(field.getName()));
if(columnMetadata.isEditable()){
HomeCol.setEditable(true);
}
homeTableView.getColumns().add(HomeCol);
}
homeTab = addTab("homename", homeTableView);
AnchorPane.setRightAnchor(tabPane, 0.0);
AnchorPane.setLeftAnchor(tabPane, 0.0);
AnchorPane.setTopAnchor(tabPane, 0.0);
AnchorPane.setBottomAnchor(tabPane, 0.0);
anchorPane.getChildren().addAll(tabPane);
public Tab addTab(String name, TableView tableView){
Tab tab = new Tab();
tab.setText(name);
tab.setContent(tableView);
tabPane.getTabs().addAll(tab);
return tab;
}

JavaFX architecture in building dynamic "rows"

I have an application that I am building that has a table in it, I'm not using a tableview to build this table because I need each row to be able to expand similar to an accordion. I was able to achieve what I need by using a timeline and looping through the data and building each row (its kind of crude right now since I'm still working with dummy data eventually it will be a list iterator and not just a for loop) but I'm not happy with how its done. There are a lot of default values that will never change so I don't really need to set them in my worker class every time, I decided to just add them to the object class that I put together. So basically, at a high level it looks something like this:
for (int i = 0; i < 30; i++) {
RowBuilder builder = new RowBuilder(tableBox, i);
try {
builder.run();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm passing it the parent which is a VBox - tableBox, then I'm passing the count for later use.
Inside the RowBuilder I'm getting a new instance of the object DashboardRow which has all the defaults set in it, then I'm setting the data for each row and returning the DashboardRow.
Here is an example of a getter setting values in the DashboardRow
public HBox getMainRow() {
mainRow.setAlignment(Pos.CENTER_LEFT);
mainRow.setPrefHeight(60);
mainRow.setMinHeight(60);
mainRow.setMaxHeight(60);
mainRow.setPrefWidth(-1);
mainRow.setStyle("-fx-background-color:#FFFFFF;");
return mainRow;
}
Inside the DashboardRow class I have a ton of new objects being created for every element I need in the row. There are 21 for each row, mostly VBox, HBox and StackPane to build the actual row, the rest are just labels and buttons.
This is what is looks like so far. Opened and closed states.
Is there a better way to dynamically build things like this in javafx? I'm basically pulling data from a database and looping through that data to populate a row.
I can't comment but it may be an answer anyway. Why can't you use the setGraphic method of a custom table cell and put the accordion node in a table. setGraphic takes any kind of node.
It sounds simpler than what you're doing.
I just tried it out with the Oracle sample and it works great.
I added
Callback<TableColumn<Person, String>, TableCell<Person, String>> accCellFactory
= new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
#Override
public TableCell call(TableColumn p) {
TitledPane t1 = new TitledPane("T1", new Button("B1"));
TitledPane t2 = new TitledPane("T2", new Button("B2"));
TitledPane t3 = new TitledPane("T3", new Button("B3"));
Accordion accordion = new Accordion();
accordion.getPanes().addAll(t1, t2, t3);
TableCell tc = new TableCell();
tc.setGraphic(accordion);
return tc;
}
};
and changed this line firstNameCol.setCellFactory(accCellFactory);
and I get
Of course you might want something other than buttons but I just copied the Accordion sample from the javadoc.

Resources