JavaFx: TableView - unbind all properties - java

I have a TableView and the columns for it I create like this:
TableColumn<Foo,String> fieldColumn=new TableColumn("field");
fieldColumn.setCellValueFactory(data->data.getValue().getFieldProperty());
tableView.add(fieldColumn);
Now I want to destroy my tableView but I want to continue to use all foos. That's why I want to unbind foos' properties from table/column. How to do it?

If you remove the TableColumns, the listeners will be removed during the next layout pass. This allows you to remove the listeners added by the TableView by clearing the columns and calling layout():
Item class for allowing to get the number of listeners to the property
public class Item {
private final Set<Object> listeners = new HashSet<>();
public Item(String value) {
this.value.set(value);
}
private final StringProperty value = new SimpleStringProperty() {
#Override
public void removeListener(ChangeListener<? super String> listener) {
super.removeListener(listener);
listeners.remove(listener);
}
#Override
public void addListener(ChangeListener<? super String> listener) {
super.addListener(listener);
listeners.add(listener);
}
#Override
public void removeListener(InvalidationListener listener) {
super.removeListener(listener);
listeners.remove(listener);
}
#Override
public void addListener(InvalidationListener listener) {
super.addListener(listener);
listeners.add(listener);
}
};
public final StringProperty valueProperty() {
return this.value;
}
public int getListenerCount() {
return listeners.size();
}
}
Text Application
private void printListenerCount(String message) {
System.out.println(message + tableView.getItems().stream().mapToInt(Item::getListenerCount).sum());
}
private TableView<Item> tableView;
#Override
public void start(Stage primaryStage) {
tableView = new TableView<>();
tableView.getItems().addAll(new Item("a"), new Item("b"), new Item("c"));
TableColumn<Item, String> column = new TableColumn<>();
column.setCellValueFactory(cd -> cd.getValue().valueProperty());
tableView.getColumns().add(column);
Button btn = new Button("print listener count");
btn.setOnAction((ActionEvent event) -> {
printListenerCount("listeners: ");
});
Button btn2 = new Button("clear columns");
btn2.setOnAction(evt -> {
tableView.getColumns().clear();
// do layout to remove the listeners added for the columns
tableView.layout();
printListenerCount("after clear columns: ");
});
Scene scene = new Scene(new VBox(tableView, btn, btn2));
primaryStage.setScene(scene);
primaryStage.show();
}
Pressing the print listener count and then the clear columns buttons will result in the following output:
listeners: 3
after clear columns: 0

Related

JavaFX - How to disable TreeTableView column or Cell children Node on Button Click

