Java Swing Hamburger Menu

How to Create a Hamburger Menu in Java Netbeans




In this Java Tutorial we will see How To Create a modern hamburger menu navigation with smooth animations and custom icons In Java Using Netbeans.


What We'll Build?
    An animated hamburger menu that slides in from the left.
    - Custom drawn icons for each menu item.
    - Transitions and hover effects.
    - A responsive overlay system.


What We Are Gonna Use In This Project:

- Java Programming Language.
- NetBeans Editor.





Project Source Code:



/**
 *
 * @author 1BestCsharp
 */
public class HamburgerMenu extends JFrame {
    // Menu state and animation properties
    private boolean isMenuOpen = false;    // Tracks if menu is currently open
    private JPanel sideMenu;               // The side navigation panel
    private Timer animationTimer;          // Controls the animation speed
    private float currentWidth = 0;        // Current width during animation
    private float currentAlpha = 0;        // Current transparency of overlay
    
    // Constants for menu appearance and animation
    private final int MENU_WIDTH = 280;            // Width of the side menu
    private final int ANIMATION_DURATION = 250;    // Total animation time in milliseconds
    private final int ANIMATION_STEPS = 30;        // Number of steps in animation
    
    // UI Components
    private HamburgerIcon hamburgerIcon;   // The hamburger/close button
    private JPanel overlay;                // Semi-transparent overlay behind menu
    
    // Colors used throughout the UI
    private final Color accentColor = new Color(75, 107, 251);        // Highlight color
    private final Color backgroundColor = new Color(245, 245, 250);    // Main background
    private final Color menuBackground = new Color(25, 25, 35);       // Menu background
    private final Color menuHoverColor = new Color(45, 45, 55);       // Menu item hover color
    private final Color menuActiveColor = new Color(55, 155, 65);      // Menu item active color
    
