Search code examples
javaswingjpanelpaintcomponentpreferredsize

Can't draw anything on my JPanel


Just trying to understand simple Java things. Cant'get this thing to work. Warning : lots of bad code incoming.

import java.awt.*;
import java.lang.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.LineBorder;


class DrawFrame  {
    public DrawFrame(){
        DrawPanels panelFrame=new DrawPanels();
        JFrame mainFrame=new JFrame();
        mainFrame.setLayout(new GridLayout(1,3));
        mainFrame.setVisible(true);
        mainFrame.setSize(480, 800);
        mainFrame.setTitle("Title");
        mainFrame.setResizable(false);
        mainFrame.add(panelFrame.panel1);
        mainFrame.add(panelFrame.panel2);
        mainFrame.add(panelFrame.panel3);
        //panelFrame.panel1.getGraphics();
        panelFrame.panel1.add(new DrawBlock());
        panelFrame.panel2.add(new DrawBlock());
        panelFrame.panel3.add(new DrawBlock());
        mainFrame.revalidate();
        mainFrame.repaint();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }
class DrawPanels extends JPanel{
     JPanel panel1=new JPanel();
     JPanel panel2=new JPanel();
     JPanel panel3=new JPanel();
    public DrawPanels(){
        panel1.setBackground(Color.ORANGE);
        panel2.setBackground(Color.BLACK);
        panel3.setBackground(Color.RED);
        panel1.setVisible(true);
        panel2.setVisible(true);
        panel3.setVisible(true);
        panel1.setBorder(new LineBorder(Color.BLACK));
        panel2.setBorder(new LineBorder(Color.BLACK));
        panel3.setBorder(new LineBorder(Color.BLACK));

    }
}

class DrawBlock extends JPanel{

    private static final long serialVersionUID = 1L;
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawRect(1, 1,15,15);
    }
}


public class MainClass {

    /**
     * @param args
     */
    public static void main(String[] args) {


        DrawFrame Windos=new DrawFrame();
    }}

If my class DrawBlock extends JPanel, there will be a small white square at each JPanel, however, there is no reaction for paintComponent() method. If i extend DrawBlock to JComponent, there will be no squares at all. This is probably beginners problem, but i can't resolve it.


Solution

  • The primary issue you have is the fact that DrawBlock actually has no size, therefore, the repaint manager automatically discards painting it...

    enter image description here

    Try modifying you code as such...

    public class DrawBlock extends JPanel {
    
        private static final long serialVersionUID = 1L;
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(18, 18);
        }
    
        @Override
        public void paintComponent(Graphics g) {
            System.out.println("...");
            super.paintComponent(g);
            g.setColor(Color.WHITE);
            g.drawRect(1, 1, 15, 15);
        }
    }
    

    Adding the getPreferredSize method will let the layout manager know what size your component would like to be...

    Warning - Code Review ;)

    I'm not sure why you've done what you've done, but lets leave that aside...

    You create a class that extends from JPanel (DrawPanels) that contains a number of other JPanels, but instead of adding them to the frame, you extract the panels from it and those to the frame...

    It would make more sense to simply add the DrawPanels directly to the frame itself...

    public static class DrawFrame {
    
        public DrawFrame() {
            DrawPanels panelFrame = new DrawPanels();
            JFrame mainFrame = new JFrame();
            mainFrame.setLayout(new BorderLayout());
            mainFrame.setSize(480, 800);
            mainFrame.setTitle("Title");
            mainFrame.setResizable(false);
            mainFrame.add(panelFrame);
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainFrame.setVisible(true);
        }
    }
    
    public class DrawPanels extends JPanel {
    
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        JPanel panel3 = new JPanel();
    
        public DrawPanels() {
            setLayout(new GridLayout(1, 3));
            panel1.setBackground(Color.ORANGE);
            panel2.setBackground(Color.BLACK);
            panel3.setBackground(Color.RED);
            panel1.setBorder(new LineBorder(Color.BLACK));
            panel2.setBorder(new LineBorder(Color.BLACK));
            panel3.setBorder(new LineBorder(Color.BLACK));
    
            panel1.add(new DrawBlock());
            panel2.add(new DrawBlock());
            panel3.add(new DrawBlock());
    
            add(panel1);
            add(panel2);
            add(panel3);
    
        }
    }
    

    Note - I moved the mainFrame.setVisible(true) to the last statement, this will ensure that the frame is laid out before it is made visible.

    I also moved the layout managers around a bit...