Periodic Table In Java Swing

How to Create a Periodic Table in Java Netbeans

How to Create a Periodic Table in Java Netbeans



In this Java Tutorial we will see How To Create a Periodic Table that displays all 118 chemical elements with hover tooltips and gradient backgrounds In Java Using Netbeans.

What We Are Gonna Use In This Project:

- Java Programming Language.
- NetBeans Editor.





Project Source Code:



/**
 *
 * @author 1BestCsharp
 */
public class PeriodicTable extends JFrame {

        // A map to store all chemical elements with their symbols as keys
        private final Map<String, Element> elements = new HashMap<>();
        // Custom tooltip to display element information
        private CustomTooltip tooltip;
    
        public PeriodicTable(){
            
                // Set basic JFrame properties
                setTitle("Periodic Table");
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                setLayout(new BorderLayout());
                
                // Load all element data into the elements map
                initializeElements();

                // Create a tooltip that will appear when hovering over elements
                tooltip = new CustomTooltip();
                tooltip.setVisible(false);
                
                  // Create the main panel with a gradient background
                 JPanel mainPanel = new JPanel() {
                             
                         /**
                        * Override the paintComponent method to create a custom gradient background
                        */
                       @Override
                       protected void paintComponent(Graphics g) {
                           
                                   super.paintComponent(g);
                                // Cast to Graphics2D to access advanced drawing features
                                Graphics2D g2d = (Graphics2D) g;
                                // Enable anti-aliasing for smoother edges
                                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                                int w = getWidth();
                                int h = getHeight();
                                // Create dark blue to darker blue gradient
                                GradientPaint gp = new GradientPaint(0, 0, new Color(30, 33, 39), w, h, new Color(15, 15, 18));
                                g2d.setPaint(gp);
                                g2d.fillRect(0, 0, w, h);
                       
                       }
                 };
                 
                  // Set up a grid layout for the periodic table (10 rows, 18 columns)
                mainPanel.setLayout(new GridLayout(10, 18, 5, 5));
                mainPanel.setBackground(Color.WHITE);
                mainPanel.setOpaque(true);
                
                // Create and place element buttons in the correct positions in the grid
                for (int i = 0; i < 10; i++) {
                    
                      for (int j = 0; j < 18; j++) {
                          // Get the element symbol at this position (if any)
                         String elementSymbol = getElementSymbol(i, j);
                         if (elementSymbol != null) {
                                // Create a button for this element
                                JButton button = createElementButton(elementSymbol);
                                mainPanel.add(button);
                          }  else {
                                // Add an empty panel for positions with no element
                                JPanel emptyPanel = new JPanel();
                                emptyPanel.setOpaque(false);
                                mainPanel.add(emptyPanel);
                            }
                      }
                    
                }
                
                
                 // Add the main panel to the center of the JFrame
                add(mainPanel, BorderLayout.CENTER);
                
                 // Set the window size and center it on the screen
                setSize(1600, 1000);
                setLocationRelativeTo(null);

        }
        
        
        /**
        * Creates a custom button for a chemical element
        * 
        * @param symbol The chemical symbol of the element (e.g., "H" for Hydrogen)
        * @return A JButton customized for the element
        */
         private JButton createElementButton(String symbol) {
         
                  // Create a custom JButton with overridden paintComponent method
                 JButton button = new JButton() {
                 
                        /**
                        * Custom rendering for element buttons with rounded corners and gradient
                        */
                       @Override
                       protected void paintComponent(Graphics g) {
                                    Graphics2D g2d = (Graphics2D) g;
                                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                            RenderingHints.VALUE_ANTIALIAS_ON);
                                    
                                   // Get the element data
                                    Element element = elements.get(symbol);
                                    // Get appropriate color based on element category
                                    Color bgColor = getCategoryColor(element.category); 
                                    
                                   // Create gradient background with a rounded rectangle shape
                                    GradientPaint gradient = new GradientPaint(
                                        0, 0, 
                                        bgColor.darker(), 
                                        getWidth(), 
                                        getHeight(), 
                                       bgColor.brighter()
                                    );
                                    g2d.setPaint(gradient);
                                    g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 16, 16);
                                    
                                    // Add shadow effect to give depth
                                    g2d.setColor(new Color(0, 0, 0, 50)); // Semi-transparent black
                                    g2d.fillRoundRect(6, 6, getWidth() - 12, getHeight() - 12, 12, 12);
                                    
                                   // Draw the atomic number in the top-left corner
                                    g2d.setColor(Color.WHITE);
                                    g2d.setFont(new Font("Segoe UI", Font.PLAIN, 12));
                                    g2d.drawString(String.valueOf(element.atomicNumber), 12, 20);
                                    
                                    // Draw the element symbol in the center
                                    g2d.setFont(new Font("Segoe UI", Font.BOLD, 20));
                                    FontMetrics fm = g2d.getFontMetrics();
                                    int symbolWidth = fm.stringWidth(symbol);
                                    int symbolX = (getWidth() - symbolWidth) / 2;
                                    g2d.drawString(symbol, symbolX, getHeight() / 2 + 7);

                       }
                     
                 };
                 
                  // Set button properties
                 button.setPreferredSize(new Dimension(100, 100));
                 button.setBorderPainted(false);
                 button.setFocusPainted(false);
                 button.setContentAreaFilled(false);
                 
                 // Add mouse listeners 
                 button.addMouseListener(new MouseAdapter() {
                 
                            /**
                            * Show tooltip with element details when mouse hovers over the button
                            */
                           @Override
                           public void mouseEntered(MouseEvent e) {
                               Element element = elements.get(symbol);
                               showTooltip(element, e.getLocationOnScreen());
                               button.setCursor(new Cursor(Cursor.HAND_CURSOR));
                           }
                           
                           /**
                            * Hide tooltip when mouse leaves the button
                            */
                           @Override
                           public void mouseExited(MouseEvent e) {
                               tooltip.setVisible(false);
                           }
                     
                 });
                 
                 
                 return button;
             
         }
        
        
     /**
     * Displays a tooltip with detailed information about an element
     * 
     * @param element The Element object containing the data to display
     * @param location The screen location where the mouse entered the button
     */
      private void showTooltip(Element element, Point location) {
      
             // Update tooltip content with element information
             tooltip.updateContent(element);
          
            // Get the current size of the tooltip
            Dimension tooltipSize = tooltip.getSize();
            
            // Calculate position for the tooltip (offset from mouse pointer)
            int x = location.x + 15;
            int y = location.y - tooltipSize.height - 15;
            
           // Get screen dimensions to ensure tooltip stays on screen
           int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
           
            // Adjust y-coordinate if tooltip would go off the top of the screen
            if (y < 0) {
                y = location.y + 15;
            }
          
            // Adjust x-coordinate if tooltip would go off the right side of the screen
            if (x > 0) {
                if (x + tooltipSize.width > screenWidth + (tooltipSize.width / 4)) {
                    x = screenWidth - tooltipSize.width + (tooltipSize.width / 2);
                } else { 
                    x = location.x + 15; 
                } 
            }
            
            // Set the tooltip's location and fade it in with animation
            tooltip.setLocation(x, y);
            tooltip.fadeIn(x, y);
            
      }
         
         
         
         
      /**
     * Custom tooltip window class with fancy styling and animation effects
     */
      private static class CustomTooltip extends JWindow {
          
                  // UI components for the tooltip
                private final JPanel contentPane;
                private final JLabel titleLabel;
                private final JLabel detailsLabel;
                private final JLabel descriptionLabel;
        
                // Animation properties
                private javax.swing.Timer fadeTimer;
                private float opacity = 0.0f;
                private static final int ANIMATION_DURATION = 200; // milliseconds
                private static final int ANIMATION_STEPS = 20;
                
                /**
                * Constructor - Creates a custom tooltip with styling
                */
                 public CustomTooltip() {
                           // Make the window background transparent
                           setBackground(new Color(0, 0, 0, 0));
                           
                          // Create custom panel with painting overridden for effects
                          contentPane = new JPanel() {
                              
                                /**
                                * Custom painting for the tooltip
                                */
                               @Override
                               protected void paintComponent(Graphics g) {
                                   
                                   Graphics2D g2d = (Graphics2D) g;
                                    // Enable high quality rendering settings
                                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                                            RenderingHints.VALUE_ANTIALIAS_ON);
                                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
                                            RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
                                    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, 
                                            RenderingHints.VALUE_RENDER_QUALITY);

                                   // Create main background shape with rounded corners
                                    int width = getWidth();
                                    int height = getHeight();
                                    RoundRectangle2D.Float background = new RoundRectangle2D.Float(
                                            0, 0, 
                                            width - 1, 
                                            height - 1, 
                                            16, 
                                            16
                                    );
                                    
                                    // Create drop shadow effect with fading based on animation
                                    g2d.setComposite(AlphaComposite.getInstance(
                                            AlphaComposite.SRC_OVER, opacity * 0.4f));
                                    g2d.setColor(Color.BLACK);
                                    g2d.fill(new RoundRectangle2D.Float(4, 4, width - 1, height - 1, 16, 16));

                                    // Create gradient background with animated opacity
                                    g2d.setComposite(AlphaComposite.getInstance(
                                            AlphaComposite.SRC_OVER, opacity));
                                    
                                    Paint gradientPaint = new LinearGradientPaint(
                                        0, 0,
                                        0, height,
                                        new float[]{0f, 1f}, // Gradient stops
                                        new Color[]{
                                            new Color(40, 44, 52), // Top color
                                            new Color(30, 33, 40)  // Bottom color
                                        }
                                    );
                                    g2d.setPaint(gradientPaint);
                                    g2d.fill(background);
                                    
                                    // Add subtle inner glow effect
                                    g2d.setComposite(AlphaComposite.getInstance(
                                            AlphaComposite.SRC_OVER, opacity * 0.1f));
                                    g2d.setColor(Color.WHITE);
                                    g2d.setStroke(new BasicStroke(15f));
                                    g2d.draw(new RoundRectangle2D.Float(2, 2, width - 5, height - 5, 15, 15));

                                    // Add border with semi-transparent white
                                    g2d.setComposite(AlphaComposite.getInstance(
                                            AlphaComposite.SRC_OVER, opacity * 0.5f));
                                    g2d.setColor(new Color(140, 140, 140));
                                    g2d.setStroke(new BasicStroke(2f));
                                    g2d.draw(background);
                    
                                   // Reset composite to fully opaque for content
                                    g2d.setComposite(AlphaComposite.getInstance(
                                            AlphaComposite.SRC_OVER, 1f));

                               }
                              
                          };
                          
                            // Set up the content panel with vertical layout
                            contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
                            contentPane.setOpaque(false);
                            contentPane.setBorder(BorderFactory.createEmptyBorder(16, 20, 16, 20));
                            
                            // Create title label with bold styling
                            titleLabel = new JLabel();
                            titleLabel.setForeground(new Color(225, 225, 225, 1));
                            titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 20));
                            titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

                            // Create details label for atomic properties
                            detailsLabel = new JLabel();
                            detailsLabel.setForeground(new Color(200, 200, 200));
                            detailsLabel.setFont(new Font("Segoe UI", Font.PLAIN, 14));
                            detailsLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

                            // Create description label for element info
                            descriptionLabel = new JLabel();
                            descriptionLabel.setForeground(new Color(160, 160, 160));
                            descriptionLabel.setFont(new Font("Segoe UI", Font.ITALIC, 14));
                            descriptionLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

                            // Add components to the panel with spacing
                            contentPane.add(titleLabel);
                            contentPane.add(Box.createVerticalStrut(12)); // Add spacing
                            contentPane.add(detailsLabel);
                            contentPane.add(Box.createVerticalStrut(8));  // Add spacing
                            contentPane.add(descriptionLabel);
                            
                           // Set the content pane for this window
                           setContentPane(contentPane);

                            // Initialize animation timer for fade-in effect
                            fadeTimer = new javax.swing.Timer(
                                    ANIMATION_DURATION / ANIMATION_STEPS, (ActionEvent e) -> {
                                        
                                    opacity = Math.min(1.0f, opacity + (1.0f / ANIMATION_STEPS));
                                    repaint();
                                    if (opacity >= 1.0f) {
                                        fadeTimer.stop();
                                    }
                            });

                 }
                 
                /**
                * Animates the tooltip fading in at the specified location
                * 
                * @param x X-coordinate for tooltip position
                * @param y Y-coordinate for tooltip position
                */
               public void fadeIn(int x, int y) {
                   setLocation(x, y);
                   opacity = 0.0f; // Start fully transparent
                   setVisible(true);
                   fadeTimer.restart(); // Begin fade-in animation
               }
               
               
            /**
            * Updates the tooltip content with element information
            * 
            * @param element The Element object containing data to display
            */
            public void updateContent(Element element) {
                    // Add an icon and set the element name and symbol as the title
                    String iconText = "⚛ ";  // Unicode atom symbol
                    titleLabel.setText(String.format(
                            "<html>%s%s <span style='color: #88B8FF'>(%s)</span></html>",
                        iconText, element.name, element.symbol));
                    
                    // Format detailed information with HTML formatting
                    detailsLabel.setText(String.format("<html>" +
                        "<span style='color: #88B8FF'>Atomic Number:</span> %d<br>" +
                        "<span style='color: #88B8FF'>Atomic Mass:</span> %.3f<br>" +
                        "<span style='color: #88B8FF'>Category:</span> %s" +
                        "</html>",
                        element.atomicNumber, element.atomicMass, element.category));
                    
                     // Wrap description text with HTML for proper text wrapping
                    descriptionLabel.setText("<html><div style='width: 300px'>" + element.description + "</div></html>");
                    
                    // Resize the tooltip to fit the content
                    pack();
                    
                    // Ensure minimum width for consistent appearance
                    setSize(Math.max(getWidth(), 400), getHeight());

            }

      }
         
         
         
         
         
         
     
     /**
     * Returns an appropriate color for each element category
     * 
     * @param category The element category (e.g., "Noble Gas", "Alkali Metal")
     * @return Color object representing the category
     */
    private Color getCategoryColor(String category) {
        // Use switch expression to map categories to colors
        return switch (category) {
            case "Alkali Metal" -> new Color(255, 105, 97);          // Reddish
            case "Alkaline Earth Metal" -> new Color(255, 178, 102); // Orange
            case "Transition Metal" -> new Color(255, 228, 105);     // Yellow
            case "Post-Transition Metal" -> new Color(158, 216, 105); // Light green
            case "Metalloid" -> new Color(105, 255, 178);            // Turquoise
            case "Nonmetal" -> new Color(105, 228, 255);            // Light blue
            case "Noble Gas" -> new Color(105, 153, 255);           // Blue
            case "Lanthanide" -> new Color(178, 105, 255);          // Purple
            case "Actinide" -> new Color(255, 105, 255);            // Pink
            default -> new Color(200, 200, 200);                    // Grey (default)
        };
    }
         
         
        
        
        
     /**
     * Initializes the elements HashMap with all periodic table elements
     * This method creates Element objects for all chemical elements
     */
      private void initializeElements() {
      
                  // Row 1
                addElement(1, "H", "Hydrogen", 1.008, "Nonmetal", "Lightest element");
                addElement(2, "He", "Helium", 4.003, "Noble Gas", "Inert gas");
                
                // Row 2
                addElement(3, "Li", "Lithium", 6.941, "Alkali Metal", "Highly reactive metal");
                addElement(4, "Be", "Beryllium", 9.012, "Alkaline Earth Metal", "Toxic metal");
                addElement(5, "B", "Boron", 10.811, "Metalloid", "Semiconductor");
                addElement(6, "C", "Carbon", 12.011, "Nonmetal", "Basis for organic chemistry");
                addElement(7, "N", "Nitrogen", 14.007, "Nonmetal", "Essential for life");
                addElement(8, "O", "Oxygen", 15.999, "Nonmetal", "Essential for respiration");
                addElement(9, "F", "Fluorine", 18.998, "Nonmetal", "Most reactive nonmetal");
                addElement(10, "Ne", "Neon", 20.180, "Noble Gas", "Used in signs");
                
                 // Row 3
                addElement(11, "Na", "Sodium", 22.990, "Alkali Metal", "Highly reactive metal");
                addElement(12, "Mg", "Magnesium", 24.305, "Alkaline Earth Metal", "Light structural metal");
                addElement(13, "Al", "Aluminum", 26.982, "Post-Transition Metal", "Common structural metal");
                addElement(14, "Si", "Silicon", 28.086, "Metalloid", "Semiconductor");
                addElement(15, "P", "Phosphorus", 30.974, "Nonmetal", "Essential for life");
                addElement(16, "S", "Sulfur", 32.065, "Nonmetal", "Yellow nonmetal");
                addElement(17, "Cl", "Chlorine", 35.453, "Nonmetal", "Toxic green gas");
                addElement(18, "Ar", "Argon", 39.948, "Noble Gas", "Inert gas");
                
                // Row 4
                addElement(19, "K", "Potassium", 39.098, "Alkali Metal", "Essential for life");
                addElement(20, "Ca", "Calcium", 40.078, "Alkaline Earth Metal", "Essential for bones");
                addElement(21, "Sc", "Scandium", 44.956, "Transition Metal", "Rare earth metal");
                addElement(22, "Ti", "Titanium", 47.867, "Transition Metal", "Strong light metal");
                addElement(23, "V", "Vanadium", 50.942, "Transition Metal", "Hard metal");
                addElement(24, "Cr", "Chromium", 51.996, "Transition Metal", "Shiny hard metal");
                addElement(25, "Mn", "Manganese", 54.938, "Transition Metal", "Hard brittle metal");
                addElement(26, "Fe", "Iron", 55.845, "Transition Metal", "Magnetic metal");
                addElement(27, "Co", "Cobalt", 58.933, "Transition Metal", "Magnetic metal");
                addElement(28, "Ni", "Nickel", 58.693, "Transition Metal", "Hard metal");
                addElement(29, "Cu", "Copper", 63.546, "Transition Metal", "Conductive metal");
                addElement(30, "Zn", "Zinc", 65.380, "Transition Metal", "Blue-white metal");
                addElement(31, "Ga", "Gallium", 69.723, "Post-Transition Metal", "Low melting point");
                addElement(32, "Ge", "Germanium", 72.640, "Metalloid", "Semiconductor");
                addElement(33, "As", "Arsenic", 74.922, "Metalloid", "Toxic metalloid");
                addElement(34, "Se", "Selenium", 78.960, "Nonmetal", "Photovoltaic");
                addElement(35, "Br", "Bromine", 79.904, "Nonmetal", "Liquid nonmetal");
                addElement(36, "Kr", "Krypton", 83.798, "Noble Gas", "Inert gas");
                
                // Row 5
                addElement(37, "Rb", "Rubidium", 85.468, "Alkali Metal", "Soft silver metal");
                addElement(38, "Sr", "Strontium", 87.620, "Alkaline Earth Metal", "Soft metal");
                addElement(39, "Y", "Yttrium", 88.906, "Transition Metal", "Rare earth metal");
                addElement(40, "Zr", "Zirconium", 91.224, "Transition Metal", "Hard metal");
                addElement(41, "Nb", "Niobium", 92.906, "Transition Metal", "Superconductor");
                addElement(42, "Mo", "Molybdenum", 95.960, "Transition Metal", "High melting point");
                addElement(43, "Tc", "Technetium", 98.000, "Transition Metal", "Radioactive metal");
                addElement(44, "Ru", "Ruthenium", 101.070, "Transition Metal", "Hard white metal");
                addElement(45, "Rh", "Rhodium", 102.906, "Transition Metal", "Noble metal");
                addElement(46, "Pd", "Palladium", 106.420, "Transition Metal", "Noble metal");
                addElement(47, "Ag", "Silver", 107.868, "Transition Metal", "Precious metal");
                addElement(48, "Cd", "Cadmium", 112.411, "Transition Metal", "Toxic metal");
                addElement(49, "In", "Indium", 114.818, "Post-Transition Metal", "Soft metal");
                addElement(50, "Sn", "Tin", 118.710, "Post-Transition Metal", "Low melting point");
                addElement(51, "Sb", "Antimony", 121.760, "Metalloid", "Semiconductor");
                addElement(52, "Te", "Tellurium", 127.600, "Metalloid", "Semiconductor");
                addElement(53, "I", "Iodine", 126.904, "Nonmetal", "Essential nutrient");
                addElement(54, "Xe", "Xenon", 131.293, "Noble Gas", "Inert gas");
                
                // Row 6
                addElement(55, "Cs", "Cesium", 132.905, "Alkali Metal", "Most reactive metal");
                addElement(56, "Ba", "Barium", 137.327, "Alkaline Earth Metal", "Reactive metal");
                addElement(57, "La", "Lanthanum", 138.905, "Lanthanide", "Rare earth metal");
                addElement(58, "Ce", "Cerium", 140.116, "Lanthanide", "Rare earth metal");
                addElement(59, "Pr", "Praseodymium", 140.908, "Lanthanide", "Rare earth metal");
                addElement(60, "Nd", "Neodymium", 144.242, "Lanthanide", "Magnetic rare earth");
                addElement(61, "Pm", "Promethium", 145.000, "Lanthanide", "Radioactive metal");
                addElement(62, "Sm", "Samarium", 150.360, "Lanthanide", "Rare earth metal");
                addElement(63, "Eu", "Europium", 151.964, "Lanthanide", "Rare earth metal");
                addElement(64, "Gd", "Gadolinium", 157.250, "Lanthanide", "Rare earth metal");
                addElement(65, "Tb", "Terbium", 158.925, "Lanthanide", "Rare earth metal");
                addElement(66, "Dy", "Dysprosium", 162.500, "Lanthanide", "Rare earth metal");
                addElement(67, "Ho", "Holmium", 164.930, "Lanthanide", "Rare earth metal");
                addElement(68, "Er", "Erbium", 167.259, "Lanthanide", "Rare earth metal");
                addElement(69, "Tm", "Thulium", 168.934, "Lanthanide", "Rare earth metal");
                addElement(70, "Yb", "Ytterbium", 173.054, "Lanthanide", "Rare earth metal");
                addElement(71, "Lu", "Lutetium", 174.967, "Lanthanide", "Rare earth metal");
                addElement(72, "Hf", "Hafnium", 178.490, "Transition Metal", "High melting point");
                addElement(73, "Ta", "Tantalum", 180.948, "Transition Metal", "Hard metal");
                addElement(74, "W", "Tungsten", 183.840, "Transition Metal", "Highest melting point");
                addElement(75, "Re", "Rhenium", 186.207, "Transition Metal", "Heavy metal");
                addElement(76, "Os", "Osmium", 190.230, "Transition Metal", "Densest natural element");
                addElement(77, "Ir", "Iridium", 192.217, "Transition Metal", "Hard dense metal");
                addElement(78, "Pt", "Platinum", 195.084, "Transition Metal", "Noble metal");
                addElement(79, "Au", "Gold", 196.967, "Transition Metal", "Precious metal");
                addElement(80, "Hg", "Mercury", 200.590, "Transition Metal", "Liquid metal");
                addElement(81, "Tl", "Thallium", 204.383, "Post-Transition Metal", "Toxic metal");
                addElement(82, "Pb", "Lead", 207.200, "Post-Transition Metal", "Heavy metal");
                addElement(83, "Bi", "Bismuth", 208.980, "Post-Transition Metal", "Slightly radioactive");
                addElement(84, "Po", "Polonium", 209.000, "Post-Transition Metal", "Radioactive metal");
                addElement(85, "At", "Astatine", 210.000, "Metalloid", "Radioactive halogen");
                addElement(86, "Rn", "Radon", 222.000, "Noble Gas", "Radioactive gas");
                
                // Row 7
                addElement(87, "Fr", "Francium", 223.000, "Alkali Metal", "Highly radioactive");
                addElement(88, "Ra", "Radium", 226.000, "Alkaline Earth Metal", "Radioactive metal");
                addElement(89, "Ac", "Actinium", 227.000, "Actinide", "Radioactive metal");
                addElement(90, "Th", "Thorium", 232.038, "Actinide", "Radioactive metal");
                addElement(91, "Pa", "Protactinium", 231.036, "Actinide", "Radioactive metal");
                addElement(92, "U", "Uranium", 238.029, "Actinide", "Nuclear fuel");
                addElement(93, "Np", "Neptunium", 237.000, "Actinide", "Radioactive metal");
                addElement(94, "Pu", "Plutonium", 244.000, "Actinide", "Nuclear fuel");
                addElement(95, "Am", "Americium", 243.000, "Actinide", "Radioactive metal");
                addElement(96, "Cm", "Curium", 247.000, "Actinide", "Radioactive metal");
                addElement(97, "Bk", "Berkelium", 247.000, "Actinide", "Radioactive metal");
                addElement(98, "Cf", "Californium", 251.000, "Actinide", "Radioactive metal");
                addElement(99, "Es", "Einsteinium", 252.000, "Actinide", "Radioactive metal");
                addElement(100, "Fm", "Fermium", 257.000, "Actinide", "Radioactive metal");
                addElement(101, "Md", "Mendelevium", 258.000, "Actinide", "Radioactive metal");
                addElement(102, "No", "Nobelium", 259.000, "Actinide", "Radioactive metal");
                addElement(103, "Lr", "Lawrencium", 262.000, "Actinide", "Radioactive metal");
                addElement(104, "Rf", "Rutherfordium", 267.000, "Transition Metal", "Synthetic element");
                addElement(105, "Db", "Dubnium", 268.000, "Transition Metal", "Synthetic element");
                addElement(106, "Sg", "Seaborgium", 269.000, "Transition Metal", "Synthetic element");
                addElement(107, "Bh", "Bohrium", 270.000, "Transition Metal", "Synthetic element");
                addElement(108, "Hs", "Hassium", 269.000, "Transition Metal", "Synthetic element");
                addElement(109, "Mt", "Meitnerium", 278.000, "Transition Metal", "Synthetic element");
                addElement(110, "Ds", "Darmstadtium", 281.000, "Transition Metal", "Synthetic element");
                addElement(111, "Rg", "Roentgenium", 282.000, "Transition Metal", "Synthetic element");
                addElement(112, "Cn", "Copernicium", 285.000, "Transition Metal", "Synthetic element");
                addElement(113, "Nh", "Nihonium", 286.000, "Post-Transition Metal", "Synthetic element");
                addElement(114, "Fl", "Flerovium", 289.000, "Post-Transition Metal", "Synthetic element");
                addElement(115, "Mc", "Moscovium", 290.000, "Post-Transition Metal", "Synthetic element");
                addElement(116, "Lv", "Livermorium", 293.000, "Post-Transition Metal", "Synthetic element");
                addElement(117, "Ts", "Tennessine", 294.000, "Metalloid", "Synthetic element");
                addElement(118, "Og", "Oganesson", 294.000, "Noble Gas", "Synthetic element");
      
      }
        
        
      
         /**
        * Returns the chemical symbol of the element at the specified position in the periodic table.
        * This method uses a 2D array representation of the periodic table to determine
        * which element (if any) should appear at the given row and column position.
        */
         private String getElementSymbol(int row, int col) {
             
                  // This 2D array represents the layout of the periodic table
                // Each row is an array of element symbols, with null values for empty spaces
                // This creates the characteristic shape of the periodic table
                 String[][] periodicTable = {
                           // Row 1 (Period 1): Only H and He with empty spaces between them
                          {"H", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "He"},
                     
                          // Row 2 (Period 2): Li and Be on left, then B through Ne on right
                         {"Li", "Be", null, null, null, null, null, null, null, null, null, null, "B", "C", "N", "O", "F", "Ne"},
                         
                         // Row 3 (Period 3): Na and Mg on left, then Al through Ar on right
                        {"Na", "Mg", null, null, null, null, null, null, null, null, null, null, "Al", "Si", "P", "S", "Cl", "Ar"},

                        // Row 4 (Period 4): Complete row with K to Kr (including transition metals)
                        {"K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr"},

                         // Row 5 (Period 5): Complete row with Rb to Xe (including transition metals)
                         {"Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe"},
           
                         // Row 6 (Period 6): Cs, Ba, La then Hf to Rn (Lanthanides are shown separately)
                        {"Cs", "Ba", "La", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn"},

                         // Row 7 (Period 7): Fr, Ra, Ac then Rf to Og (Actinides are shown separately)
                        {"Fr", "Ra", "Ac", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og"},
                        
                        // Row 8 (Lanthanides): Elements Ce to Lu
                        {null, null, null, "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", null},

                        // Row 9 (Actinides): Elements Th to Lr
                        {null, null, null, "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", null}

                 };
                 
                 // Check if the provided row and column indices are within the valid range
                // This prevents ArrayIndexOutOfBoundsException when accessing the array
                if (row >= 0 && row < periodicTable.length && col >= 0 && col < periodicTable[row].length) {
                        // Return the symbol at the specified position (which may be null)
                        return periodicTable[row][col];
                  }
                
                 // Return null if the coordinates are out of bounds
                return null;
             
         }
      
      
      
        
         /**
        * Adds a chemical element to the elements HashMap using its symbol as the key.
        * This method will be used to populate the periodic table with element data.
        */
         private void addElement(int atomicNumber, String symbol, String name,
                          double atomicMass, String category, String description) {
                // Create a new Element object with all the provided parameters
                // Then add it to the elements HashMap with the symbol as the key
                // This allows for quickly retrieving element data using its symbol
                elements.put(symbol, new Element(atomicNumber, symbol, name,
                        atomicMass, category, description));
          }

        
        
        
     /**
     * Class representing a chemical element in the periodic table.
     * This class stores all relevant information about a single element.
     */
        private static class Element {
        
             // The element's atomic number (number of protons)
             int atomicNumber;
             
             // The element's chemical symbol (1-3 letters, first letter capitalized)
            String symbol;
            
             // The element's full name
            String name;

            // The element's atomic mass in atomic mass units (amu)
            double atomicMass;
            
            // The element's chemical category (e.g., "Nonmetal", "Noble Gas")
            String category;

            // A brief description of the element's properties or uses
            String description;
            
            Element(int atomicNumber, String symbol, String name,
            double atomicMass, String category, String description) {
                    // Initialize all the instance variables with the provided values
                    this.atomicNumber = atomicNumber;
                    this.symbol = symbol;
                    this.name = name;
                    this.atomicMass = atomicMass;
                    this.category = category;
                    this.description = description;
            }

        }
        

         public static void main(String[] args) {
             SwingUtilities.invokeLater(() -> {
                PeriodicTable table = new PeriodicTable();
                table.setVisible(true);
            });
    }

}
  


The Final Result:

Periodic Table In Java Swing - 1

Periodic Table In Java Swing - 2

Periodic Table In Java Swing - 3

Periodic Table In Java Swing - 4

Periodic Table In Java Swing - 5



if you want the full source code click on the download button below




disclaimer: you will get the source code, and to make it work in your machine is your responsibility and to debug any error/exception is your responsibility this project is for the students who want to see an example and read the code not to get and run.