PROGRAMMING

m9/ JAVA
REMEMBERS




Last update:   26-07-2021

Drawing

! The Java 2D api provides classes for drawing points, lines, cursves, and rectangles. These geometry classes are part of the java.awt.geom package.

Lines

A line is a graphics primitive that connects two points.
 
import java.awt.*;
import java.awt.geom.Line2D;
import javax.swing.*;

public class App extends JFrame {
    
    public static void main(String[] args) {
    App frame = new App();
    frame.setBounds(200, 200, 400, 300);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setVisible(true);
    }
    
    public App() {
        
        JPanel p = new JPanel(){
            
            @Override
            public void paintComponent(Graphics g) {
                
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;
                
                // Vertical line --- Look Here
                g2.setColor(Color.black); // color black default
                g2.draw(new Line2D.Double(50, 10, 50, 100)); 
                    // x1, y1, x2, y2

                // Oblique line
                g2.setColor(Color.blue);
                g2.draw(new Line2D.Double(100, 10, 120, 100));
                
                // Graph
                for (int i=0; i<100; i += 10) {
                    
                    g2.setColor(Color.red);
                    g2.setStroke(new BasicStroke(5));
                                        
                    int x1 = 150 + i;
                    int x2 = x1;
                    int y1 = 10 + i;
                    int y2 = 150;
                    
                    g2.draw(new Line2D.Double(x1, y1, x2, y2));
                }
            }
        };
        
        add(p);
    }
}
... 32 lines
 

Gradient

To draw a gradient use GradientPaint class.
 
import java.awt.*;
import java.awt.geom.Line2D;
import javax.swing.*;

public class App extends JFrame {
    
    public static void main(String[] args) {
    App frame = new App();
    frame.setBounds(200, 200, 400, 300);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setVisible(true);
    }
    
    public App() {
        
        add( new JPanel() {
            
            @Override
            public void paintComponent(Graphics g1) {
                
                super.paintComponent(g1);
                Graphics2D g = (Graphics2D) g1;
                
                g.setPaint( // Look Here
                    new GradientPaint(50, 50, Color.green, 50, 150, Color.red)
                );
                g.setStroke(new BasicStroke(3));
                
                int start = 50;
                int height = 150;
                
                int x1 = 50;
                int x2 = 50;
                int y1 = 50;
                int y2 = 150;
                
                for (int i=0; i<200; i += 10) {
                    
                    x1 = start + i;
                    x2 = x1;           
                    y1 = (i < 100) ? start + i : y1 - 10;
                    y2 = y2;
 
                    g.draw(new Line2D.Double(x1, y1, x2, y2));
                }
            }
        });

    }
}
... 31 lines
 
Chart    (2/3)

Chart

Chat with grid and numbers.
 
import java.awt.*;
import java.awt.geom.Line2D;
import javax.swing.*;

public class App extends JFrame {
    
    public static void main(String[] args) {
    App frame = new App();
    frame.setBounds(200, 200, 350, 250);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setTitle("Chart with Grid & Numbers");
    frame.setVisible(true);
    }
    
    public App() {
        
        add( new JPanel() {
            
            @Override
            public void paintComponent(Graphics g1) {
                
                super.paintComponent(g1);
                Graphics2D g = (Graphics2D) g1;
                
                int[][] data = new int[][]{ // Look Here
                    {1, 5},
                    {3, 15},
                    {4, 10},
                    {6, 13},
                    {7, 17},
                };
                
                addAxisGrid(g, data); // Axis & Grids
                
                addChart(g, data); // Chart
            }
        });

    }
    
    private void addAxisGrid(Graphics2D g, int[][] data) {

        int x = 20;
        int y = 20;
        int h = 200;
        int w = 320;
        
        g.setStroke(new BasicStroke(1));
        g.setColor(Color.gray);
        g.draw(new Line2D.Double(x, x, x, h)); // vertical ax
        g.draw(new Line2D.Double(x, h, w, h)); // horizontal ax

        for (int i=0; i<18; i++) { 
                // horizontal (grid) and vertical (numbers)
            
            g.setColor(Color.decode("#dddddd")); // Look Here
            g.draw(new Line2D.Double(x+2, h - 10 - i*10, w, h - 10 - i*10)); 
                // horizontal ax
            
            g.setColor(Color.gray);
            
            if (i%5 == 0 && i > 0) {
                g.setFont(new Font("Arial", 1, 10));
                g.drawString(String.valueOf(i), i<10 ? 10 : 5, h+5-i*10); 
                    // Look Here
            }
        }
        
        
        for (int i=0; i<=30; i++) { // horizontal numbers

            g.setColor(Color.gray);
            
            if (i%5 == 0) {
                g.setFont(new Font("Arial", 1, 10));
                g.drawString(String.valueOf(i), i<10 ? x+i*10 : x+i*10-5, h+15);
            }
        }

    }
    
