Java Create Bar Chart

How to Create a Custom Bar Chart In Java Netbeans





In this Java Tutorial we will see How To Create a Custom Bar Chart from scratch with Gradient colors using graphics class in java netbeans.

What We Are Gonna Use In This Project:

- Java Programming Language.
- NetBeans Editor.





Project Source Code:


package customchartbar;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 *
 * @author 1BestCsharp
 */
public class BarChartPanel extends JPanel{

    private boolean useOrangeGradiant = false;
    
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        // Define your data and values for the chart
        int[] values = {30,50,70,40,60,130,50,70,40,60};
        String[] labels = {"A", "B", "C", "D", "E","A2", "B2", "C2", "D2", "E2"};
         // Maximum value for scaling
        int maxValue = 130;
        // Set chart dimensions
        int chartWidth = getWidth();
        int chartHeight = getHeight();
        // Define the spacing and size of bars
        int barSpacing = 20;
        int barWidth = (chartWidth - (values.length + 1)*barSpacing) / values.length;
        // Set colors and fonts
        g.setColor(new Color(63,81,181));
        g.setFont(new Font("Arial",Font.BOLD, 12));
        // Draw horizontal lines
        int numHorizontalLines = 5;
        int horizontalSpacing = (chartHeight - 50)/numHorizontalLines;
        
        for(int i = 0; i <= numHorizontalLines; i++)
        {
            int y = chartHeight - 20 - i * horizontalSpacing;
            g.setColor(Color.lightGray);
            g.drawLine(30, y, chartWidth-20, y);
        }
        
        // Draw vertical lines
        for(int i = 0; i < values.length; i++)
        {
            int x = 30 + i * (barWidth + barSpacing);
            g.setColor(Color.lightGray);
            g.drawLine(x + barWidth, 20, x+barWidth, chartHeight-20);
        }
        
        // Draw the bars and labels
        for(int i = 0; i < values.length; i++)
        {
            int barheight = (int) ((double)values[i] / maxValue * (chartHeight - 50));
            int x = 30 + i * (barWidth + barSpacing);
            int y = chartHeight - barheight - 20;
            
            GradientPaint gradient;
            
            // Alternate between gradient colors
            if(useOrangeGradiant)
            {
                gradient = new GradientPaint(x, y, new Color(255,140,0), x + barWidth, y + barheight, Color.YELLOW);
            }
            else
            {
                 gradient = new GradientPaint(x, y, Color.blue, x + barWidth, y + barheight, Color.cyan);
            }
            
             // Toggle the flag
             useOrangeGradiant = !useOrangeGradiant;
            
            
            ((Graphics2D) g).setPaint(gradient);
            
            ((Graphics2D) g).fill(new RoundRectangle2D.Double(x,y,barWidth, barheight,20,20));
            
            // Draw the label
            String label = labels[i];
            int labelWidth = g.getFontMetrics().stringWidth(label);
            int labelX = x + (barWidth - labelWidth) / 2;
            int labelY = chartHeight - 5;
            g.setColor(Color.black);// label color
            g.drawString(label, labelX, labelY);
        }
        
        // Draw the vertical axis labels
        int numTicks = 5; // Number of ticks on the vertical axis
        int tickSpacing = (chartHeight - 50) / numTicks;
        g.setColor(Color.black);// Axis label color
        
        
        for(int i = 0; i <= numTicks; i++)
        {
            int tickValue = maxValue * i / numTicks;
            String tickLabel = Integer.toString(tickValue);
            int labelX = 5;
            int labelY = chartHeight - 20 - i * tickSpacing;
            g.drawString(tickLabel, labelX, labelY);
        }

    }
    
    
    public static void main(String[] args) {
        
        JFrame frame = new JFrame("Bar Chart");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600,400);
        frame.setLocationRelativeTo(null);
        BarChartPanel chartPanel = new BarChartPanel();
        chartPanel.setBackground(Color.white);
        frame.add(chartPanel);
        frame.setVisible(true);
        
    }
    
}



The Final Result:







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








PHP - Comment System with PHP and MySQL

How to Create a Comment System Using PHP and MySQL Database

How to Create a Comment System Using PHP and MySQL Database


