Search code examples
javaswingpaintcomponent

paintComponent() TextField causes Infinite loop (itself + parent)


After several days of research, I beg to ask your help. The following code works but generates significant CPU consumption. It seems that this simple text field executes "paintComponent" in a loop, not only its own, but also its parent (JPanel). Could you give me a way to correct that?

Thank you :)

package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.BorderFactory;
import javax.swing.JTextField;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

import constants.Colors;
import constants.Polices;
import constants.Spacing;

public class FieldText extends JTextField 
{
    private static final long serialVersionUID = 4526307090633268880L;
    private int xheight = 96;
    public Boolean hinted = false;                      // Définit si le     contenu == au hint ou si le contenu a été entré par l'utilisateur.
    protected Color bgColor = Colors.INPUT;             // Background normal.
    protected Color textColor = Colors.TEXT_INPUT;      // Couleur du texte normal.
    protected Color bgHinted = Colors.INPUT;            // Background lors que le placeholder est actif.
    protected Color textHinted = Colors.TEXT_INPUT;     // Couleur du texte placeholder.
    protected Font textFont = Polices.INPUTS;           // Police texte utilisateur.
    protected Font textHintFont = Polices.INPUTS_HINT;  // Police     placeholder.

    public FieldText()
    {   
        super();
        init(null, null);
    }


    /**
     * @param text String Texte du champ (valeur) 
     * @param text String PlaceHoler
     */
        public FieldText( String text, String hint )
        {   
            super();
            init(text, hint);
        }

    /**
     * @param hint Sting Texte du champ (valeur).
     */
        public FieldText( String hint )
        {   
            super();
            init(null, hint);
        }


    private void init( String text, String hint )
    {
        setOpaque(false);
        setBackground(bgColor);
        setForeground(textColor);
        setMinimumSize( new Dimension( 200, 64 ) );
        setBorder( new CompoundBorder (
                                                BorderFactory.createMatteBorder(0, 5, 0, 0, Colors.GREEN), 
                                            new EmptyBorder(     Spacing.PADDING_INPUTS )   
                                       ) 
        );
        setFont( Polices.INPUTS );

        if ( text != null && text.length() > 0 )
        {
            setText(text);  
        }

        setHeight(-1);          // Height by default.
    }


    /**
     * Définit la hauteur de l'élément. 
     * @param height int Hauteur à attribuer à l'élément. -1 pour utiliser la hauteur par défaut (xheight).
     */
        public void setHeight( int height )
        {
            setPreferredSize( new Dimension(this.getWidth(), (height>-1)     ? height : xheight) );
        }


    @Override
    protected void paintComponent(Graphics g) 
    {       
        Graphics2D g2d = (Graphics2D)g;

        GradientPaint gp = new GradientPaint (
            0, 0, new Color( 255, 255, 255, 50 ),
            0, 20, new Color( 179, 179, 179, 50 ) 
        );

        g2d.setPaint( gp );
        g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 10, 10);

        super.paintComponent(g2d);

        System.out.println("======> inside FieldText.paintComponent() ");
    }
}`

JTextField is in JPanel in JFrame.

Sorry for my bad english ...

Here a little example who causes the loop.

EDIT : Exemple integration in src/views/GuestLoginView

Here is the full src


Solution

  • Running your program doesn't cause high CPU consumption for me.

    Also the TextField probably needs constant repainting to animate the blinking cursor. One repaint every second is a reasonable expectation and it is what I see on my console.