Java : How to display a label inside a Jframe component

41 views Asked by At

I try do display a text at the bottom of the container (JFrame) but it doesn't appear ....

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class Peintre extends JFrame implements MouseMotionListener {
    private int valeurX ;
    private int valeurY;
    
    public Peintre() {
        super("Programme simple de dessin");
        addMouseMotionListener(this);
        JLabel label = new JLabel("Tirer sur la souris pour dessiner");
        label.setForeground(Color.PINK);
        label.setFont(new Font("Arial", Font.PLAIN, 20));
        add(label,BorderLayout.SOUTH);
        setSize(700, 500);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void paint(Graphics g) {
        g.fillOval(valeurX, valeurY, 15, 15);
    }
    
    public void mouseDragged(MouseEvent e) {
        valeurX = e.getX();
        valeurY = e.getY();

        repaint();
    }

    public void mouseMoved(MouseEvent e) {}

    
    public static void main(String[] args) {
        new Peintre();

    }

}

I tried :

  • Check width and height of the container
  • set position of the label inside the frame
  • change the color and font-family for visibility

I wanna display multiple characters at the bottom of the frame

2

There are 2 answers

0
MadProgrammer On BEST ANSWER

As has already been stated, you've overridden a method from the parent class, but failed to either take over it's responsibility or call it's super implementation (ie paint).

As a general recommendation, avoid overriding paint of top level containers, like JFrame, instead prefer overriding paintComponent of normal containers, like JPanel. Also see Painting in AWT and Swing and Performing Custom Painting to get a better understanding of how painting works in Swing.

Further, avoid extending from top level containers, you're not adding any new functionality the class, instead prefer composition over extension. In particular, JFrame has a complex component hierarchy, which could interfere with what ever was painted by the paint method randomly.

Also, in your current code, it would be possible for your paint to interfere with the label, you might want this, you might not, but it's a consideration to keep in mind.

The following example separates the label from the paint workflow, so it's not for the two to interfere with each other.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }
    
    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
    
    protected class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            add(new PaintPane());
            add(new JLabel("You can't paint over me"), BorderLayout.SOUTH);
        }
    }
    
    protected class PaintPane extends JPanel { 

        private Point dragPoint;
        
        public PaintPane() {
            MouseAdapter adapter = new MouseAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    dragPoint = e.getPoint();
                    repaint();
                }
            };
            addMouseMotionListener(adapter);
        }
        
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (dragPoint == null) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.fillOval(dragPoint.x - 8, dragPoint.y - 8, 16, 16);
            g2d.dispose();
        }
    }
}
1
gloowa On

You have overriden

public void paint(Graphics g) 

of your JFrame. That means that any components you have added to it will not paint anymore. Call super.paint(g); as a first operation in your paint implementation to invoke the JFrame implementation, and then draw your oval.

In general you have to be careful about overriding methods in swing. Always check if they are not doing something important before doing so.