javacanvasgraphicsawtjava-canvas

Java AWT canvas in the output is overiding it's own graphic contents


I was practising and came across a problem with no perfect explanation of solution. ''' package com.company;

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    public class Main extends Frame {
    
        public Main() {
    
            Button bt = new Button("Click me");
            bt.setBounds(20,40,80,30);
            bt.setBackground(Color.green);
            bt.setForeground(Color.blue);
    
            Label l1 = new Label("This is label");
            l1.setBounds(20,90,80,30);
    
            TextField tf1 = new TextField();
            tf1.setBounds(20,120,150,30);
    
            TextArea ta = new TextArea();
            ta.setBounds(20,170,350,100);
    
            Checkbox cb1 = new Checkbox("cb1");
            cb1.setBounds(200,40,40,40);
            Checkbox cb2 = new Checkbox("cb2");
            cb2.setBounds(200,65,40,40);
    
            MyCanvas cv = new MyCanvas();
    
    
            add(bt);
            add(l1);
            add(tf1);
            add(ta);
            add(cb1);
            add(cb2);
            add(cv);
    
            setSize(400,300);
            setLayout(null);
            setVisible(true);
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    Frame frame = (Frame)e.getSource();
                    frame.dispose();
                }
            });
    
            bt.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    l1.setText("button click...");
                }
            });
    
        }
    
        public static void main(String[] args) {
        // write your code here
            Main m = new Main();
        }
    }
    
    class MyCanvas extends Canvas{
        public MyCanvas(){
            setBackground(Color.cyan);
            setBounds(250,40,100,100);
        }
    
        public void paint(Graphics g){
            g.setColor(Color.red);
            g.drawOval(240,42,70,50);
            g.drawString("JAVA is best",252,94);
        }
    }

''' And the output is as shown in the image:

https://i.sstatic.net/dsxF4.png

I did find out that the graphics contents are getting hidden behind the canvas in the frame. PLease explain what is causing such output.


Solution

  • setBounds(250,40,100,100);
     
    ...
    
    g.drawString("JAVA is best",252,94);
    

    Graphics are painted relative to the component. The width of your component is only 100, so attempting to paint at 252 is out of bounds of the component.

    Try:

    g.drawString("JAVA is best",52,94);
    

    Other suggestions:

    1. Don't use AWT. Instead use Swing. Swing components start with "J". See the Swing Tutorial for Swing basics. The demo code you find there will be better quality that the code you currently have.

    2. Don't use a null layout. Swing (and AWT) were designed to be used with layout managers.