In this PHP project tutorial, we will see how to create a basic comment system using PHP, HTML, CSS, JavaScript, and a MySQL database
The system connects to a MySQL database to store and retrieve comments.
Users can submit comments and replies to specific comments, and there is an option to cancel replies.








Project Source Code:


- Create a Class "db_connect" To Connect Our Form With Database

This file establishes a database connection using PDO (PHP Data Objects) and sets up error handling for the connection.


<?php

$servername = "localhost";
$username = "root";
$password = "";
$dbname = "php-comments";

try{
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn -> setAttribute(PDO:: ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
echo "connection failed: " .$e->getMessage();
die();
}

?>




- On The Comments Page: Creating the HTML Structure

This file contains an HTML form for submitting comments, retrieves and displays comments from a database, allows users to reply to comments, and integrates JavaScript for toggling the display of the reply form.


<!DOCTYPE html>
<html>
<head>
<title>Comment System</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>

<div class="container">

<form action="operation.php" method="post">
<label for="name"> Name: </label>
<input type="text" name="name" id="name" required>

<label for="comment"> Comment: </label>
<textarea name="comment" id="comment" rows="5" required></textarea>

<input type="submit" name="submit" value="Post Comment">
</form>

<div class="comments">
<h2>Comments</h2>
<div class="comment-container">
<?php
include 'operation.php';
display_comments($comments);
?>
<!-- test -->
<!-- <ul>
<li class="comment">
<div class="comment-info">
<span class="comment-name">Username</span>
</div>

<div class="comment-text">comment text here</div>
<button class="reply-button">Reply</button>

</li>
</ul> -->

</div>

<form id="reply-form" method="post" action="operation.php">

<input type="hidden" name="parent-id" id="parent-id">
<label for="name">Name:</label>
<input type="text" name="name" id="reply-name">
<input type="hidden" name="reply-to-name" id="reply-to">
<label for="reply-comment-text">Comment:</label>
<textarea name="reply-comment-text" id="reply-comment-text" rows="5" required></textarea>
<button type="submit" name="submit-reply">Submit</button>
<button name="cancel" id="cancel-button">Cancel</button>

</form>


</div>
</div>

<script src="testjs.js"></script>

</body>
</html>



- The Operation File: Handling Form Submissions with PHP

This file manages comment and reply submissions by processing form data, inserting it into the database, and then redirecting to the comments page. 
It also retrieves comments from the database, organizes them hierarchically, and prepares them for display on the web page.


<?php

// Require the database connection file
require_once 'db-connect.php';

// Check if the request method is POST
if($_SERVER['REQUEST_METHOD'] === 'POST'){

// Check if the submit button was clicked
if(isset($_POST['submit'])){

// Check if the name and comment fields are not empty
if(!empty($_POST['name']) && !empty($_POST['comment']))
{
// Get the name and comment values from the form
$name = $_POST['name'];
$comment = $_POST['comment'];
$parent_id = null;

// Prepare an SQL statement to insert the new comment into the database
$stmt = $conn->prepare('INSERT INTO `comments`(`name`, `comment_text`, `parent_id`)
VALUES (:name,:comment,:parent_id)');

// Execute the SQL statement, passing in the name, comment, and parent_id values
$stmt->execute(array(':name'=>$name, ':comment'=>$comment, ':parent_id'=>$parent_id));

// Redirect the user to the comments page after the comment has been added
header('Location: comments.php');
exit;

}
}


if(isset($_POST['submit-reply'])){

$name = filter_input(INPUT_POST,'name',FILTER_SANITIZE_STRING);
$comment_text = filter_input(INPUT_POST,'reply-comment-text',FILTER_SANITIZE_STRING);
$replyTo = filter_input(INPUT_POST,'reply-to-name',FILTER_SANITIZE_STRING);
$comment_text = $replyTo . " " . $comment_text;
$parent_id = $_POST['parent-id'];

// Check if the name and comment fields are not empty
if(!empty($_POST['name']) && !empty($_POST['reply-comment-text']))
{
// Prepare an SQL statement to insert the new comment into the database
$stmt = $conn->prepare('INSERT INTO `comments`(`name`, `comment_text`, `parent_id`)
VALUES (:name,:comment,:parent_id)');

// Execute the SQL statement, passing in the name, comment, and parent_id values
$stmt->execute(array(':name'=>$name, ':comment'=>$comment_text, ':parent_id'=>$parent_id));

// Redirect the user to the comments page after the comment has been added
header('Location: comments.php');
exit;
}

}

}


// Fetch comments
// Select all comments from the database
$stmt = $conn->query('SELECT * FROM `comments`');

// Initialize an empty array to store the comments
$comments = array();

// Loop through each row of the result set and create a comment array
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){

// Create an array to represent the comment
$comment=array(
'id' => $row['id'],
'name' => $row['name'],
'comment' => $row['comment_text'],
'parent_id' => $row['parent_id'],
'replies' => array()
);

// Find parent comment and add this comment as its reply
if($row['parent_id'] !== null)
{
foreach($comments as &$parent){
if($parent['id'] == $row['parent_id']){
$parent['replies'][] = $comment;
}
}
// Remove reference to the last element of $comments
unset($parent);

}else{
// If the comment does not have a parent, add it to the comments array
$comments[] = $comment;
}
}


/**
* This function displays comments in a hierarchical structure.
* @param array $comments An array of comments to display.
* @param int|null $parent_id The ID of the parent comment. If null, display top-level comments.
*/
function display_comments($comments, $parent_id=null){

echo'<ul>';
foreach($comments as $comment){
if($comment['parent_id'] == $parent_id){
// Start displaying the comment
echo'<li class="comment">';
echo'<div class="comment-info">';
echo'<span class="comment-name" data-username="'.$comment['name'].'">'.$comment['name'].'</span>';
echo'</div>';
echo'<div class="comment-text">'.$comment['comment'].'</div>';

// Add reply button
if($parent_id == null){
// Display the reply button for top-level comments
echo'<button class="reply-button"
data-username-text="'.$comment['name'].'"
data-parent-id="'.$comment['id'].'">Reply</button>';
}
else{
// Display the reply button for nested comments
echo'<button class="reply-button"
data-username-text="'.$comment['name'].'"
data-parent-id="'.$comment['parent_id'].'">Reply</button>';
}

// Recursively display replies to the current comment
if(!empty($comment['replies'])){
display_comments($comment['replies'], $comment['id']);
}

// End displaying the comment
echo'</li>';

}
}

echo'</ul>';

}

                                                     

- The testjs.js File: Adding JavaScript for Reply Functionality

this JavaScript file attaches click event listeners to reply buttons, enabling users to reply to comments. When a user selects "Reply," it reveals the reply form, sets the parent comment's ID, and pre-fills the user's name. Additionally, it offers a "Cancel" button for hiding the reply form.


// Get all the reply buttons and assign them to replyButtons variable
const replyButtons = document.querySelectorAll('.reply-button');

// Loop through each reply button and add a click event listener to it
replyButtons.forEach(button => {
button.addEventListener('click', event=>{
// Get the parent ID of the clicked reply button
const parent_id = event.target.getAttribute('data-parent-id');
// Get the username of the user whose comment is being replied to
const name = event.target.getAttribute('data-username-text');
// Set the name input value to '@' + the username
const replyTo = '@'+name;
// Get the reply form and the parent ID field
const replyForm = document.getElementById("reply-form");
const parentField = document.querySelector("#parent-id");
const replyToField = document.querySelector("#reply-to");
replyToField.value = replyTo;
parentField.value = parent_id;

// Show the reply form and scroll to the bottom of the form
replyForm.style.display = "block";
scrollToBottom();

console.log(replyTo);
});
});


// scroll to the bottom to see the reply form
function scrollToBottom(){
const replyForm = document.getElementById("reply-form");
replyForm.scrollIntoView({behavior:"smooth"});
}


// Get the cancel button and the reply form
const cancelButton = document.querySelector("#cancel-button");
const replyForm = document.getElementById("reply-form");

// Add a click event listener to the cancel button
cancelButton.addEventListener('click', event=>{
event.preventDefault();
// Hide the reply form
replyForm.style.display = "none";

});



                                          


////// OUTPUT : 
Comment System with PHP and MySQL

Java Custom Table Design

How to Create a Custom Scrollable Table in Java NetBeans with MySQL Database



In this Java Tutorial we will see How To Make a Custom Scrollable Table, plus how to display data from mysql database into this table in Java using NetBeans.

What We Are Gonna Use In This Project:

- Java Programming Language.
- NetBeans Editor.
MySQL Database.
- PhpMyAdmin.

What We Will Do In This Project:
- Using a Graphics2D object to draw table headers and rows with alternating row colors.
- Employs a custom JScrollPane with a ModernScrollBarUI to create a modern-looking scrollbar, the scrollbar appearance is customized using the BasicScrollBarUI class.
- Connect Java To MySQL Database, using JDBC, executes a SELECT query on the "product" table, and retrieves the data, which is stored in a list of TableRow objects.






Project Source Code (V1):



/**
 *
 * @author 1BestCsharp
 */
public class CustomTable extends JFrame {
    
    private List<TableRow> tableData;
    private JScrollPane scrollPane;
    private TablePanel tablePanel;

    public CustomTable()
    {
        
        setTitle("Custom Table Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);

        // Initialize table data
        tableData = new ArrayList<>();
        tableData.add(new TableRow("John", "Doe", "25"));
        tableData.add(new TableRow("Jane", "Smith", "30"));
        tableData.add(new TableRow("Alice", "Johnson", "22"));
        tableData.add(new TableRow("Bob", "Brown", "35"));
        tableData.add(new TableRow("Eve", "Wilson", "28"));
        tableData.add(new TableRow("John", "Doe", "25"));
        tableData.add(new TableRow("Jane", "Smith", "30"));
        tableData.add(new TableRow("Alice", "Johnson", "22"));
        tableData.add(new TableRow("Bob", "Brown", "35"));
        tableData.add(new TableRow("Eve", "Wilson", "28"));
        tableData.add(new TableRow("John", "Doe", "25"));
        tableData.add(new TableRow("Jane", "Smith", "30"));
        tableData.add(new TableRow("Alice", "Johnson", "22"));
        tableData.add(new TableRow("Bob", "Brown", "35"));
        tableData.add(new TableRow("Eve", "Wilson", "28"));
        tableData.add(new TableRow("John", "Doe", "25"));
        tableData.add(new TableRow("Jane", "Smith", "30"));
        tableData.add(new TableRow("Alice", "Johnson", "22"));
        tableData.add(new TableRow("Bob", "Brown", "35"));
        tableData.add(new TableRow("Eve", "Wilson", "28"));
        tableData.add(new TableRow("John", "Doe", "25"));
        tableData.add(new TableRow("Jane", "Smith", "30"));
        tableData.add(new TableRow("Alice", "Johnson", "22"));
        tableData.add(new TableRow("Bob", "Brown", "35"));
        tableData.add(new TableRow("Eve", "Wilson", "28"));
        tableData.add(new TableRow("John", "Doe", "25"));
        tableData.add(new TableRow("Jane", "Smith", "30"));
        tableData.add(new TableRow("Alice", "Johnson", "22"));
        tableData.add(new TableRow("Bob", "Brown", "35"));
        tableData.add(new TableRow("Eve", "Wilson", "28"));

        // Create a table panel to hold the table
        tablePanel = new TablePanel();
        tablePanel.setBackground(Color.white);
        tablePanel.setPreferredSize(new Dimension(380, 200));

        // Create a custom scroll pane
        scrollPane = new CustomScrollPane(tablePanel);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        add(scrollPane);

    }
    
    
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
        
            new CustomTable().setVisible(true);
            
        });
        
    }
    
    
    
    // Inner class for the table panel
    private class TablePanel extends JPanel
    {
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            drawTable(g);
        }
        
    }
    
    
    // Method to draw the custom table
    private void drawTable(Graphics g){

        
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        int x = 10;
        int y = 10;
        int rowHeight = 30;
        int tableWidth = 360;
        
        
        // Draw table header
        g2d.setColor(new Color(255,121,48));
        g2d.fillRect(x, y, tableWidth, rowHeight);
        g2d.setColor(new Color(255,255,255));
        g2d.setFont(new Font("Arial",  Font.BOLD, 14));
        g2d.drawString("First Name", x+20, y+20);
        g2d.drawString("Last Name", x+140, y+20);
        g2d.drawString("Age", x+270, y+20);
        
        g2d.setColor(Color.black);
        g2d.setFont(new Font("Arial",  Font.ITALIC, 14));
        // Draw table rows with data
        for(int i = 0; i < tableData.size(); i++){
            
            TableRow rowData = tableData.get(i);
            y += rowHeight;
            g2d.setColor(Color.white);
            if(i%2 != 0){
                // Alternate row color
                g2d.setColor(new Color(181,242,238));
                g2d.fillRect(x, y, tableWidth, rowHeight);
                g2d.setColor(Color.black);
            }
            else{
                g2d.setColor(new Color(249,241,238));
                g2d.fillRect(x, y, tableWidth, rowHeight);
                g2d.setColor(Color.black);
            }
            
            g2d.drawString(rowData.getFirstName(), x+20, y+20);
            g2d.drawString(rowData.getLastName(), x+140, y+20);
            g2d.drawString(rowData.getAge(), x+270, y+20);
           
        }
        
        // Set the preferred size of the table panel to match the table content
        tablePanel.setPreferredSize(new Dimension(380, y+rowHeight+10));

    }
    
    
    
    // Inner class representing a row in the table
    private static class TableRow
    {
        private String firstName;
        private String lastName;
        private String age;
        
        
        public TableRow(String fname, String lname, String age)
        {
            this.firstName = fname;
            this.lastName = lname;
            this.age = age;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public String getAge() {
            return age;
        }
        
    }
    
    
    // Inner class for the custom scroll pane with a custom scrollbar UI
    private class CustomScrollPane extends JScrollPane{
        
        public CustomScrollPane(Component view){
            super(view);
            initializeScrollBarUI();
        }

        private void initializeScrollBarUI(){

            JScrollBar verticallScrollBar = getVerticalScrollBar();
            verticallScrollBar.setUI(new ModernScrollBarUI());
            verticallScrollBar.addAdjustmentListener((e) -> {
                repaint();
            });

        }
        
    }
    
    
    
    
    // Inner class for the custom scrollbar UI
    private class ModernScrollBarUI extends BasicScrollBarUI{
        
        private final Dimension thumbSize = new Dimension(10,40);
        
        @Override
        protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds){
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(new Color(100,100,100));
            g2d.fillRoundRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height, 0, 0); 
        }
        
        
        @Override
        protected void setThumbBounds(int x, int y, int width, int height){
            super.setThumbBounds(x, y, thumbSize.width, height);
        }
        
        
        @Override
        protected JButton createDecreaseButton(int orientation){
            return createEmptyButton();
        }
        
        
        @Override
        protected JButton createIncreaseButton(int orientation){
            return createEmptyButton();
        }
        
        private JButton createEmptyButton(){
            JButton button = new JButton();
            button.setPreferredSize(new Dimension(0,0));
            return button;
        }
        
    }
    
}





  

