Search code examples
javaswinglabeljframe

Java : How to display a label inside a Jframe component


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


Solution

  • 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();
            }
        }
    }