You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaFX实现Windows 10风格导航抽屉及主内容伸缩?

Replicating Windows 10-Style Navigation Drawer in JavaFX

Absolutely! You can absolutely replicate that Windows 10-style navigation drawer behavior—where icons show by default, and text appears only when you click the hamburger button, with the main content area resizing accordingly—using either core JavaFX components or third-party libraries. Let me walk you through both approaches:

Core JavaFX Implementation

If you prefer to build it from scratch without external dependencies, you can combine JavaFX's layout containers and animation APIs to get the desired effect. Here's a step-by-step breakdown:

  1. Layout Structure: Use a BorderPane as your root container. The left region will hold your navigation drawer (a VBox), and the center region will contain your main content.
  2. Drawer Items: Each navigation item should be an HBox containing an ImageView (for the icon) and a Label (for the text). By default, hide the Label so only icons are visible.
  3. Animation & Toggle Logic: Use a Timeline to animate the drawer's width when the hamburger button is clicked. Toggle the visibility of the text labels alongside the width animation.
  4. Auto-Resizing Main Content: Since the main content is in the BorderPane's center, it will automatically resize as the left drawer expands or contracts—no extra work needed here!

Example Code Snippet

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.List;

public class Windows10DrawerDemo extends Application {
    private boolean drawerExpanded = false;
    private final List<HBox> drawerItems = new ArrayList<>();
    private final VBox drawerPane = new VBox(10);

    @Override
    public void start(Stage stage) {
        // Setup hamburger button
        Button hamburgerButton = new Button("☰");
        hamburgerButton.setOnAction(e -> toggleDrawer());

        // Create drawer items
        createDrawerItem("Home", "home-icon.png");
        createDrawerItem("Settings", "settings-icon.png");
        createDrawerItem("Documents", "docs-icon.png");

        drawerPane.setPadding(new Insets(10));
        drawerPane.setPrefWidth(60); // Default width for icons only

        // Main content area
        Label mainContent = new Label("Main Content Area");
        mainContent.setStyle("-fx-font-size: 24px; -fx-padding: 20px;");

        // Root layout
        BorderPane root = new BorderPane();
        root.setTop(hamburgerButton);
        root.setLeft(drawerPane);
        root.setCenter(mainContent);

        Scene scene = new Scene(root, 800, 600);
        stage.setTitle("Windows 10 Style Drawer");
        stage.setScene(scene);
        stage.show();
    }

    private void createDrawerItem(String text, String iconPath) {
        ImageView icon = new ImageView(new Image(iconPath));
        icon.setFitWidth(32);
        icon.setFitHeight(32);

        Label label = new Label(text);
        label.setVisible(false); // Hide text by default

        HBox item = new HBox(10, icon, label);
        item.setPadding(new Insets(5));
        drawerItems.add(item);
        drawerPane.getChildren().add(item);
    }

    private void toggleDrawer() {
        Timeline timeline = new Timeline();
        double targetWidth = drawerExpanded ? 60 : 200;

        // Animate drawer width
        KeyValue widthKV = new KeyValue(drawerPane.prefWidthProperty(), targetWidth);
        KeyFrame widthKF = new KeyFrame(Duration.millis(300), widthKV);
        timeline.getKeyFrames().add(widthKF);

        // Toggle text visibility
        drawerItems.forEach(item -> {
            Label label = (Label) item.getChildren().get(1);
            label.setVisible(!drawerExpanded);
        });

        drawerExpanded = !drawerExpanded;
        timeline.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Third-Party Library Options

If you want a more polished, out-of-the-box solution, these libraries have built-in components that match your requirement:

ControlsFX

The NavigationDrawer component in ControlsFX is designed exactly for this use case. It automatically shows only icons when collapsed, and expands to show text when opened. It also handles the main content resizing automatically.

Quick Usage Example:

import org.controlsfx.control.DrawerPane;
import org.controlsfx.control.NavigationDrawer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ControlsFXDrawerDemo extends Application {
    @Override
    public void start(Stage stage) {
        DrawerPane drawerPane = new DrawerPane();
        NavigationDrawer navDrawer = new NavigationDrawer();

        // Add navigation items with icon and text
        NavigationDrawer.Item homeItem = new NavigationDrawer.Item("Home", new ImageView(new Image("home-icon.png")));
        NavigationDrawer.Item settingsItem = new NavigationDrawer.Item("Settings", new ImageView(new Image("settings-icon.png")));
        navDrawer.getItems().addAll(homeItem, settingsItem);

        drawerPane.setSideDrawer(navDrawer);

        // Hamburger button to toggle drawer
        Button hamburgerButton = new Button("☰");
        hamburgerButton.setOnAction(e -> {
            if (drawerPane.isDrawerVisible()) {
                drawerPane.hideDrawer();
            } else {
                drawerPane.showDrawer();
            }
        });

        BorderPane root = new BorderPane();
        root.setTop(hamburgerButton);
        root.setCenter(drawerPane);

        Scene scene = new Scene(root, 800, 600);
        stage.setTitle("ControlsFX Drawer");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

JFoenix

JFoenix's JFXDrawer component also supports this behavior. You can customize the drawer's content to show icons only when collapsed, and add text on expansion. It includes smooth animations and integrates well with other JFoenix components.

Tips for Polish

  • Adjust the animation duration (Duration.millis(300) in the examples) to match Windows 10's feel.
  • Add hover effects to drawer items for better interactivity.
  • Ensure icons are sized consistently (32x32 is a good standard for Windows 10-style navigation).

内容的提问来源于stack exchange,提问作者Volkeee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:46:20