Project Source Code (V2 - With MySQL Database):


/**
 *
 * @author 1BestCsharp
 */
public class CustomTable_WithMySQL extends JFrame {
    
    private List<TableRow> tableData;
    private JScrollPane scrollPane;
    private TablePanel tablePanel;

    public CustomTable_WithMySQL()
    {
        
        setTitle("Custom Table Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);

        // Initialize table data
        tableData = fetchTableDataFromDatabase();

        // Create a table panel to hold the table
        tablePanel = new TablePanel();
        tablePanel.setBackground(Color.white);
        tablePanel.setPreferredSize(new Dimension(380, 200));

        // Create a custom scroll pane
        scrollPane = new CustomScrollPane(tablePanel);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        add(scrollPane);

    }
    
    
    // create a function to fetch data from database
    private List<TableRow> fetchTableDataFromDatabase()
    {
        List<TableRow> data = new ArrayList<>();
        
        try
        {
            String jdbc_url = "jdbc:mysql://localhost:3306/data_db";
            String username = "root";
            String password = "";
            
            Connection connection = DriverManager.getConnection(jdbc_url,username,password);
            Statement statement = connection.createStatement();
            String sqlQuery = "SELECT * FROM `product`";
            
            ResultSet result = statement.executeQuery(sqlQuery);
            
            while(result.next())
            {
                String id = result.getString("id");
                String name = result.getString("name");
                String price = result.getString("price");
                data.add(new TableRow(id, name, price));
            }
            
            result.close();
            statement.close();
            connection.close();
            
        }
        catch(SQLException ex){ System.out.println(ex.getMessage()); }

        return data;
    }
    
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
        
            new CustomTable_WithMySQL().setVisible(true);
            
        });
        
    }
    
    
    
    // Inner class for the table panel
    private class TablePanel extends JPanel
    {
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            drawTable(g);
        }
        
    }
    
    
    // Method to draw the custom table
    private void drawTable(Graphics g){

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            
        int x = 10;
        int y = 10;
        int rowHeight = 30;
        int tableWidth = 360;
        
        // Draw table header
        g2d.setColor(Color.orange);
        g2d.fillRect(x, y, tableWidth, rowHeight);
        g2d.setColor(new Color(255,255,255));
        g2d.setFont(new Font("Arial",  Font.BOLD, 16));
        g2d.drawString("ID", x+20, y+20);
        g2d.drawString("Name", x+140, y+20);
        g2d.drawString("Price", x+270, y+20);
        
        g2d.setColor(Color.black);
        g2d.setFont(new Font("Arial",  Font.PLAIN, 14));
        // Draw table rows with data
        for(int i = 0; i < tableData.size(); i++){
            
            TableRow rowData = tableData.get(i);
            y += rowHeight;
            g2d.setColor(Color.red);
            if(i%2 == 0){
                // Alternate row color
                g2d.setColor(Color.lightGray);
                g2d.fillRect(x, y, tableWidth, rowHeight);
                g2d.setColor(Color.white);
            }
            
            
            g2d.drawString(rowData.getFirstName(), x+20, y+20);
            g2d.drawString(rowData.getLastName(), x+140, y+20);
            g2d.drawString(rowData.getAge(), x+270, y+20);
           
        }
        
        // Set the preferred size of the table panel to match the table content
        tablePanel.setPreferredSize(new Dimension(380, y+rowHeight+10));

    }
    
    
    
    // Inner class representing a row in the table
    private static class TableRow
    {
        private String firstName;
        private String lastName;
        private String age;
        
        
        public TableRow(String fname, String lname, String age)
        {
            this.firstName = fname;
            this.lastName = lname;
            this.age = age;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public String getAge() {
            return age;
        }
        
    }
    
    
    // Inner class for the custom scroll pane with a custom scrollbar UI
    private class CustomScrollPane extends JScrollPane{
        
        public CustomScrollPane(Component view){
            super(view);
            initializeScrollBarUI();
        }

        private void initializeScrollBarUI(){

            JScrollBar verticallScrollBar = getVerticalScrollBar();
            verticallScrollBar.setUI(new ModernScrollBarUI());
            verticallScrollBar.addAdjustmentListener((e) -> {
                repaint();
            });

        }
        
    }
    
    
    
    
    // Inner class for the custom scrollbar UI
    private class ModernScrollBarUI extends BasicScrollBarUI{
        
        private final Dimension thumbSize = new Dimension(10,40);
        
        @Override
        protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds){
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(new Color(100,100,100));
            g2d.fillRoundRect(thumbBounds.x, thumbBounds.y, thumbBounds.width, thumbBounds.height, 0, 0); 
        }
        
        
        @Override
        protected void setThumbBounds(int x, int y, int width, int height){
            super.setThumbBounds(x, y, thumbSize.width, height);
        }
        
        
        @Override
        protected JButton createDecreaseButton(int orientation){
            return createEmptyButton();
        }
        
        
        @Override
        protected JButton createIncreaseButton(int orientation){
            return createEmptyButton();
        }
        
        private JButton createEmptyButton(){
            JButton button = new JButton();
            button.setPreferredSize(new Dimension(0,0));
            return button;
        }
        
    }
    
}







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