I have JFXTreeTableView which consist of 5 columnsx In that first 2 columns have Delete & Edit Buttons for each cell. After populating table
I want first columns should disable on save Button click.
If above case is not possible then delete Buttons inside first column's cells should be disabled on Save button click.
I did like this but dont know how to disable column or buttons inside cells.
Controller Class
public class FinanceActionsController implements Initializable {
#FXML
private JFXTreeTableView<InvoiceItems> tblInvoiceItemsView;
private JFXButton btnSave;
#FXML
private HBox hbBottonBtnBar;
ObservableList<InvoiceItems> invoiceItems = FXCollections.observableArrayList();
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
tableStructure();
btnSave.setOnAction((ActionEvent event) -> {
if (invoiceItems.isEmpty()) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Please add Atleast one Invoice Item");
alert.showAndWait();
} else {
onClickBtnSaveInvoice();
disableAndAddControlsOnSave();
//tblInvoiceItemsView.setDisable(true);
}
});
}
private void tableStructure() {
JFXTreeTableColumn<InvoiceItems, Boolean> delItem = new JFXTreeTableColumn<>("Delete");
JFXTreeTableColumn<InvoiceItems, String> editItem = new JFXTreeTableColumn<>("Edit");
JFXTreeTableColumn<InvoiceItems, String> billItem = new JFXTreeTableColumn<>("Billable Head");
delItem.setCellValueFactory((TreeTableColumn.CellDataFeatures<InvoiceItems, Boolean> param) -> param.getValue().getValue().getBtnFlag());
delItem.setCellFactory(new Callback<TreeTableColumn<InvoiceItems, Boolean>, TreeTableCell<InvoiceItems, Boolean>>() {
#Override
public TreeTableCell<InvoiceItems, Boolean> call(TreeTableColumn<InvoiceItems, Boolean> param) {
final TreeTableCell<InvoiceItems, Boolean> cell = new TreeTableCell<InvoiceItems, Boolean>() {
MaterialIconView del = new MaterialIconView(MaterialIcon.DELETE_FOREVER, "1.5em");
final JFXButton btnDel = new JFXButton("", del);
#Override
public void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
btnDel.disableProperty().bind(txtN.disableProperty());
del.setFill(Color.RED);
btnDel.setButtonType(JFXButton.ButtonType.RAISED);
btnDel.setOnAction(event -> {
});
setGraphic(btnDel);
setText(null);
}
}
};
return cell;
}
});
billItem.setCellValueFactory((TreeTableColumn.CellDataFeatures<InvoiceItems, String> param) -> param.getValue().getValue().getBillItemDesc());
final TreeItem<InvoiceItems> root = new RecursiveTreeItem<>(invoiceItems, RecursiveTreeObject::getChildren);
tblInvoiceItemsView.getColumns().setAll(delItem, editItem, billItem);
tblInvoiceItemsView.setRoot(root);
tblInvoiceItemsView.setShowRoot(false);
}
Class InvoiceItems -
class InvoiceItems extends RecursiveTreeObject<InvoiceItems> {
StringProperty billItemDesc;
BooleanProperty btnFlag;
public InvoiceItems(String billItemDesc) {
this.billItemDesc = new SimpleStringProperty(billItemDesc);
}
public StringProperty getBillItemDesc() {
return billItemDesc;
}
public BooleanProperty getBtnFlag() {
return btnFlag;
}
public void setBtnFlag(Boolean btnFlag) {
this.btnFlag = new SimpleBooleanProperty(btnFlag);
}
}
I have tried to pass InvoiceItems setBtnFlag as True in Observable list to work in setCellFactory's updateItem method but not working. Please help any help will be appreciable, Thank You.

How to detect a tableview items count resize in JavaFx?

