簡體   English   中英

paintComponent()TextField導致無限循環(自身+父級)

[英]paintComponent() TextField causes Infinite loop (itself + parent)

經過幾天的研究,我請求您的幫助。 以下代碼有效,但會產生大量的CPU消耗。 看起來,這個簡單的文本字段循環執行“ paintComponent”,不僅是其自身,還包括其父級(JPanel)。 您能給我一種糾正方法嗎?

謝謝 :)

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在JFrame的JPanel中。

對不起,我的英語不好 ...

這里是一個引起循環的小例子。

編輯:在src / views / GuestLoginView中的示例集成

這是完整的src

運行程序不會對我造成很高的CPU消耗。

同樣,TextField可能需要不斷重繪以動畫閃爍的光標。 每秒進行一次重繪是一個合理的期望,這就是我在控制台上看到的。

我更簡潔地重寫了您的代碼,以將其(大部分)放在一個文件中以簡化此過程。 首先,不斷重塗是由插入克拉的閃爍引起的。 但是,要使用gradientPaint ,最好使用JLayer 還有其他一些事情可以簡化您的代碼。

  1. 不要擴展JFrame。 它的方法很少被重寫,因此沒有必要這樣做。 只需使用一個實例。
  2. 不用使用構造函數調用的init() ,只需讓多個構造函數使用this調用主構造函數即可。 this(null, null)

JLayer允許Swing組件利用其子代。 這正是您要在程序中執行的操作。 我已經包含了此鏈接,因此您可以觀看教程和隨附的視頻。 我使用視頻中的字段名稱來幫助按照您自己的代碼中的說明進行操作。 最后,當我運行此程序時,我沒有看到Windows 10 with a quad core i7 processor上所有進程的2% CPU利用率只有2% CPU

    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 java.awt.GridLayout;

    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLayer;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.border.CompoundBorder;
    import javax.swing.border.EmptyBorder;
    import javax.swing.plaf.LayerUI;

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

    public class TestFrame {
       private static final long serialVersionUID = 818148271075948079L;
       private TestPanel         panelContent;
       private FieldText         field1, field2;

       JFrame                    frame            = new JFrame();

       public TestFrame() {

          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          field1 = new FieldText("your text 1", null);
          field2 = new FieldText("your text 2", null);
          panelContent = new TestPanel();
          panelContent.add(field1);
          panelContent.add(field2);
          LayerUI<JComponent> layerUI = new MyLayerUISubClass();
          JLayer<JComponent> jlayer = new JLayer<>(panelContent, layerUI);

          panelContent.setPreferredSize(new Dimension(500, 256));
          frame.add(jlayer);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }

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

    }

    class MyLayerUISubClass extends LayerUI<JComponent> {
       @Override
       public void paint(Graphics g, JComponent c) {
          super.paint(g, c);
          Graphics2D g2d = (Graphics2D) g.create();

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

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

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

    }

    class TestPanel extends JPanel {
       private static final long serialVersionUID = -4236642932453746731L;

       public TestPanel() {
          setLayout(new GridLayout(2, 1));
          setBackground(Color.black);

       }

       @Override
       protected void paintComponent(Graphics g) {
          // TODO Auto-generated method stub
          super.paintComponent(g);

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

    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(String text, String hint) {
          setOpaque(true);
          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.
       }

       public FieldText() {
          this(null, null);
       }

       public FieldText(String hint) {
          this(null, hint);
       }

       /**
        * 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));
       }
    }

我發現了問題。

它不在字段中,而是在我的自定義按鈕的paintComponent()中。

我有

  ImageIcon bicon = ( mouseHover ) ? new ImageIcon( iconHover ) : new ImageIcon( icon );
        setIcon(bicon);
        getIcon().paintIcon( this, g2, getIconX(), getIconY() ); 

==> paintComponent中的setIcon 不是一個好主意 ,它導致了循環和CPU使用率。

感謝您的有用建議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM