Pregunta sobre accordion, javafx-2 – Evita que un acordeón en JavaFX se colapse

8

¿Existe una manera fácil de evitar que un acordeón en JavaFX 2.1 se colapse completamente? Tengo un acordeón con algunas entradas, pero si el usuario hace clic en la entrada de acordeón activa, colapsa el acordeón.

Probablemente podría usar un detector de clics del mouse para verificar la verificación y actuar en consecuencia, pero parece que debería ser incluso más sencillo de lograr.

Ahora hay una solicitud de función en javafx-jira para esto# RT-28141 drzymala

Tu respuesta

2   la respuesta
8

Agregue un oyente al panel de acordeón actualmente expandido e impida que el usuario pueda colapsarlo modificando su propiedad colapsable.

Aquí hay una aplicación de muestra:

<code>import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class AccordionSample extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage primaryStage) {
    // create some titled panes to go in an accordion.
    TitledPane adminPane = new TitledPane("Animals", 
      VBoxBuilder.create().style("-fx-padding: 10").spacing(10).children(
        ButtonBuilder.create().text("Zebra").maxWidth(Double.MAX_VALUE).build(),
        ButtonBuilder.create().text("Shrew").maxWidth(Double.MAX_VALUE).build()
      ).build()            
    );
    TitledPane viewPane = new TitledPane("Vegetables", 
      VBoxBuilder.create().style("-fx-padding: 10").spacing(10).children(
        ButtonBuilder.create().text("Eggplant").maxWidth(Double.MAX_VALUE).build(),
        ButtonBuilder.create().text("Carrot").maxWidth(Double.MAX_VALUE).build()
      ).build()            
    );

    // create an accordion, ensuring the currently expanded pane can not be clicked on to collapse.
    Accordion accordion = new Accordion();
    accordion.getPanes().addAll(adminPane, viewPane);
    accordion.expandedPaneProperty().addListener(new ChangeListener<TitledPane>() {
      @Override public void changed(ObservableValue<? extends TitledPane> property, final TitledPane oldPane, final TitledPane newPane) {
        if (oldPane != null) oldPane.setCollapsible(true);
        if (newPane != null) Platform.runLater(new Runnable() { @Override public void run() { 
          newPane.setCollapsible(false); 
        }});
      }
    });
    for (TitledPane pane: accordion.getPanes()) pane.setAnimated(false);
    accordion.setExpandedPane(accordion.getPanes().get(0));

    // layout the scene.
    StackPane layout = new StackPane();
    layout.setStyle("-fx-padding: 10; -fx-background-color: cornsilk;");
    layout.getChildren().add(accordion);
    primaryStage.setScene(new Scene(layout));
    primaryStage.show();
  }
}
</code>
Usar la propiedad de contraer deshabilita la animación Strassenrenner
4

Aquí hay otra solución para asegurarse de que el acordeón nunca se colapsará por completo. La diferencia con la gran respuesta original de @jewelsea es pequeña: no me gustó el hecho de que la flecha hacia abajo orientada hacia abajo por defecto estaba desapareciendo de la cara abierta de TitledPane de acordeón, porque su propiedad "colapsable" se está configurando como falsa. Jugué con él un poco más para lograr una sensación más "natural" para mi interfaz.

<code>    /* Make sure the accordion can never be completely collapsed */
    accordeon.expandedPaneProperty().addListener((ObservableValue<? extends TitledPane> observable, TitledPane oldPane, TitledPane newPane) -> {
        Boolean expand = true; // This value will change to false if there's (at least) one pane that is in "expanded" state, so we don't have to expand anything manually
        for(TitledPane pane: accordeon.getPanes()) {
            if(pane.isExpanded()) {
                expand = false;
            }
        }
        /* Here we already know whether we need to expand the old pane again */
        if((expand == true) && (oldPane != null)) {
            Platform.runLater(() -> {
                accordeon.setExpandedPane(oldPane);
            });
        }
    });
</code>

Preguntas relacionadas