    // Look Here
    private void addChart(Graphics2D g, int[][] data) {
        
        g.setPaint(
            new GradientPaint(50, 50, Color.green, 50, 150, Color.red)
        );
        g.setStroke(new BasicStroke(3));
        
        int start = 30;
        int height = 150;
        
        int x1 = 20;
        int x2 = 20;
        int y1 = 20;
        int y2 = 198;
        
        for (int i=0; i<data.length; i++) {
            
            int[] row = data[i];
            
            int day = row[0];
            int cnt = row[1];
            
            x1 = start - 10 + day*10;
            x2 = x1;           
            y1 = y2 - cnt*10;
            y2 = y2;

            g.draw(new Line2D.Double(x1, y1, x2, y2));  // Look Here
            
        }
   
    }
}
... 76 lines
 
Add and delete records to the chart.
 
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.*;

public class App extends JFrame {

    private int x = 20;
    private int y = 20;
    private int height = 220;
    private int weight = 320;
    private int step = 0;
    private Map<Integer, Integer> data = 
        new LinkedHashMap<Integer, Integer>(){{
            put(1, 5); 
            put(3, 15);
            put(4, 10);
            put(6, 13);
            put(7, 17);
    }};
    private JLabel labelDay = new JLabel("Day");
    private JTextField textDay = new JTextField("5");
    private JLabel labelNo = new JLabel("No");
    private JTextField textNo= new JTextField("30");
    private JButton buttonAdd = new JButton("Add");
    private JButton buttonDelete = new JButton("Delete");
        
    public static void main(String[] args) {
    App frame = new App();
    frame.setBounds(200, 200, 350, 320);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setTitle("Chart with Grid & Numbers");
    frame.setVisible(true);
    }
    
    public App() {
        
        setStep();

        // Components
        JPanel chart = new JPanel() { 
            
            @Override
            public void paintComponent(Graphics g1) {
                
                super.paintComponent(g1);
                Graphics2D g = (Graphics2D) g1;
                
                addAxisAndGrid(g);
                paintChart(g);
            }
        };
        
        // Set font
        Font font = new Font("Arial", Font.PLAIN, 12);
        labelDay.setFont(font);
        textDay.setFont(font);
        labelNo.setFont(font);
        textNo.setFont(font);
        
        // Look Here
        buttonAdd.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                
                addNewRecord();
                setStep();
                
                repaint();
            }
        });
        
        // Look Here
        buttonDelete.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                
                int i = Integer.parseInt(textDay.getText());
                System.out.println(i);
                data.remove(i); // remove day
                
                setStep();
  
                repaint();
            }
        });
        
        // Layout
        
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
             layout.createParallelGroup()   
                .addComponent(chart)
                .addGroup(layout.createSequentialGroup()
                    .addGap(20)
                    .addComponent(labelDay).addGap(5)
                    .addComponent(textDay).addGap(5)
                    .addComponent(labelNo).addGap(5)
                    .addComponent(textNo).addGap(5)
                    .addComponent(buttonAdd)
                    .addComponent(buttonDelete)
                    .addGap(20)
                )
        );
        layout.setVerticalGroup(
                layout.createSequentialGroup()
                .addComponent(chart, 250, 250, 250)
                .addGroup(
                    layout.createParallelGroup(GroupLayout.Alignment.CENTER
                )
                    .addComponent(labelDay)
                    .addComponent(textDay) 
                    .addComponent(labelNo)
                    .addComponent(textNo)  
                    .addComponent(buttonAdd)
                    .addComponent(buttonDelete)
                )
                .addGap(20)
        );

    }
    
    private void addNewRecord() {
        
        int day = Integer.valueOf(textDay.getText());
        int no = Integer.valueOf(textNo.getText());
        data.put(day, no);
    }
    
    private void setStep() {
        
        int max = 0;
        for (Object i : data.keySet()) {
            int cnt = data.get(i);
            if (cnt > max) max = cnt; 
        }
   
        step = 200/max; 
    }
    
    
    private void addAxisAndGrid(Graphics2D g) {
        
        g.setStroke(new BasicStroke(1));
        g.setColor(Color.gray);
        g.draw(new Line2D.Double(x, x, x, height)); // vertical ax
        g.draw(new Line2D.Double(x, height, weight, height)); // horizontal ax
        
        int noOfGrids = (height-y)/step;

        for (int i=0; i<noOfGrids; i++) { // Horizontal Grid
            if (i < noOfGrids) { // skip last
                g.setColor(Color.decode("#dddddd"));
                g.draw(new Line2D.Double(
                    x+2, height-step-i*step, weight, height-step-i*step)
                ); // horizontal ax
            }
        }

        for (int i=0; i<=noOfGrids; i++) { // Vertical Numbers
            if (i%5 == 0 && i > 0) {
                g.setColor(Color.gray);
                g.setFont(new Font("Arial", 1, 10));
                g.drawString(
                    String.valueOf(i), i<10 ? x-10 : x-15, height+5-i*step
                );
            }
        }
        
        for (int i=0; i<=30; i++) { // horizontal numbers (30 days)

            g.setColor(Color.gray);
            
            if (i%5 == 0) {
                g.setFont(new Font("Arial", 1, 10));
                g.drawString(
                    String.valueOf(i), i<10 ? x+i*10 : x+i*10-5, height+15
                );
            }
        }

    }
    
    private void paintChart(Graphics2D g) {
        
        g.setPaint(new GradientPaint(x, y, Color.green, x, height, Color.red));
        g.setStroke(new BasicStroke(3));
        
        for (Object i : data.keySet()) {
                       
            int day = (Integer) i;
            int cnt = data.get(i);
            
            int x1 = x + day*10;
            int x2 = x1; 
            int y2 = height-2;
            int y1 = y2 - cnt*step;

            g.draw(new Line2D.Double(x1, y1, x2, y2));  
        }
   
    }
}
... 159 lines
 
