Hi everyone, im trying to show/hide a button in the UI depending on a boolean variable present in the class.
This is the fxml file
<?xml version="1.0" encoding="UTF-8"?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import org.cryptomator.ui.controls.FormattedLabel?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.addvaultwizard.AddVaultSuccessController"
prefWidth="450"
prefHeight="450"
spacing="12"
alignment="TOP_CENTER">
<padding>
<Insets topRightBottomLeft="24"/>
</padding>
<children>
<Region VBox.vgrow="ALWAYS"/>
<StackPane alignment="CENTER" HBox.hgrow="NEVER">
<Circle styleClass="glyph-icon-primary" radius="36"/>
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="CHECK" glyphSize="36"/>
</StackPane>
<Region VBox.vgrow="ALWAYS"/>
<FormattedLabel format="%addvaultwizard.success.nextStepsInstructions" arg1="${controller.vault.displayName}" wrapText="true" HBox.hgrow="ALWAYS"/>
<Region VBox.vgrow="ALWAYS"/>
<ButtonBar buttonMinWidth="120" buttonOrder="+IU">
<buttons>
<Button text="%generic.button.done" ButtonBar.buttonData="FINISH" onAction="#close" defaultButton="${!controller.vault.locked}"/>
<Button text="%addvaultwizard.success.unlockNow" ButtonBar.buttonData="OTHER" onAction="#unlockAndClose" defaultButton="${controller.vault.locked}" visible="${controller.vault.locked}"/>
<Button text="%addvaultwizard.success.unlockNow" ButtonBar.buttonData="OTHER" onAction="#unlockAndClose" defaultButton="${controller.vault.lockedsecube}" visible="${controller.vault.lockedsecube}"/>
</buttons>
</ButtonBar>
</children>
</VBox>
Here i would like to show the button only when the variable 'lockedsecube', present in the Vault class, is true. The other button, the one with the variable locked, works, but the other with lockedsecube doesn't work. I do not understand the reason, i followed the same steps of the other button. I'm sure that the variable is set true because i debugged the code, but the button is not shown.
This is the Controller
package org.cryptomator.ui.addvaultwizard;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.fxapp.FxApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import java.util.Optional;
@AddVaultWizardScoped
public class AddVaultSuccessController implements FxController {
private final FxApplication fxApplication;
private final Stage window;
private final ReadOnlyObjectProperty<Vault> vault;
private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultPasswordController.class);
@Inject
AddVaultSuccessController(FxApplication fxApplication, @AddVaultWizardWindow Stage window, @AddVaultWizardWindow ObjectProperty<Vault> vault) {
this.fxApplication = fxApplication;
this.window = window;
this.vault = vault;
}
@FXML
public void unlockAndClose() {
close();
fxApplication.startUnlockWorkflow(vault.get(), Optional.of(window));
}
@FXML
public void close() {
window.close();
}
/* Observables */
public ReadOnlyObjectProperty<Vault> vaultProperty() {
return vault;
}
public Vault getVault() {
return vault.get();
}
}
This is the Vault.java file
/*******************************************************************************
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.common.vaults;
import com.google.common.base.Strings;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.mountpoint.InvalidMountPointException;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.vaults.Volume.VolumeException;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.cryptolib.api.MasterkeyLoader;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@PerVault
public class Vault {
private static final Logger LOG = LoggerFactory.getLogger(Vault.class);
private static final Path HOME_DIR = Paths.get(SystemUtils.USER_HOME);
private static final int UNLIMITED_FILENAME_LENGTH = Integer.MAX_VALUE;
private final VaultSettings vaultSettings;
private final Provider<Volume> volumeProvider;
private final StringBinding defaultMountFlags;
private final AtomicReference<CryptoFileSystem> cryptoFileSystem;
private final VaultState state;
private final ObjectProperty<Exception> lastKnownException;
private final VaultConfigCache configCache;
private final VaultStats stats;
private final StringBinding displayName;
private final StringBinding displayablePath;
private final BooleanBinding locked;
///////////////////
private final BooleanBinding lockedsecube;
/////////////////////
private final BooleanBinding processing;
private final BooleanBinding unlocked;
private final BooleanBinding missing;
private final BooleanBinding needsMigration;
private final BooleanBinding unknownError;
private final StringBinding accessPoint;
private final BooleanBinding accessPointPresent;
private final BooleanProperty showingStats;
//bool value to mark the vault Locked with SEcube
//private final
private volatile Volume volume;
@Inject
Vault(VaultSettings vaultSettings, VaultConfigCache configCache, Provider<Volume> volumeProvider, @DefaultMountFlags StringBinding defaultMountFlags, AtomicReference<CryptoFileSystem> cryptoFileSystem, VaultState state, @Named("lastKnownException") ObjectProperty<Exception> lastKnownException, VaultStats stats) {
this.vaultSettings = vaultSettings;
this.configCache = configCache;
this.volumeProvider = volumeProvider;
this.defaultMountFlags = defaultMountFlags;
this.cryptoFileSystem = cryptoFileSystem;
this.state = state;
this.lastKnownException = lastKnownException;
this.stats = stats;
this.displayName = Bindings.createStringBinding(this::getDisplayName, vaultSettings.displayName());
this.displayablePath = Bindings.createStringBinding(this::getDisplayablePath, vaultSettings.path());
this.locked = Bindings.createBooleanBinding(this::isLocked, state);
this.lockedsecube = Bindings.createBooleanBinding(this::isLockedSEcube, state);
LOG.debug("variable locked secube in Vault constructor: "+this.lockedsecube.toString());
this.processing = Bindings.createBooleanBinding(this::isProcessing, state);
this.unlocked = Bindings.createBooleanBinding(this::isUnlocked, state);
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state);
this.accessPoint = Bindings.createStringBinding(this::getAccessPoint, state);
this.accessPointPresent = this.accessPoint.isNotEmpty();
this.showingStats = new SimpleBooleanProperty(false);
//LOG.debug("Vault costruttore"+this.locked.toString() + this.locked_secube.toString());
}
// ******************************************************************************
// Observable Properties
// *******************************************************************************
public VaultState stateProperty() {
return state;
}
public VaultState.Value getState() {
return state.getValue();
}
public ObjectProperty<Exception> lastKnownExceptionProperty() {
return lastKnownException;
}
public Exception getLastKnownException() {
return lastKnownException.get();
}
public void setLastKnownException(Exception e) {
lastKnownException.setValue(e);
}
public BooleanBinding lockedProperty() {
LOG.debug("Sono entrato in lockedProperty"+this.displayName.toString()+ "variable: "+locked.toString());
return locked;
}
public boolean isLocked() {
//LOG.debug("Sono entrato in isLocked"+this.locked.toString()+"state get"+state.get().toString() + "name" +this.displayName.toString());
return state.get() == VaultState.Value.LOCKED;
}
I do not know if i understand well how fxml works, but i think that the property visible=controller.vault.lockedsecube depend on the value of the variable "lockedsecube" in the vault class, right?