Search code examples
javapaintcomponent

Why is this graphics component not working?


I am trying to draw a rectangle in the class "Graphics", but for some reason the rectangle does not appear, but the program returns no errors. I have never experience issues such as this before so I am rather confused.

Main()

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Main
{

    public Main()
    {
        JFrame window = new JFrame();

        Sound soundCall = new Sound();
        Graphics graphicsCall = new Graphics();

        final JPanel container = new JPanel();

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.getContentPane().add(container);
        window.setSize(600, 400);
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        window.setResizable(false);

    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new Main();
            }
        });

    }

Graphics()

import java.awt.Color;
import java.awt.Graphics2D;

import javax.swing.JPanel;

public class Graphics extends JPanel
{

    public void paintComponent(java.awt.Graphics g)
    { 
        super.paintComponent(g);
        g.setColor(Color.GRAY);
        g.drawRect(500, 500, 500, 500);
    }

}

EDIT FOR HOVERCRAFT

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Main
{

    public Main()
    {
        JFrame window = new JFrame();

        Sound soundCall = new Sound();
        Draw drawCall = new Draw();

        final JPanel container = new JPanel();

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.getContentPane().add(drawCall);
        window.setSize(600, 400);
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        window.setResizable(false);

    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new Main();
            }
        });

    }

}

Through adding this window.getContentPane().add(drawCall); asks me to change drawCall to a Component

EDIT 2:

public class Draw 
{

    public class Graphics extends JPanel
    {

        public void paintComponent(java.awt.Graphics g)
        { 
            super.paintComponent(g);
            g.setColor(Color.GRAY);
            g.drawRect(0, 0, 500, 500);
        }

    }


}

ERROR The method add(Component) in the type Container is not applicable for the arguments (Draw)


Solution

  • You add your graphicsCall variable to nothing, and so it will not be displayed. Solution: add it to a container such as that JPanel that you just created, or perhaps directly to the JFrame's contentPane.

    i.e., change this:

        JFrame window = new JFrame();
    
        Sound soundCall = new Sound();
        Graphics graphicsCall = new Graphics();
    
        final JPanel container = new JPanel();
    
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.getContentPane().add(container);
    

    to this:

        JFrame window = new JFrame();
    
        Sound soundCall = new Sound();
        Graphics graphicsCall = new Graphics();
    
        // final JPanel container = new JPanel();
    
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.getContentPane().add(soundCall);
    

    As an aside, you will want to re-name that class from Graphics to something else, or else you risk confusing yourself or your compiler since there already exists a critical Java class with that name.

    Also, avoid using setSize(...). Better to have your drawing JPanel override getPreferredSize() and to call pack() on your JFrame.


    Edit
    As per MadProgrammer's astute observation, you're drawing outside of the bounds of your component.


    Edit 2
    Regarding your latest code, this:

    public class Draw 
    {
        public class Graphics extends JPanel
        {
            public void paintComponent(java.awt.Graphics g)
            { 
                super.paintComponent(g);
                g.setColor(Color.GRAY);
                g.drawRect(0, 0, 500, 500);
            }
        }
    }
    

    is useless dreck. Why are you needlessly wrapping a class inside of a class? Instead why not simply:

    public class Draw extends JPanel   {
    
        public void paintComponent(java.awt.Graphics g)
        { 
            super.paintComponent(g);
            g.setColor(Color.GRAY);
            g.drawRect(0, 0, 500, 500);
        }
    
        @Override
        public Dimension getPreferredSize() {
           // return an appropriate Dimension here
        }
    }