Search code examples
javaswingjpanellayout-managerpaintcomponent

Can't draw lines on existing panel


I'm writing my first Java GUI with Swing. I'm trying to create a panel with 10X10 dots and draw lines on these dots.

The problem is that I can create only one of the above. Meaning that I can create a matrix of 10X10 dots or create lines.

Here is my code:

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("DrawMatrix");
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new DrawRectPanel());
        frame.setSize(240, 260);
        frame.setVisible(false);
        frame.getContentPane().add(new DrawLine());
        frame.setVisible(true);
   }
}

public class DrawRectPanel extends JPanel{
   final static int DIST = 20;
   final static int MAX_ROW = 11;
   final static int MAX_COL = 11;
   int i = 1;

@Override

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    {
        // Points matrix
        int x = 0;
        for(int row = 1; row < MAX_ROW; row++)
        {
             x = row * DIST;
            for(int col = 1; col < MAX_COL; col++)
            {
                int y = col * DIST;
                g.setColor(Color.blue);
                g.drawLine(x,y,x,y+1);
            }
        }
    }
  }
}

public class DrawLine extends JPanel {

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawLine(20,20,40,40);
    }
 }

Any idea why? should I use setVisible in a different way?


Solution

  • You overwrite each component added to the contentPane on successive calls to add(..).

    I want both of them do be in the center, because i want to draw lines from point to point

    You should rather use an approach which entails a single DrawingPanel, to which objects can be drawn to. You might also need an array(s) to hold the shapes to be drawn and so the can easily be got and manipulated paintComponent(..).

    • Please do remember to do all Swing component creation and manipulation on Event Dispatch Thread via SwingUtilities.inovkeLater(..)

    • do not call setSize() on JFrame rather call pack() before setting JFrame visible rather override getPrefferedSize or setPrefferedSize of JPanel and return a dimension which fits all drawing in it.

    • No need for getContentPand.add(..) simply call add(..) on JFrame as call will be directed to contentPane

    Here is an example (basically you code with above fixes)

    enter image description here

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class Main {
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.setTitle("DrawMatrix");
                    frame.setResizable(false);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.getContentPane().add(new DrawPanel());
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }
    }
    
    class DrawPanel extends JPanel {
    
        final static int DIST = 20;
        final static int MAX_ROW = 11;
        final static int MAX_COL = 11;
        int i = 1;
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Points matrix
            int x = 0;
            for (int row = 1; row < MAX_ROW; row++) {
                x = row * DIST;
                for (int col = 1; col < MAX_COL; col++) {
                    int y = col * DIST;
                    g.setColor(Color.blue);
                    g.drawLine(x, y, x, y + 1);
                }
            }
            g.drawLine(20, 20, 40, 40);
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }
    }