1

我通过扩展 JtextField 类和覆盖 paintComponent(Graphics g) 方法创建了一个自定义 JTextField。当我编译并拖入 JFrame 时,它​​可以正常工作。但是当我运行它时,结果是不同的。

我的自定义 JTextField 被白色方块覆盖,我怀疑这是 super.paintComponent(g); 的结果;方法。

这是我在 paintComponent() 方法上的代码;

@Override
protected void paintComponent(Graphics g) {
    Graphics2D gd = (Graphics2D) g.create();
    gd.setPaint(new GradientPaint(0, 0, Color.BLUE, getWidth(), 0, Color.BLACK));
    gd.fillRoundRect(0, 0, getWidth(), getHeight(), getWidth() / 2, getHeight() / 2);
    gd.dispose();
    super.paintComponent(g);
}
4

3 回答 3

3

移动super.paintComponent(g)到您的顶部paintComponent。通过这种方式,您可以确保在超类paintComponent执行后完成自定义绘制。

于 2012-10-28T15:59:16.020 回答
0
//Here is a example for Custom JTextfeild

1. This supports highlighting Jtextfeild with Icons.

2. This custom Jtextfeild with different fonts.

  Header Section
---------------------
import java.awt.*;  
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;  
import javax.swing.*;  
import javax.swing.border.Border;



//Main class section 

    public class CustomJTextFeild extends JTextField implements FocusListener,KeyListener{
          private Color color;
          private ImageIcon normal_icon;
          private ImageIcon hover_icon;
          private ImageIcon icon_Label;
          private boolean start_action=false;
          private String Matchtext;
          private int x0 ;

 //Constructor with input parameters
 //icon ->  normal icon
 //icon 1-> hover icon
 //text ->  initial text 

     public  CustomJTextFeild(ImageIcon icon,ImageIcon icon1, String text) { 


        this.normal_icon=icon;
            this.hover_icon=icon1;
            this.icon_Label=normal_icon;
            this.Matchtext=text;

            Font myFont = new Font("Segoe UI", Font.BOLD,12);
            setFont(myFont);
            Border border = UIManager.getBorder("TextField.border");  
            x0 = border.getBorderInsets(new JTextField()).left;  
            Border Textborder = BorderFactory.createLineBorder(new Color(0xd4d4d4 , false), 2 );
            setBorder(BorderFactory.createCompoundBorder(Textborder, 
            BorderFactory.createEmptyBorder(0,5 + icon_Label.getIconWidth(), 0, 0)));
            setText(text);
            addFocusListener(this) ; 
            addKeyListener(this) ; 

        }

    @Override
    public void paintComponent(Graphics g) {

       int y = (this.getHeight() - icon_Label.getIconHeight())/2;  
       super.paintComponent(g);  
       g.drawImage(icon_Label.getImage(), x0, y, this);   

    }

    @Override
    public void focusGained(FocusEvent e) {
        // TODO Auto-generated method stub
        if(e.getSource() == this && !this.start_action)
            this.setText("");

         this.icon_Label=hover_icon;
         this.repaint();
         this.revalidate();


    }
    @Override
    public void focusLost(FocusEvent arg0) {
        // TODO Auto-generated method stub
        if(!this.start_action || this.getText().length()==0)
           this.setText(this.Matchtext);

         this.icon_Label=normal_icon;
         this.repaint();
         this.revalidate();
    }
    @Override
    public void keyPressed(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }
    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
        this.start_action=true;
    }



    }  

/* Output */

 JtextFeild name_Value=new CustomJTextFeild(   new ImageIcon(getClass().getResource("filename1")).getImage(), new ImageIcon(getClass().getResource("filename")).getImage(),"Name");  
于 2014-01-20T11:29:45.143 回答
0

我知道这个问题已经很老了,但是我在寻找其他东西时偶然发现了它,并认为我会为遇到它的其他人加两分钱。