Add a line using mouse (drag mouse up), double click on line to delete it. Drag window to resize graph.
 
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.util.*;
import javax.swing.*;

public class App extends JFrame {
    
    final static private App frame = new App();
    
    public static void main(String[] args) {
    
    frame.setBounds(200, 200, 350, 280);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setTitle("Chart (mouse dragged to draw line)");
    frame.setVisible(true);
    }
    
    public App() {
        
        final Chart chart = new Chart();
        add(chart);
        
        getRootPane().addComponentListener(new ComponentAdapter() {
            
            // Look Here
            @Override public void componentResized(ComponentEvent e) {
                
                Dimension d = frame.getSize();
                
                chart.step = (d.height - 80)/20;
                chart.height = d.height - 60;
                chart.width = d.width - 30;
                chart.stepMonth = (chart.width)/chart.days;
            }
        });
    }     
}

class Chart extends JPanel {
    
    private int x = 20;
    private int y = 20;
    public int height = 220;
    public int width = 320;
    public int days = 30;
    private int currDay = 0;
    public int step = 10;
    public int stepMonth = (width - 20)/days;
    private int stroke = 3;
    private final Map<Integer, Integer> data = 
        new LinkedHashMap<Integer, Integer>(){{
            put(1, 5); 
            put(3, 15);
            put(4, 10);
            put(6, 13);
            put(7, 17);
    }};

    {
        addMouseListener(new MouseAdapter(){
            
            // Look Here
            @Override public void mousePressed(MouseEvent e) {
                
                currDay = (e.getX() - x)/stepMonth;
            
                if (e.getButton() == 1) { // Left clicked
                    if (data.get(currDay) == null) { // Not exists
                        if (e.getY() == height - y) {
                            addNewRecord(String.valueOf(currDay), "1");
                            repaint();
                        }
                    } 
                }

                if (e.getClickCount() == 2) { // Double click
                    if (data.get(currDay) != null) { // If exists
                        deleteRecord(currDay); // Delete it
                        repaint();
                    } 
                }
            }
        });
        
        // Look Here
        addMouseMotionListener(new MouseMotionAdapter(){
            @Override public void mouseDragged(MouseEvent e) {
                if (currDay > 0) {
                    data.put(currDay, (height - e.getY())/step);
                    repaint();
                }
            }
        });
    }

    @Override
    public void paintComponent(Graphics g1) {

        super.paintComponent(g1);
        Graphics2D g = (Graphics2D) g1;
        addAxisAndGrid(g);
        paintChart(g);
    }   
    
