问题
An example of what I am trying to accomplish here is: when you open an office Word 2013 file and you click file, in the left side it shows a list {Info, New, Open...}.
Are there any JavaFX components like that? I am looking for a kind of List of (something) whose items are aligned vertically and you can click on to do something (in my case change the view on the right exactly like Word).

回答1:
You can easily reproduce the Word like menu with a VBox and buttons with custom CSS styles. Here is a quick and dirty example that shows a possible solution.
public class Jfxdemos extends Application {
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("File");
final StackPane root = new StackPane();
AnchorPane editorRoot = new AnchorPane();
editorRoot.getChildren().add(btn);
root.getChildren().add(editorRoot);
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().add("/jfxdemos/styles.css");
primaryStage.setScene(scene);
primaryStage.show();
HBox fileRoot = new HBox();
VBox menu = new VBox();
menu.setStyle("-fx-background-color: blue;");
menu.setFillWidth(true);
Button backBtn = new Button("Left Arrow");
backBtn.setPrefWidth(100);
backBtn.getStyleClass().add("custom-menu-button");
backBtn.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent event) {
FadeTransition hideFileRootTransition = new FadeTransition(Duration.millis(500), fileRoot);
hideFileRootTransition.setFromValue(1.0);
hideFileRootTransition.setToValue(0.0);
FadeTransition showEditorRootTransition = new FadeTransition(Duration.millis(500), editorRoot);
showEditorRootTransition.setFromValue(0.0);
showEditorRootTransition.setToValue(1.0);
showEditorRootTransition.play();
hideFileRootTransition.play();
root.getChildren().remove(fileRoot);
}
});
Button infoBtn = new Button("Info");
infoBtn.setPrefWidth(100);
infoBtn.getStyleClass().add("custom-menu-button");
Button newBtn = new Button("New");
newBtn.setPrefWidth(100);
newBtn.getStyleClass().add("custom-menu-button");
Button openBtn = new Button("Open");
openBtn.setPrefWidth(100);
openBtn.getStyleClass().add("custom-menu-button");
menu.getChildren().addAll(backBtn,infoBtn, newBtn, openBtn);
VBox.setVgrow(infoBtn, Priority.ALWAYS);
fileRoot.getChildren().add(menu);
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
root.getChildren().add(fileRoot);
FadeTransition hideEditorRootTransition = new FadeTransition(Duration.millis(500), editorRoot);
hideEditorRootTransition.setFromValue(1.0);
hideEditorRootTransition.setToValue(0.0);
FadeTransition showFileRootTransition = new FadeTransition(Duration.millis(500), fileRoot);
showFileRootTransition.setFromValue(0.0);
showFileRootTransition.setToValue(1.0);
hideEditorRootTransition.play();
showFileRootTransition.play();
}
});
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Plus the styles.css.
.custom-menu-button {
-fx-background-color: blue;
-fx-text-fill: white;
-fx-border: none;
}
.custom-menu-button:hover {
-fx-background-color: lightblue;
}

The same scene after clicking the File button. I used a FadeTransition here because it is simple. But of course you can try to reproduce the same animation as in Word.

回答2:
Here's a quick example using a styled MenuButton.
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class WordLikeMenuButton extends Application {
@Override
public void start(Stage primaryStage) {
MenuButton menuButton = new MenuButton();
menuButton.getItems().addAll(
Stream.of("Info", "New", "Open", "Save", "Save As", "Print", "Share", "Export", "Close")
.map(MenuItem::new).collect(Collectors.toList()));
BorderPane root = new BorderPane(null, menuButton, null, null, null);
Scene scene = new Scene(root, 350, 75);
scene.getStylesheets().add("word-like-menu-button.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
word-like-menu-button.css:
.menu-button, .menu-button .menu-item, .menu-button .context-menu {
-fx-background-color: #28559c;
}
.menu-button .menu-item:hover {
-fx-background-color: #3b6bb7 ;
}
.menu-button .menu-item .label {
-fx-text-fill: white ;
}
.menu-button > .arrow-button {
-fx-background-color: white, #28559c ;
-fx-background-insets: 1, 3 ;
-fx-background-radius: 16, 16 ;
-fx-padding: 8 ;
}
.menu-button > .arrow-button > .arrow {
-fx-background-color: white ;
/*-fx-background-insets: 0, 2 ;
-fx-background-radius: 12, 12 ;*/
-fx-padding: 8 ;
-fx-shape: "M0 6 l-6 -6 l0 -2 l6 -6 l2 0 l-6 6 l12 0 l0 2 l-12 0 l6 6 z";
}
This gives

回答3:
It would be much better to use JFXTabPane
and customize it a little bit. As for the back arrow, you can do what I did with logout button in this tutorial http://synappse.co/blog/vertical-stateful-jfxtabpane-with-icons-in-javafx/
来源:https://stackoverflow.com/questions/28717343/javafx-create-a-vertical-menu-ribbon