原因: OPs 报告问题的原因与他假设的完全一样......即在super.paintComponent(g)他的自定义绘画代码上有效绘画的行为。

但是......他发布的代码并没有什么问题。它确实/将起作用,我必须分别不同意 DanD 建议的答案。不幸的是,OP 没有包含更多示例代码,因此只能推测他的确切问题。

嗯?你问。那么怎么回事呢?

修复:很简单,如果您想使用这种方法自定义 JTextField 的外观,那么您必须有效地告诉超类不要在您的自定义绘画上进行绘画。这是通过在组件上设置以下属性值来完成的:

text.setOpaque(false);
text.setBorder(null);

通过这种方式,您可以让所有代码保持原样,并且您实际上是在告诉原始的 paintComponent() 方法不要绘制背景颜色或绘制边框。

我提供以下 SSCCE 作为示例和解决方案。请注意以下事项:

  1. 我创建了一个静态布尔值“FIXIT”。希望不用说您不会将其包含在“生产”代码中;它在示例中被使用以允许您观察这两种行为。只需切换其值即可查看“之前”和“之后”。

  2. 更重要的是(IMO),请注意我在自定义代码类的外部设置了提到的属性值。我这样做是为了更符合 OP 提出问题的方式,并且这种方法不需要更改他的自定义类。但是,正如代码中的注释所述,更强大的解决方案将在自定义类构造函数中设置这些值以确保它们的正确性。

  3. 我还提供了一种更具视觉吸引力的绘画方法。虽然它几乎与原版相同,但请参阅所做调整的评论。当然,这只是我的观点,但仍作为示例提供。

package misc;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * An SSCCE in response to the following StackOverflow question:
 * https://stackoverflow.com/questions/13109638/my-custom-jtextfield-covered-by-super-paintcomponentg-method
 * 
 * @author kansasSamurai
 *
 */
@SuppressWarnings("serial")
public class CustomTextField extends JTextField {
    
    private static boolean FIXIT = true;
    
    public static void main(String args[]) {

        SwingUtilities.invokeLater( new Runnable() {
            @Override public void run() { createAndShowGUI(); }
        } );

    }

    protected static void createAndShowGUI() {
        JFrame frame = new JFrame("SSCCE - CustomTextField");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridBagLayout());
        
        CustomTextField text = new CustomTextField();
        text.setText("  Ipsum Lorem  "); 
            if (FIXIT) {
                // These two lines are NECESSARY...
                text.setOpaque(false);
                text.setBorder(null);
                // or!!! ... they could/should be added to the constructor(s) of your custom class

                // These two lines are OPTIONAL
                text.setForeground(Color.white);
                text.setCaretColor(Color.white);
            }
        frame.getContentPane().add(text);
        
        frame.pack();
        frame.setSize(330, 100); // these dimensions are "arbitrary"
        frame.setLocationRelativeTo(null); // centers the frame on screen
        frame.setVisible(true);
    }

    @Override
    protected void paintComponent(Graphics g) {
        if (FIXIT) {
            this.betterPaint(g);
            return;
        }

        final Graphics2D gd = (Graphics2D) g.create();
        gd.setPaint(new GradientPaint(0, 0, Color.BLUE, getWidth(), 0, Color.BLACK));
        gd.fillRoundRect(0, 0, getWidth(), getHeight(), getWidth() / 2, getHeight() / 2);
        gd.dispose();

        super.paintComponent(g);
    }
    
    protected void betterPaint(Graphics g) {
        final Graphics2D gd = (Graphics2D) g.create();
        
        // Improve appearance by enabling antialiasing
        gd.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        gd.setPaint(new GradientPaint(0, 0, Color.BLUE, getWidth(), 0, Color.BLACK));

        // Fully rounded ends (not strictly required to fixit... just an example)
        gd.fillRoundRect(0, 0, getWidth(), getHeight(), getHeight(), getHeight());

        gd.dispose();

        super.paintComponent(g);
    }
    
}

于 2020-12-08T16:55:56.520 回答