    private void addAxisAndGrid(Graphics2D g) {
        
        g.setStroke(new BasicStroke(1));
        g.setColor(Color.gray);
        g.draw(new Line2D.Double(x, x, x, height)); // Vertical ax
        g.draw(new Line2D.Double(x, height, width, height)); // Horizontal ax
        
        int noOfGrids = (height-y)/step;

        for (int i=0; i<noOfGrids; i++) { // Horizontal Grid
            if (i < noOfGrids) { // skip last
                g.setColor(Color.decode("#dddddd"));
                g.draw(new Line2D.Double(
                    x+2, height-step-i*step, width, height-step-i*step)
                ); // Horizontal grids
            }
        }
        
        
        for (int i=0; i<=noOfGrids; i++) { // Vertical Numbers
            if (i%5 == 0 && i > 0) {
                g.setColor(Color.gray);
                g.setFont(new Font("Arial", 1, 10));
                g.drawString(
                    String.valueOf(i), i<10 ? x-10 : x-15, height+5-i*step
                );
            }
        }
        
        for (int i=0; i<=days; i++) { // Horizontal numbers (30 days)
            g.setColor(Color.gray);
            g.setFont(new Font("Arial", 1, 10));

            if (i%2 == 0) {
                g.drawString(
                    String.valueOf(i), 
                    i<10 ? x+i*stepMonth : x+i*stepMonth-5, height+15
                );
            }   
        }

    }
    
    private void paintChart(Graphics2D g) { // Chart
        
        g.setPaint(new GradientPaint(x, y, Color.green, x, height, Color.red));
        g.setStroke(new BasicStroke(stroke));
        
        for (Object i : data.keySet()) { // Vertical lines (chart values)
                       
            int day = (Integer) i;
            int cnt = data.get(i);
            
            int x1 = x + day*stepMonth;
            int x2 = x1; 
            int y2 = height-2;
            int y1 = y2 - cnt*step;

            g.draw(new Line2D.Double(x1, y1, x2, y2));  
        }
   
    }
    
    public void addNewRecord(String d, String n) {
        int day = Integer.valueOf(d);
        int no = Integer.valueOf(n);
        data.put(day, no);
    }
    
    public void deleteRecord(int day) {
        data.remove(currDay);
    }
}
... 134 lines
 
Mouse Drawing    (3/3)

Mouse Drawing

Mouse Line

! Mouse events notify when the user uses the mouse. The MouseListener interface implements mousePressed and mouseReleased functions.
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.*;

public class App extends JFrame {

    public static void main(String[] args) {
        App frame = new App(); 
    frame.setBounds(200, 200, 300, 200);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setTitle("Draw line with the mouse");
    frame.setVisible(true);
    }
    
    public App() {

        JPanel p = new JPanel() {
            Point start = null; // Look Here
            Point end = null;
            {
                addMouseListener(new MouseAdapter() { // Look Here
                    @Override public void mousePressed(MouseEvent e) {
                        start = e.getPoint();
                    }
                    @Override public void mouseReleased(MouseEvent e) {
                        start = null;
                        end = null;
                    }
                });
                
                addMouseMotionListener(new MouseMotionAdapter() {
                    @Override public void mouseDragged(MouseEvent e) {
                        end = e.getPoint();
                        repaint();
                    }
                });
            }
            @Override public void paint(Graphics g) {
                super.paint(g);
                if (start != null) {
                    g.setColor(Color.red); // Look Here
                    g.drawLine(start.x, start.y, end.x, end.y);
                }
            }            
        };
        add(p);      
    }
}
... 41 lines
 

Mouse gradient

Drawing gradient line with the mouse (chart).
 
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import javax.swing.*;

public class App extends JFrame {

    public static App frame = new App(); 
    
    public static void main(String[] args) {
    
        frame.setBounds(200, 200, 350, 320);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setTitle("Chart with Grid & Numbers");
    frame.setVisible(true);
    }
    
    public App() {
               
        final Chart chart = new Chart();

        chart.addMouseMotionListener(new MouseMotionAdapter() {
           
            @Override
            public void mouseDragged(MouseEvent e) { // --- Look Here --- //
                chart.drawLine(e.getY());
                frame.repaint();
            }
        });
        
        add(chart);
    }

}


class Chart extends JPanel {
    
    public int x = 50;
    public int y = 50;
    public int height = 200;
    public int weight = 30;
    public Line2D line = new Line2D.Double(x, y, x, height);
 
    @Override
    public void paintComponent(Graphics g1) {
        super.paintComponent(g1);
        Graphics2D g = (Graphics2D) g1;
        g.setPaint(new GradientPaint(x, y, Color.green, x, height, Color.red));
        g.setStroke(new BasicStroke(weight));
        g.draw(line);
    }
    
    public void drawLine(int yy) {
        
        line = new Line2D.Double(50, yy, 50, height);
    }
}
... 37 lines
 

Questions    
Timer