I am trying to filter and show items count with FX Tableview.
There are some buttons and txt field for listing a spesific data
here is
text input: filtering
clear button: gettingenter code here default values
this month button: getting this month values
data picker: for getting any day values
There is a label for showing table items size
public Label lblRecordSize;
My problem;
i don't want to lblRecordSize.settext() under the every action for filtering.
Is there a listener like tableview.onItemSizeChangeListener() etc.
UPDATED:
public class CenterDbController implements Initializable {
public AnchorPane centerDbPanelPane;
/** */
public TextField txtSerialNo;
public ComboBox<EModemModel> cbxModemModel;
public Label lblRecordSize;
public DatePicker dpStartDate;
public DatePicker dpEndDate;
public Button btnShow;
public Button btnClear;
/** */
public TableView<RecordedTest> tblvRecords;
public TableColumn colRecordId;
public TableColumn colOfficeId;
public TableColumn colCompany;
public TableColumn colModemSerialNumber;
public TableColumn colModemBrand;
public TableColumn colModemModel;
public TableColumn colSoftwareVersion;
public TableColumn colAccessTest;
public TableColumn colSoftwareTest;
public TableColumn colDhcpTest;
public TableColumn colWifiTest;
public TableColumn colInternetTest;
public TableColumn colResetTest;
public TableColumn colTestResult;
public TableColumn colSendStatus;
public TableColumn colRecordDate;
public TableColumn colTestDetails;
/** */
private IRecordedTestService recordedTestService;
private FilteredList<RecordedTest> filteredList;
#Override
public void initialize(URL location, ResourceBundle resources) {
initCellFactories();
recordedTestService = UtilsForSpring.getSingleBeanOfType(IRecordedTestService.class);
filteredList = new FilteredList<>(FXCollections.observableList(recordedTestService.getThisMonthRecords()), s -> true);
tblvRecords.setItems(filteredList);
lblRecordSize.textProperty().bind(Bindings.size(tblvRecords.getItems()).asString("%s"));
// lblRecordSize.setText(filteredList.size() + "");
filteredList.addListener(new ListChangeListener<RecordedTest>() {
#Override
public void onChanged(Change<? extends RecordedTest> c) {
// lblRecordSize.setText(filteredList.size() + "");
}
});
cbxModemModel.getItems().addAll(EModemModel.values());
}
private void initCellFactories() {
colRecordId.setCellValueFactory(new PropertyValueFactory<RecordedTest, String>("recordId"));
colOfficeId.setCellValueFactory(new PropertyValueFactory<>("officeId"));
colCompany.setCellValueFactory(new PropertyValueFactory<>("company"));
colModemSerialNumber.setCellValueFactory(new PropertyValueFactory<>("modemSerialNumber"));
colModemBrand.setCellValueFactory(new PropertyValueFactory<>("modemBrand"));
colModemModel.setCellValueFactory(new PropertyValueFactory<>("modemModel"));
colSoftwareVersion.setCellValueFactory(new PropertyValueFactory<>("softwareVersion"));
colAccessTest.setCellValueFactory(new PropertyValueFactory<>("accessTest"));
colSoftwareTest.setCellValueFactory(new PropertyValueFactory<>("softwareTest"));
colDhcpTest.setCellValueFactory(new PropertyValueFactory<>("dhcpTest"));
colWifiTest.setCellValueFactory(new PropertyValueFactory<>("wifiTest"));
colInternetTest.setCellValueFactory(new PropertyValueFactory<>("internetTest"));
colResetTest.setCellValueFactory(new PropertyValueFactory<>("resetTest"));
colTestResult.setCellValueFactory(new PropertyValueFactory<>("testResult"));
colSendStatus.setCellValueFactory(new PropertyValueFactory<>("sendStatus"));
colRecordDate.setCellValueFactory(new PropertyValueFactory<>("recordDate"));
colTestDetails.setCellValueFactory(new PropertyValueFactory<>("testDetails"));
}
public void btnClearOnClickAction(ActionEvent e) {
txtSerialNo.clear();
cbxModemModel.getSelectionModel().clearSelection();
dpEndDate.setValue(null);
dpStartDate.setValue(null);
filteredList = new FilteredList<>(FXCollections.observableList(recordedTestService.getThisMonthRecords()), s -> true);
tblvRecords.setItems(filteredList);
// lblRecordSize.setText(filteredList.size() + "");
}
public void btnShowOnClickAction(ActionEvent e) {
if (dpStartDate.getValue() != null && dpEndDate != null) {
filteredList = new FilteredList<>(FXCollections.observableList(recordedTestService.getBetweenRecords(dpStartDate.getValue(), dpEndDate.getValue())));
tblvRecords.setItems(filteredList);
}
}
public void tableOnSortListener() {
// lblRecordSize.setText(tblvRecords.getItems().size() + "");
}
public void txtSerialNoOnKeyPress() {
txtSerialNo.textProperty().addListener(observable -> {
String filter = txtSerialNo.getText();
if (filter == null || filter.length() == 0) {
filteredList.setPredicate(s -> true);
} else {
filteredList.setPredicate(s -> s.getModemSerialNumber().contains(filter));
}
});
}
public void cbxModemModelOnValueChange() {
String filter = cbxModemModel.getSelectionModel().getSelectedItem().toString();
if (filter == null || filter.length() == 0) {
filteredList.setPredicate(s -> true);
} else {
filteredList.setPredicate(s -> s.getModemModel().equalsIgnoreCase(filter));
}
}
}
The Bindings class provides a size method that allows you to create a binding for the size of a ObservableList. Assuming you modify the existing list and do not replace it with a new one every time you filter (e.g. using FilteredList), you can use this to bind the Label text:
// after assigning the items
lblRecordSize.textProperty().bind(Bindings.size(tableview.getItems()).asString("Record count: %s"));
Edit
In your code you replace the items list. The prequesite of the items not being replaced is not given...
You could add a listener to the item property instead and rebind the Label text every time
// before setting items the first time
tblvRecords.itemsProperty().addListener((observable, oldItems, newItems) ->
lblRecordSize.textProperty().bind(
Bindings.size(newItems).asString()));
However you could also modify a single list to contain the source data instead of recreating the lists every time:
private final ObservableList<RecordedTest> data = FXCollections.observableArrayList();
private final FilteredList<RecordedTest> filteredList = new FilteredList<>(data);
#Override
public void initialize(URL location, ResourceBundle resources) {
initCellFactories();
recordedTestService = UtilsForSpring.getSingleBeanOfType(IRecordedTestService.class);
filteredList.setPredicate(null);
data.setAll(recordedTestService.getThisMonthRecords());
tblvRecords.setItems(filteredList);
lblRecordSize.textProperty().bind(Bindings.size(filteredList).asString());
...
}
...
public void btnClearOnClickAction(ActionEvent e) {
...
filteredList.setPredicate(null);
data.setAll(recordedTestService.getThisMonthRecords()));
}

