Pergunta sobre accordion, javafx-2 – Evitar que um acordeão no JavaFX entre em colapso

8

Existe uma maneira fácil de impedir que um acordeão no JavaFX 2.1 entre em colapso total? Eu tenho um acordeão com algumas entradas, mas se o usuário clica na entrada do acordeão ativa, ele recolhe o acordeão.

Eu provavelmente poderia usar um ouvinte de clique do mouse para verificar o check e agir em conformidade, mas parece que deveria ser ainda mais simples do que isso para realizar.

Existe agora uma solicitação de recurso no javafx-jira para isso# RT-28141 drzymala

Sua resposta

2   a resposta
8

que ele seja recolhido pelo usuário, modificando sua propriedade recolhível.

Aqui está um aplicativo de amostra:

<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>
Usando a propriedade de recolhimento desativa a animação Strassenrenner
4

tamente. A diferença da grande resposta original de @jewelsea é pequena - eu não gostei do fato de que a seta padrão para baixo estava desaparecendo da abertura do TitledPane, porque sua propriedade "colapsável" está sendo definida como falsa. Eu joguei com ele um pouco mais para conseguir uma sensação mais "natural" para a minha interface.

<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>

Perguntas relacionadas