    public HamburgerMenu(){
        // Set up the main window
        setTitle("Hamburger Menu");
        setSize(1000, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);  // Center the window on screen
        setBackground(backgroundColor);
        
        // Create the main content area
        JPanel mainContent = new JPanel();
        mainContent.setLayout(new BorderLayout());
        mainContent.setBackground(backgroundColor);
        
        // Create header with hamburger button
        setupHeader();
        
        // Create semi-transparent overlay that appears behind the menu
        setupOverlay();
        
        // Create side menu with navigation options
        setupSideMenu();
        
        
        // Set up layered pane for menu animation
        setupLayeredPane(mainContent);
        
        
        // Set up animation timer that controls the menu slide effect
        setupAnimationTimer();
        
    }
    
    
    /**
     * Sets up the header section with title and hamburger icon
     */
    private void setupHeader() {
        hamburgerIcon = new HamburgerIcon();
        
        // Create header panel with a subtle bottom border
        JPanel headerPanel = new JPanel(new BorderLayout());
        headerPanel.setBackground(Color.WHITE);
        headerPanel.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(230, 230, 235)),
            BorderFactory.createEmptyBorder(15, 15, 15, 15)
        ));
        
        // Add title to header
        JLabel titleLabel = new JLabel("Dashboard");
        titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 20));
        titleLabel.setForeground(new Color(40, 40, 45));
        titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0));
        
        // Add components to header
        headerPanel.add(hamburgerIcon, BorderLayout.WEST);
        headerPanel.add(titleLabel, BorderLayout.CENTER);
        
        // Add header to main frame
        add(headerPanel, BorderLayout.NORTH);
        
    }
    
    /**
     * Sets up the semi-transparent overlay that appears when menu is open
     */
    private void setupOverlay() {
        // Create transparent panel that darkens when menu opens
        overlay = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                // Set transparency based on animation progress
                g2d.setColor(new Color(0, 0, 0, (int)(currentAlpha * 120)));
                g2d.fillRect(0, 0, getWidth(), getHeight());
            }
        };
        overlay.setOpaque(false);
        overlay.setBounds(0, 0, 2000, 1200);
        
        // Close menu when clicking overlay
        overlay.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                toggleMenu();
            }
        });
        
        overlay.setVisible(false);
        
    }
    
    
    /**
     * Sets up the side navigation menu with menu items
     */
    private void setupSideMenu() {
        // Create the main menu panel
        sideMenu = new JPanel();
        sideMenu.setLayout(new BoxLayout(sideMenu, BoxLayout.Y_AXIS));
        sideMenu.setBackground(menuBackground);
        
        // Add brand/logo section at the top
        JPanel brandPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 25));
        brandPanel.setBackground(menuBackground);
        brandPanel.setMaximumSize(new Dimension(MENU_WIDTH, 80));
        
        JLabel brandLabel = new JLabel("Modern UI");
        brandLabel.setFont(new Font("Segoe UI", Font.BOLD, 24));
        brandLabel.setForeground(Color.WHITE);
        brandPanel.add(brandLabel);
        sideMenu.add(brandPanel);
        sideMenu.add(Box.createVerticalStrut(20));  // Add spacing
        
        // Define menu item names
        String[] menuItems = {
            "Dashboard", "Profile", "Analytics", "Settings", "Help", "Logout"
        };
        
        // Create and add each menu item
        for (int i = 0; i < menuItems.length; i++) {
            JPanel menuItemPanel = createMenuItemPanel(menuItems[i], i);
            sideMenu.add(menuItemPanel);
            sideMenu.add(Box.createVerticalStrut(5));  // Add spacing between items
        }
    }
    
    
    
    /**
     * Sets up the layered pane that allows components to overlap
     * This enables the menu to slide over the main content
     */
    private void setupLayeredPane(JPanel mainContent) {
        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setLayout(null);
        
        // Position components
        mainContent.setBounds(0, 0, 2000, 1200);
        sideMenu.setBounds(-MENU_WIDTH, 0, MENU_WIDTH, 1200);
        
        // Add components to layers (higher number = in front)
        layeredPane.add(mainContent, JLayeredPane.DEFAULT_LAYER);     // Bottom layer
        layeredPane.add(overlay, JLayeredPane.PALETTE_LAYER);         // Middle layer
        layeredPane.add(sideMenu, JLayeredPane.MODAL_LAYER);          // Top layer
        
        add(layeredPane, BorderLayout.CENTER);
        
    }
    
    
    /**
     * Sets up animation timer that controls the menu sliding effect
     */
    private void setupAnimationTimer() {
        animationTimer = new Timer(ANIMATION_DURATION / ANIMATION_STEPS, e -> {
            if (isMenuOpen) {
                // Opening animation - increase width and opacity
                currentWidth = Math.min(currentWidth + MENU_WIDTH / ANIMATION_STEPS, MENU_WIDTH);
                currentAlpha = Math.min(currentAlpha + 1.0f / ANIMATION_STEPS, 1.0f);
            }  else {
                // Closing animation - decrease width and opacity
                currentWidth = Math.max(currentWidth - MENU_WIDTH / ANIMATION_STEPS, 0);
                currentAlpha = Math.max(currentAlpha - 1.0f / ANIMATION_STEPS, 0.0f);
            }
            
            // Update positions and visibility based on animation progress
            sideMenu.setBounds((int) (-MENU_WIDTH + currentWidth), 0, MENU_WIDTH, 1200);
            overlay.setVisible(currentAlpha > 0);
            hamburgerIcon.setRotation(currentWidth / MENU_WIDTH * 180);
            
            // Stop animation when complete
            if ((isMenuOpen && currentWidth == MENU_WIDTH) || (!isMenuOpen && currentWidth == 0)) {
                animationTimer.stop();
            }
            repaint();
            
        });
        
    }

    /**
     * Toggles the menu open or closed state and starts animation
     */
    private void toggleMenu() {
        isMenuOpen = !isMenuOpen;  // Toggle state
        animationTimer.start();    // Start animation
    }
    
    
    /**
     * Creates a menu item panel with icon and text
     * 
     * @param text The text label for the menu item
     * @param iconType The type of icon to display (0-5)
     * @return A panel containing the menu item
     */
    private JPanel createMenuItemPanel(String text, int iconType) {
        // Create main panel
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.setMaximumSize(new Dimension(MENU_WIDTH, 50));
        panel.setBackground(menuBackground);
        panel.setBorder(BorderFactory.createEmptyBorder(8, 20, 8, 20));
        panel.setCursor(new Cursor(Cursor.HAND_CURSOR));
        
        // Create left indicator panel (shows colored bar when active)
        JPanel indicatorPanel = new JPanel();
        indicatorPanel.setPreferredSize(new Dimension(4, 0));
        indicatorPanel.setBackground(menuBackground);
        
        // Create icon
        IconPanel iconPanel = new IconPanel(iconType);
        iconPanel.setPreferredSize(new Dimension(24, 24));
        
        // Create text label
        JLabel textLabel = new JLabel(text);
        textLabel.setFont(new Font("Segoe UI", Font.PLAIN, 15));
        textLabel.setForeground(Color.WHITE);
        textLabel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0));
        
        // Container to hold icon and text
        JPanel contentPanel = new JPanel(new BorderLayout());
        contentPanel.setBackground(menuBackground);
        contentPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
        contentPanel.add(iconPanel, BorderLayout.WEST);
        contentPanel.add(textLabel, BorderLayout.CENTER);
        
        // Add components to main panel
        panel.add(indicatorPanel, BorderLayout.WEST);
        panel.add(contentPanel, BorderLayout.CENTER);
        
        // Add interaction effects (hover, click)
        addMenuItemInteraction(panel, contentPanel, indicatorPanel, text);
        
        return panel;
        
    }
    
    
    /**
     * Adds mouse interaction behavior to menu items
     */
    private void addMenuItemInteraction(JPanel panel, JPanel contentPanel, 
                                       JPanel indicatorPanel, String text) {
        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                // Hover effect - change background color
                panel.setBackground(menuHoverColor);
                contentPanel.setBackground(menuHoverColor);
                indicatorPanel.setBackground(menuHoverColor);
                
                // Show active indicator on hover
                indicatorPanel.removeAll();
                JPanel activeIndicator = new JPanel();
                activeIndicator.setBackground(accentColor);
                indicatorPanel.setLayout(new BorderLayout());
                indicatorPanel.add(activeIndicator);
                panel.revalidate();
                panel.repaint();  
            }
            
            
            @Override
            public void mouseExited(MouseEvent e) {
                // Reset to normal state
                panel.setBackground(menuBackground);
                contentPanel.setBackground(menuBackground);
                indicatorPanel.setBackground(menuBackground);
                
                // Remove active indicator
                indicatorPanel.removeAll();
                panel.revalidate();
                panel.repaint();
                
            }
            
            @Override
            public void mousePressed(MouseEvent e) {
                // Click down effect
                panel.setBackground(menuActiveColor);
                contentPanel.setBackground(menuActiveColor);
                indicatorPanel.setBackground(menuActiveColor);
            }
            
            @Override
            public void mouseReleased(MouseEvent e) {
                // Click up effect
                panel.setBackground(menuHoverColor);
                contentPanel.setBackground(menuHoverColor);
                indicatorPanel.setBackground(menuHoverColor);
            }
            
            @Override
            public void mouseClicked(MouseEvent e) {
                // Handle menu item click
                System.out.println("Menu item clicked: " + text);
            }
            
        });
        
    }
    
    
    /**
     * IconPanel draws custom vector icons for menu items
     */
    private class IconPanel extends JPanel {
        private int iconType;  // Type of icon to draw
        
        public IconPanel(int iconType) {
            this.iconType = iconType;
            setPreferredSize(new Dimension(24, 24));
            setOpaque(false);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            // Enable antialiasing for smoother drawing
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.WHITE);
            
            int w = getWidth();
            int h = getHeight();
            
            // Draw different icon based on type
            switch (iconType) {
                case 0: // Dashboard
                    drawDashboardIcon(g2d, w, h);
                    break;
                case 1: // Profile
                    drawProfileIcon(g2d, w, h);
                    break;
                case 2: // Analytics
                    drawAnalyticsIcon(g2d, w, h);
                    break;
                case 3: // Settings
                    drawSettingsIcon(g2d, w, h);
                    break;
                case 4: // Help
                    drawHelpIcon(g2d, w, h);
                    break;
                case 5: // Logout
                    drawLogoutIcon(g2d, w, h);
                    break;
            }
            
        }
        
        /**
         * Draws dashboard icon (four squares in a grid)
         */
        private void drawDashboardIcon(Graphics2D g2d, int w, int h) {
            int padding = 3;
            int size = Math.min(w, h) - (2 * padding);
            int x = (w - size) / 2;
            int y = (h - size) / 2;
            
            int gridSize = size / 2 - 1;
            
            // Draw 4 squares to represent dashboard
            g2d.fillRect(x, y, gridSize, gridSize);
            g2d.fillRect(x + gridSize + 2, y, gridSize, gridSize);
            g2d.fillRect(x, y + gridSize + 2, gridSize, gridSize);
            g2d.fillRect(x + gridSize + 2, y + gridSize + 2, gridSize, gridSize);
            
        }
        
        /**
         * Draws profile icon (person silhouette)
         */
        private void drawProfileIcon(Graphics2D g2d, int w, int h) {
            int padding = 3;
            int size = Math.min(w, h) - (2 * padding);
            int x = (w - size) / 2;
            int y = (h - size) / 2;
            
            // Draw head circle
            int headSize = size / 2;
            g2d.fillOval(x + (size - headSize) / 2, y, headSize, headSize);
            
            // Draw body
            int bodyWidth = size / 2;
            int bodyHeight = size / 2;
            int bodyX = x + (size - bodyWidth) / 2;
            int bodyY = y + headSize;
            
            // Create body shape
            Path2D.Float body = new Path2D.Float();
            body.moveTo(bodyX, bodyY);
            body.lineTo(bodyX + bodyWidth, bodyY);
            body.lineTo(bodyX + bodyWidth + (bodyWidth / 2), bodyY + bodyHeight);
            body.lineTo(bodyX - (bodyWidth / 2), bodyY + bodyHeight);
            body.closePath();
            
            g2d.fill(body);
            
        }
        
        /**
         * Draws analytics icon (bar chart)
         */
        private void drawAnalyticsIcon(Graphics2D g2d, int w, int h) {
            int padding = 4;
            int size = Math.min(w, h) - (2 * padding);
            int x = (w - size) / 2;
            int y = (h - size) / 2;
            
            int barWidth = size / 4;
            
            // Draw three bars of increasing height
            g2d.fillRect(x, y + size - (size / 3), barWidth, size / 3);
            g2d.fillRect(x + barWidth * 1 + 1, y + size - (size / 2), barWidth, size / 2);
            g2d.fillRect(x + barWidth * 2 + 2, y + size - (size / 1), barWidth, size);
            
        }
        
        /**
         * Draws settings icon (gear)
         */
        private void drawSettingsIcon(Graphics2D g2d, int w, int h) {
            int centerX = w / 2;
            int centerY = h / 2;
            int outerRadius = w / 2 - 2;  // Outer radius of gear
            int innerRadius = outerRadius - 5;  // Inner radius of gear
            int teethCount = 8;  // Number of teeth on gear
            
            // Draw center circle
            g2d.fillOval(centerX - innerRadius/2, centerY - innerRadius/2, 
                          innerRadius, innerRadius);
            
            // Draw gear teeth
            for (int i = 0; i < teethCount; i++) {
                double angle = Math.toRadians(i * (360.0 / teethCount));
                
                // Create a tooth shape
                Path2D.Float tooth = new Path2D.Float();
                
                // Starting point (inner gear)
                double x1 = centerX + innerRadius * Math.cos(angle - 0.2);
                double y1 = centerY + innerRadius * Math.sin(angle - 0.2);
                tooth.moveTo(x1, y1);
                
                // Outer point
                double x2 = centerX + outerRadius * Math.cos(angle);
                double y2 = centerY + outerRadius * Math.sin(angle);
                tooth.lineTo(x2, y2);
                
                // End point (back to inner gear)
                double x3 = centerX + innerRadius * Math.cos(angle + 0.2);
                double y3 = centerY + innerRadius * Math.sin(angle + 0.2);
                tooth.lineTo(x3, y3);
                
                // Draw the tooth
                g2d.fill(tooth);
            }
            
        }
        
        /**
         * Draws help icon (question mark)
         */
        private void drawHelpIcon(Graphics2D g2d, int w, int h) {
            int padding = 3;
            int size = Math.min(w, h) - (2 * padding);
            int x = (w - size) / 2;
            int y = (h - size) / 2;
            
            // Draw outer circle
            g2d.setStroke(new BasicStroke(2f));
            g2d.drawOval(x, y, size, size);
            
            int centerX = x + size/2;
            int centerY = y + size/2;
            int radius = size/2;
            
            // Draw question mark stem (vertical line at bottom)
            g2d.setStroke(new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2d.drawLine(centerX, centerY + radius/3, centerX, centerY + 2*radius/3);
            
            // Draw question mark dot
            //g2d.fillOval(centerX - 1, centerY - radius/3 - 1, 3, 3);
            
            // Draw curved top of question mark
            Path2D.Float curve = new Path2D.Float();
            curve.moveTo(centerX - radius/3, centerY - radius/4);
            curve.quadTo(centerX - radius/3, centerY - radius/2, centerX, centerY - radius/2);
            curve.quadTo(centerX + radius/3, centerY - radius/2, centerX + radius/3, centerY - radius/4);
            curve.quadTo(centerX + radius/3, centerY, centerX, centerY);
            
            g2d.setStroke(new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2d.draw(curve);
        }
        
        /**
         * Draws logout icon (door with arrow)
         */
        private void drawLogoutIcon(Graphics2D g2d, int w, int h) {
            int padding = 2;
            int size = Math.min(w, h) - (2 * padding);
            int x = (w - size) / 2;
            int y = (h - size) / 2;
            
            // Set thicker stroke for better visibility
            g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            
            // Draw door frame
            int doorWidth = (int)(size * 0.6);
            int doorHeight = size;
            g2d.drawRect(x, y, doorWidth, doorHeight);
            
            // Draw door handle
            int handleX = x + doorWidth - 3;
            int handleY = y + doorHeight/2;
            g2d.fillOval(handleX - 3, handleY - 3, 6, 6);
            
            // Draw arrow pointing out
            int arrowStartX = x + doorWidth + 2;
            int arrowEndX = x + size;
            int arrowY = y + doorHeight/2;
            
            // Arrow line
            g2d.drawLine(arrowStartX, arrowY, arrowEndX, arrowY);
            
            // Arrow head
            int arrowHeadSize = 5;
            g2d.drawLine(arrowEndX - arrowHeadSize, arrowY - arrowHeadSize, arrowEndX, arrowY);
            g2d.drawLine(arrowEndX - arrowHeadSize, arrowY + arrowHeadSize, arrowEndX, arrowY);
            
        }
        
    }
    
    
    /**
     * HamburgerIcon class creates the animated hamburger/close button
     */
    private class HamburgerIcon extends JPanel {
        private float rotation = 0;        // Current rotation angle
        private boolean isHovered = false; // Hover state
        
        public HamburgerIcon() {
            setPreferredSize(new Dimension(32, 32));
            setBackground(Color.WHITE);
            setCursor(new Cursor(Cursor.HAND_CURSOR));
            
            // Add mouse interaction
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    toggleMenu(); // Toggle menu when clicked
                }
                
                @Override
                public void mouseEntered(MouseEvent e) {
                    isHovered = true;
                    repaint();
                }
               
                @Override
                public void mouseExited(MouseEvent e) {
                    isHovered = false;
                    repaint();
                } 
            });
        }
        
        /**
         * Sets the rotation angle for the icon animation
         * @param rotation Angle in degrees (0 = hamburger, 180 = X)
         */
        public void setRotation(float rotation) {
            this.rotation = rotation;
            repaint();
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                    RenderingHints.VALUE_ANTIALIAS_ON);
            
            int centerX = getWidth() / 2;
            int centerY = getHeight() / 2;
            
            // Save current transform to restore later
            AffineTransform oldTransform = g2d.getTransform();
            
            // Rotate around center
            g2d.rotate(Math.toRadians(rotation), centerX, centerY);
            
            // Set color based on hover state
            g2d.setColor(isHovered ? new Color(60, 60, 65) : new Color(40, 40, 45));
            g2d.setStroke(new BasicStroke(2.2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            
            // Draw either hamburger or X based on rotation
            if (rotation < 90) {
                // Hamburger state (three lines)
                g2d.drawLine(8, 11, 24, 11);
                g2d.drawLine(8, 16, 24, 16);
                g2d.drawLine(8, 21, 24, 21);
            }  else {
                // Close (X) state
                g2d.drawLine(11, 11, 21, 21);
                g2d.drawLine(11, 21, 21, 11);
            }
            
            // Restore original transform
            g2d.setTransform(oldTransform);
            
        }
        
    }
    
    public static void main(String[] args) {
        
         SwingUtilities.invokeLater(() -> {
            try {
                // Use system look and feel for better integration
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            // Create and show the main window
            HamburgerMenu frame = new HamburgerMenu();
            frame.setVisible(true);
        });
    }

}


  


The Final Result:





















Share this

Related Posts

Latest
Previous
Next Post »