menu items and modal windows are multiplying every time I open them

I've created a vaadin table. When I do right-click it shows context menu with +New... text and when I click on it - it shows modal window with two tables. Every table has the same fuctionality.
The problem is that every time I open and close modal window it adds duplicates for context menu items on modal tables(on the main page it works correct). Moreover - it adds several modal windows when I click on modal table context menu (for example if I open window 5 times - it add 5 context menu items and 5 modal windows for clicked modal context menus)
The only way to return to one item - restart whole application.
What is the problem?
Every my table looks like this
#Component("taskTable")
#Scope("prototype")
public class TaskTable extends AbstractObjectTable {
#Autowired
private TaskService taskService;
#Autowired
private NewTaskWindow taskWindow;
#Autowired
private ShowTaskDetailsWindow detailsWindow;
private Action[] action = new Action[] { new Action("+New...") };
#Override
public Table createTable() {
caption = "Tasks";
headers = new String[] { "Description", "Project", "Status", "Weight", "Developer", "ID" };
this.addActionHandler(new Handler() {
#Override
public Action[] getActions(Object target, Object sender) {
return action;
}
#Override
public void handleAction(Action action, Object sender, Object target) {
switch(action.getCaption()) {
case "+New...": {
PmcUi.getCurrent().addWindow(taskWindow.createWindow());
break;
}
}
//what to do for action
}
});
this.addItemClickListener(new ItemClickListener(){
#Override
public void itemClick(ItemClickEvent event) {
if (event.isDoubleClick()) {
PmcUi.getCurrent().addWindow(detailsWindow.createWindow());
}
return;
}
});
return super.createTable();
}
#Override
protected IndexedContainer projectDatasource() {
IndexedContainer indexedContainer = new IndexedContainer();
for(String header: headers) {
indexedContainer.addContainerProperty(header, String.class, "");
}
List<Task> tasks = taskService.findAllTasks();
for(int i = 0; i < tasks.size(); i++) {
Object id = indexedContainer.addItem();
Task item = tasks.get(i);
indexedContainer.getContainerProperty(id, headers[0]).setValue(item.getDescription());
indexedContainer.getContainerProperty(id, headers[1]).setValue(item.getTaskProject());
indexedContainer.getContainerProperty(id, headers[2]).setValue(item.getStatus());
indexedContainer.getContainerProperty(id, headers[3]).setValue(item.getWeight());
indexedContainer.getContainerProperty(id, headers[4]).setValue(item.getTaskDeveloper());
indexedContainer.getContainerProperty(id, headers[5]).setValue(item.getTaskId());
}
return indexedContainer;
}
}
Where AbstractObjectTable
public abstract class AbstractObjectTable extends Table {
protected String caption;
protected String[] headers = null;
protected Table createTable() {
this.setContainerDataSource(projectDatasource());
this.setVisibleColumns(headers);
this.setSelectable(true);
this.setImmediate(true);
return this;
}
protected abstract IndexedContainer projectDatasource();
}
My +New... modal windows looks similar to that
#Component("newTaskWindow")
public class NewTaskWindow {
private Window createTaskWindow;
#Autowired
private TaskService taskService;
public Window createWindow() {
createTaskWindow = new Window("New Task");
initWindow();
fillWindow();
return createTaskWindow;
}
private void initWindow() {
createTaskWindow.setSizeUndefined();
createTaskWindow.setResizable(false);
createTaskWindow.setModal(true);
createTaskWindow.addCloseListener(new CloseListener() {
#Override
public void windowClose(CloseEvent e) {
Notification.show("Closed");
}
});
}
private void fillWindow() {
final TextField taskDescription = new TextField("Description");
final ComboBox taskProject = new ComboBox("Select project");
final ComboBox taskDeveloper = new ComboBox("Select developer");
final TextField taskWeight = new TextField("Task weight");
final TextField taskStatus = new TextField("Task status");
Button create = new Button("Create");
create.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
Task task = new Task();
task.setTaskId(UUID.randomUUID().toString());
task.setStatus(taskStatus.getValue());
task.setTaskDeveloper(taskDeveloper.getValue().toString());
task.setTaskProject(taskProject.getValue().toString());
task.setWeight(taskWeight.getValue());
task.setDescription(taskDescription.getValue());
taskService.insertTask(task);
createTaskWindow.close();
}
});
Button close = new Button("Cancel");
close.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
createTaskWindow.close();
}
});
HorizontalLayout layout = new HorizontalLayout(create, close);
FormLayout formLayout = new FormLayout(taskProject, taskDeveloper, taskWeight, taskStatus,
taskDescription, layout);
formLayout.setMargin(true);
createTaskWindow.setContent(formLayout);
}
}
And my details windows also have similar architecture.
#Component("showTaskDetailsWindow")
public class ShowTaskDetailsWindow {
private Window showDetailsWindow;
#Autowired
private TaskService taskService;
public Window createWindow() {
showDetailsWindow = new Window("Show details");
initWindow();
fillWindow();
return showDetailsWindow;
}
private void initWindow() {
showDetailsWindow.setSizeUndefined();
showDetailsWindow.setResizable(false);
showDetailsWindow.setModal(true);
showDetailsWindow.addCloseListener(new CloseListener() {
#Override
public void windowClose(CloseEvent e) {
Notification.show("Closed");
}
});
}
private void fillWindow() {
final TextField taskDescription = new TextField("Description");
final TextField taskProject = new TextField("Task project");
final TextField taskDeveloper = new TextField("Task developer");
final TextField taskWeight = new TextField("Task weight");
final TextField taskStatus = new TextField("Task status");
FormLayout formLayout = new FormLayout(taskProject, taskDeveloper, taskWeight, taskStatus, taskDescription);
formLayout.setMargin(true);
showDetailsWindow.setContent(formLayout);
}
}
What is the problem? Why it is continuously multiplying?
The problem is your getActions implementation
#Override
public Action[] getActions(Object target, Object sender) {
return new Action[] { new Action("+New...")};
}
You should create one instance of the "new Action("+New...")" item and store it for example in the TaskTable object.
The getActions(..) should alsways return the same instance.
If you always create a new action, it just adds them to the already existing actions.
Looks like the createTable() method of the TaskTable class is called too many times but the provided code doesn't show where that method is called. That causes that multiple action handlers and item click listeners are added to a table.

