使用图像和提示装饰JTextField [英] Decorating a JTextField with an image and hint

查看:114
本文介绍了使用图像和提示装饰JTextField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用图像和提示创建一些看起来更漂亮的JTextFields。为此,我做了一个覆盖paintComponent方法的装饰器。我使用装饰器的原因是我想将它应用于其他类型的JTextField,例如JPasswordField。

I'm trying to create some nicer looking JTextFields with an image and a hint. To do this I made a decorator that overrides the paintComponent method. The reason I used a decorator is that I wanted to apply it to other types of JTextField such as JPasswordField.

这是我到目前为止所做的事情;

Here is what I've made so far;

左边表格中的问题是,即使我使用了JPasswordField,paintComponent似乎忽略了我所假设的密码paintComponent,它可能是密码屏蔽符号。

The problem as seen in the form on the left is that, even though I have used a JPasswordField the paintComponent seems to ignore what I assume is the passwords paintComponent which presumably does the password masking symbols.

所以问题是,我怎样才能避免重复JTextFields和JPasswordFields的代码,但仍然具有不同的功能,如密码屏蔽。

So the question is, how can I avoid duplicating the code for JTextFields and JPasswordFields but still have the different functionality such as password masking.

这是装饰器代码;

public class JTextFieldHint extends JTextField implements FocusListener{
private JTextField jtf;
private Icon icon;
private String hint;
private Insets dummyInsets;

public JTextFieldHint(JTextField jtf, String icon, String hint){
    this.jtf = jtf;
    setIcon(createImageIcon("icons/"+icon+".png",icon));
    this.hint = hint;

    Border border = UIManager.getBorder("TextField.border");
    JTextField dummy = new JTextField();
    this.dummyInsets = border.getBorderInsets(dummy);

    addFocusListener(this);
}

public void setIcon(Icon newIcon){
    this.icon = newIcon;
}

@Override
protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int textX = 2;

        if(this.icon!=null){
            int iconWidth = icon.getIconWidth();
            int iconHeight = icon.getIconHeight();
            int x = dummyInsets.left + 5;
            textX = x+iconWidth+2;
            int y = (this.getHeight() - iconHeight)/2;
            icon.paintIcon(this, g, x, y);
        }

        setMargin(new Insets(2, textX, 2, 2));

        if ( this.getText().equals("")) {
            int width = this.getWidth();
            int height = this.getHeight();
            Font prev = g.getFont();
            Font italic = prev.deriveFont(Font.ITALIC);
            Color prevColor = g.getColor();
            g.setFont(italic);
            g.setColor(UIManager.getColor("textInactiveText"));
            int h = g.getFontMetrics().getHeight();
            int textBottom = (height - h) / 2 + h - 4;
            int x = this.getInsets().left;
            Graphics2D g2d = (Graphics2D) g;
            RenderingHints hints = g2d.getRenderingHints();
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.drawString(hint, x, textBottom);
            g2d.setRenderingHints(hints);
            g.setFont(prev);
            g.setColor(prevColor);
        }

}

protected ImageIcon createImageIcon(String path, String description) {
    java.net.URL imgURL = getClass().getResource(path);
    if (imgURL != null) {
        return new ImageIcon(imgURL, description);
    } else {
        System.err.println("Couldn't find file: " + path);
        return null;
    }
}

@Override
public void focusGained(FocusEvent arg0) {
    this.repaint();
}

@Override
public void focusLost(FocusEvent arg0) {
    this.repaint();
}


}

这是我在哪里创建字段;

And this is where I create the fields;

JTextField usernameField = new JTextFieldHint(new JTextField(),"user_green","Username");
JTextField passwordField = new JTextFieldHint(new JPasswordField(),"bullet_key","Password");

希望我没有完全走错方向!

Hopefully i've not went completely off in the wrong direction here!

谢谢!

编辑:我看的越多,显然调用super.paintComponent(g)即可调用JTextFields paintcomponent,但我看不出如何在不重复代码的情况下解决这个问题。

EDIT : Again the more I look at it, it is obvious that calling super.paintComponent(g) is going to call the JTextFields paintcomponent, but I can't see how to solve this without duplicating the code.

推荐答案

文本提示适用于JPasswordField。

Text Prompt works with a JPasswordField.

一个区别是输入文本时显示的图标会消失。如果你想让图标永久化,那么我建议你创建一个自定义的IconBorder *类来绘制一个Icon而不是在paintComponent()方法中进行自定义绘制。

One difference is that the displayed icon disappears when text is entered. If you want the icon to be permanent then I suggest you create a custom "IconBorder* class to paint an Icon rather then do custom painting in the paintComponent() method.

除非你复制JTextField和JPasswordField的代码,否则你的方法将无效。

You approach will not work unless you duplicate the code for both JTextField and JPasswordField.

编辑:

其实你不需要创建自定义的IconBorder.MatteBorder支持在边框中绘制图标。

Actually you don't need to create a custom IconBorder. The MatteBorder supports the painting of an Icon in a Border.

这篇关于使用图像和提示装饰JTextField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