Aller au contenu principal

Visibilité conditionnelle (visibleIf)

Chaque widget et conteneur expose une méthode visibleIf(boolean) qui permet de le masquer conditionnellement. Le layout se recalcule automatiquement : les widgets masqués n'occupent aucun pixel.


Fonctionnement

// Widget visible uniquement si le joueur est chef de clan
Button.builder()
.text("monmod.btn.disbandclan")
.command("clan disband")
.visibleIf(isLeader)
.build();

Quand isLeader = false :

  • Le bouton n'est pas rendu.
  • Il n'occupe aucun espace vertical dans le layout.
  • Les widgets en dessous remontent automatiquement.

Quand isLeader = true :

  • Le bouton est rendu normalement et occupe sa hauteur.

Reconstruire le layout après un changement

visibleIf prend un boolean évalué au moment du buildLayout. Pour changer la visibilité après l'ouverture de l'écran, il faut déclencher un rebuild.

Pattern avec init() — toggle simple

private boolean showDetails = false;

@Override
protected void buildLayout(Column root) {
root.add(Button.builder()
.text(showDetails ? "monmod.btn.masquer" : "monmod.btn.voir_details")
.onClick(() -> { showDetails = !showDetails; init(); })
.build());

root.add(Card.create()
.add(KeyValueRow.builder()
.key("monmod.row.coordonnees")
.value(DataSource.of("X:128 Y:64 Z:-32"))
.build())
.visibleIf(showDetails));
}
init() vs update()

Utilise init() quand tu veux juste reconstruire le layout (visibilité, onglets). Utilise update() quand les données ont changé — update() préserve aussi le scroll, init() le remet à zéro.

Pattern avec plusieurs états

private int activeTab = 0; // 0 = membres, 1 = stats, 2 = historique

@Override
protected void buildLayout(Column root) {
root.add(TabBar.builder()
.tab("monmod.tab.membres", () -> { activeTab = 0; init(); })
.tab("monmod.tab.stats", () -> { activeTab = 1; init(); })
.tab("monmod.tab.historique",() -> { activeTab = 2; init(); })
.activeTab(activeTab)
.build());

root.add(buildMembresPanel().visibleIf(activeTab == 0));
root.add(buildStatsPanel() .visibleIf(activeTab == 1));
root.add(buildHistorique() .visibleIf(activeTab == 2));
}

visibleIf sur les conteneurs

visibleIf fonctionne aussi sur Column, Row et Card :

Card adminCard = Card.create()
.add(Button.builder().text("monmod.btn.kick").command("clan kick").build())
.add(Button.builder().text("monmod.btn.promote").command("clan promote").build())
.visible(isAdmin); // ← Card.visible(), pas visibleIf()

root.add(adminCard);
.visible() sur les conteneurs

Column, Row et Card utilisent .visible(boolean) (pas .visibleIf()). Les widgets (Button, Label, etc.) utilisent .visibleIf(boolean). Les deux produisent le même effet.


Avertissement de sécurité

visibleIf est purement cosmétique — il ne sécurise rien

Masquer un bouton avec visibleIf(false) empêche l'utilisateur de cliquer dessus dans l'UI. Mais un joueur malveillant peut toujours envoyer la commande ou le packet associé directement.

Toujours valider les permissions côté serveur, indépendamment de ce que l'UI affiche ou masque.

// Côté serveur — toujours re-vérifier :
@SubscribeEvent
public void onCommand(CommandEvent event) {
if (!player.hasPermission(Permission.CLAN_DISBAND)) {
event.setCanceled(true);
}
}

Voir aussi