Adding different buttons to TableView

I have discovered how to insert a button inside a row's TableView but I'm not sure how could I add different values for that button:
column
.setCellFactory(new Callback<TableColumn<GuiObject, Boolean>, TableCell<GuiObject, Boolean>>() {
#Override
public TableCell<GuiObject, Boolean> call(
TableColumn<GuiObject, Boolean> p) {
return new ButtonCell();
}
});
Where ButtonCell is self implemented button for TableCell<GuiObject, Boolean>, but I want to be able to dynamically insert different buttons dependent on the row I am inserting.
If you access the TableView from java like this:
#FXML
TableView myTable;
#Override
public void initialize(URL url, ResourceBundle rb) {
TableColumn<Item, String> firstColumn = new TableColumn<>("First Column");
firstColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Item, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Item, String> p) {
return new ReadOnlyObjectWrapper(p.getValue().column1);
}
});
TableColumn<Item, String> secondColumn = new TableColumn<>("Second Column");
secondColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Item, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Item, String> p) {
return new ReadOnlyObjectWrapper(p.getValue().column2);
}
});
TableColumn<Item, Button> buttonCol = new TableColumn<>("ButtonColumn");
buttonCol.setSortable(false);
buttonCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Item, Button>, ObservableValue<Button>>() {
#Override
public ObservableValue<Button> call(TableColumn.CellDataFeatures<Item, Button> features) {
return new ReadOnlyObjectWrapper(features.getValue().button);
}
});
myTable.getColumns().add(buttonCol);
myTable.getColumns().add(firstColumn);
myTable.getColumns().add(secondColumn);
myTable.getItems().add(new Item("Test 1", "Test 1", new Button("Test 1"), new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
//ON ACTION CODE HERE
System.out.println("TEST 1 CLICKED!");
}
}));
myTable.getItems().add(new Item("Test 2", "Test 2", new Button("Test 2"), new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
//ON ACTION CODE HERE
System.out.println("TEST 2 BUTTON CLICKED");
}
}));
}
And the Item class:
public class Item {
public String column1, column2;
public Button button;
public Item(String column1, String column2, Button b) {
this.column1 = column1;
this.column2 = column2;
button = b;
}
}
Proof it works:
I fixed my final issue thanks to the code from Cobbles. I simply added a method addAddButton() which adds a button for new row and provides the functionality for the existing objects of type Item:
private void addAddButton() {
Button b = new Button(" + ");
final Item item = new Item(="<new>",
"<new>", b);
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
Button deleteButton = new Button(" - ");
deleteButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
selectedItems.remove(item); // a predefined list of selected items
myTable.getItems().clear();
for (Item current : selectedItems) {
myTable.getItems().add(current);
}
addAddButton();
}
});
item.setButton(deleteButton);
selectedItems.add(item);
myTable.getItems().clear();
for (Item current : selectedItems) {
myTable.getItems().add(current);
}
addAddButton();
}
});
tableAvailabilites.getItems().add(ga1);
}
It is not super efficient yet, but it is working!

