Search code examples
javajpanelgraphics2d

How do I draw multiple line looks like dividing the sectors of a panel Java?


I would like to know how to draw multiple line that looks like dividing the panel into sectors.

This is the example of lines that I wanted to draw

Below are the code of so far I've figured it out but it can only draw "x" line and a one horizontal line on the panel. I would like to know how is it possible for me to draw lines like the image above.

public void paintComponent(Graphics g){
    super.paintComponent(g);

    Graphics2D graphic = (Graphics2D)g;
    Insets insets = getInsets();
    graphic.setStroke(new BasicStroke(5.0f));
    graphic.draw(new Line2D.Double(insets.left, insets.top,getWidth()-insets.right, getHeight()-insets.bottom));
    graphic.draw(new Line2D.Double(insets.left,getHeight()-insets.bottom,getWidth()-insets.right,insets.top));
    graphic.drawLine(0,200,800,200);


}

thank you.


Solution

  • There's probably a few ways you could do this, but to me, this looks like spokes on a wheel, and since I know how to calculate a point a circle, this is where I'd fall back to.

    What do we know:

    • We know the area (size of the panel)
    • The number of segments/divisions we want
    • How to calculate a point on a circle

    So with that basic information, we can devise the angle delta which would required to draw the number of divisions evenly around the center point

    Overshoot

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.geom.Line2D;
    import java.awt.geom.Point2D;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected Point2D pointAt(double radians, double radius) {
                double x = radius * Math.cos(radians);
                double y = radius * Math.sin(radians);
    
                return new Point2D.Double(x, y);
            }
    
            protected Point2D translate(Point2D point, Point2D to) {
                Point2D newPoint = new Point2D.Double(point.getX(), point.getY());
                newPoint.setLocation(point.getX() + to.getX(), point.getY() + to.getY());
                return newPoint;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(Color.BLACK);
    
                double startAngle = 0;
                double divisions = 12;
                double delta = 360.0 / divisions;
    
                int centerX = getWidth() / 2;
                int centerY = getHeight() / 2;
                int radius = Math.min(centerX, centerY) * 2; // Overshoot the visible bounds
    
                Point2D centerPoint = new Point2D.Double(centerX, centerY);
                double angle = startAngle;
                for (int index = 0; index < divisions; index++) {
                    Point2D point = pointAt(Math.toRadians(angle), radius);
                    point = translate(point, centerPoint);
                    g2d.draw(new Line2D.Double(centerPoint, point));
                    angle += delta;
                }
    
                g2d.dispose();
            }
    
        }
    
    }
    

    Now, if you prefer not to have the lines "overshoot", then change

    int radius = Math.min(centerX, centerY) * 2; // Overshoot the visible bounds
    

    to

    int radius = Math.min(centerX, centerY);
    

    Undershoot

    Now, if you want it to look a little "nicer", you could consider adding

    RenderingHints hints = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHints(hints);
    

    into the paintComponent method before you paint anything