JavaFX custom component get action from button in custom component

I want to get the event of two buttons in my custom component.
the component is a imageview with two buttons to move between images, but I need to get the position of the image that is currently displayed, Im storing the key of the image, but I need to know when a button have been pressed outside the custom component, so I can change a Label outside the custom component.
public class TransitionSlider extends AnchorPane {
#FXML
private AnchorPane transitionSliderPane;
#FXML
private ImageView transitionSliderImageView;
#FXML
private Button prevButton;
#FXML
private Button nextButton;
private Map<Integer,Image> imageMap;
private Image currentImage;
private DropShadow imageViewDropShadow;
private int currentKey = 1;
private Image[] images;
public TransitionSlider() {
FXMLLoader loader = new FXMLLoader();
loader.setRoot(this);
loader.setController(this);
loader.setLocation(this.getClass().getResource("TransitionSlider.fxml"));
loader.setClassLoader(this.getClass().getClassLoader());
try {
loader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
prevButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
if(currentKey <= 1){
currentKey = currentKey + 1;
currentImage = imageMap.get(currentKey);
createTransition(transitionSliderImageView, currentImage);
}
}
});
nextButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
if(currentKey <= imageMap.size()){
currentKey = currentKey - 1;
currentImage = imageMap.get(currentKey);
createTransition(transitionSliderImageView, currentImage);
}
}
});
}
// more code here...
}
I want a way to capture the event and get variables inside the component and change a label outside the custom component...
for example:
public class Gallery extends Application {
#FXML
TransitionSlider ts;
Label label;
#Override
public void start(Stage stage) throws Exception {
label = new Label();
TransitionSlider ts = new TransitionSlider();
ts.captureButtonEvent(){ // need a way to capture this
label.setText(ts.getCurrentKey());
}
// more code here....
}
If I understood your question correctly, you want a binding.. Follow these steps:
1) Put bindable field and its getter/setter into TransitionSlider:
private IntegerProperty currentKey = new SimpleIntegerProperty(1);
public int getCurrentKey() {
return currentKey.get();
}
public void setCurrentKey(int val) {
return currentKey.set(val);
}
public IntegerProperty currentKeyProperty() {
return currentKey;
}
2) Bind this property to label's text in Gallery:
label = new Label();
TransitionSlider ts = new TransitionSlider();
label.textProperty.bind(ts.currentKeyProperty().asString());
Alternatively, if you want to do stuff more than just changing label's text, you can add a change listener to currentKeyProperty:
ts.currentKeyProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue) {
label.setText(newValue);
// do other stuff according to "oldValue" and "newValue".
}
});

Categories