`
rcyl2003
  • 浏览: 237326 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

带提示的JTextField

阅读更多

转自 一文online


 接着昨天的MyJTextField,我们继续为JTextField增强,今天我们为MyJTextField增加一个泡泡提示。先看图片:

当输入第三个字符'a'时,由于昨天我们的MyJTextField做了处理,所以'a'不能被输入,而且弹出泡泡提示你下次不要了哟!
同样的,下一张图片:


为MyJTextField增加泡泡提示功能要做以下几件事情:
1. 泡泡窗口
2. 显示的时候计算位置

这里我使用了Bernhard Pauler的BalloonTip包的BalloonBorder代码,改造了BalloonTip代码,好废话不说,放上完整代码后再解释:
<!---->  1 /**
  2  * @(#)MyJTextField.java  0.1.1  2007-9-8
  3  */
  4 package ruislan;
  5 
  6 import java.awt.BorderLayout;
  7 import java.awt.Color;
  8 import java.awt.Component;
  9 import java.awt.Container;
 10 import java.awt.Font;
 11 import java.awt.Point;
 12 import java.awt.event.ComponentAdapter;
 13 import java.awt.event.ComponentEvent;
 14 import java.awt.event.KeyAdapter;
 15 import java.awt.event.KeyEvent;
 16 
 17 import javax.swing.Icon;
 18 import javax.swing.ImageIcon;
 19 import javax.swing.JDialog;
 20 import javax.swing.JFrame;
 21 import javax.swing.JLabel;
 22 import javax.swing.JLayeredPane;
 23 import javax.swing.JPanel;
 24 import javax.swing.JTextField;
 25 import javax.swing.border.EmptyBorder;
 26 
 27 import net.java.balloontip.BalloonBorder;
 28 
 29 
 30 /**
 31  * Custom JTextField.
 32  * 
 33  * @version 0.1.1, 2007-9-9
 34  * @author ruislan <a href="mailto:z17520@126.com"/>
 35  */
 36 public class MyJTextField extends JTextField {
 37     private static final Color TIP_COLOR = new Color(255255225);
 38     private int limit = Integer.MAX_VALUE;
 39     private boolean numberOnly;
 40     private CoolToolTip numberTip;
 41     private CoolToolTip limitTip;
 42     private ImageIcon tipIcon;
 43 
 44     public MyJTextField() {
 45         initComponents();
 46         initEventListeners();
 47     }
 48 
 49     private void initComponents() {
 50         tipIcon = new ImageIcon(MyJTextField.class.getResource("tip.gif"));
 51 
 52         numberTip = new CoolToolTip(this, TIP_COLOR, getColumns(), 10);
 53         numberTip.setText("只能输入数字!");
 54         numberTip.setIcon(tipIcon);
 55         numberTip.setIconTextGap(10);
 56 
 57         limitTip = new CoolToolTip(this, TIP_COLOR, getColumns(), 10);
 58         limitTip.setIcon(tipIcon);
 59         limitTip.setIconTextGap(10);
 60     }
 61 
 62     private void initEventListeners() {
 63         addKeyListener(new KeyAdapter() {
 64             @Override
 65             public void keyTyped(KeyEvent e) {
 66                 if (getText().length() + 1 > limit) {
 67                     deleteInputChar(e);
 68                     limitTip.setVisible(true);
 69                     return;
 70                 } else {
 71                     limitTip.setVisible(false);
 72                 }
 73                 if (numberOnly) {
 74                     char input = e.getKeyChar();
 75                     if (!Character.isDigit(input)) {
 76                         numberTip.setVisible(true);
 77                         deleteInputChar(e);
 78                     } else {
 79                         numberTip.setVisible(false);
 80                     }
 81                 }
 82             }
 83 
 84             private void deleteInputChar(KeyEvent source) {
 85                 source.setKeyChar((char) KeyEvent.VK_CLEAR);
 86             }
 87         });
 88     }
 89 
 90     public void setMaxTextLength(int limit) {
 91         if (limit < 0) {
 92             return;
 93         }
 94         this.limit = limit;
 95         limitTip.setText(String.format("超过最大长度 \"%d\"", limit));
 96     }
 97 
 98     public int getMaxTextLength() {
 99         return limit;
100     }
101 
102     public void setNumberOnly(boolean numberOnly) {
103         this.numberOnly = numberOnly;
104     }
105 
106     public boolean isNumberOnly() {
107         return this.numberOnly;
108     }
109 
110     private class CoolToolTip extends JPanel {
111         private JLabel label = new JLabel();
112         private boolean haveShowPlace;
113 
114         private Component attachedComponent;
115 
116         public CoolToolTip(Component attachedComponent, Color fillColor,
117                 int borderWidth, int offset) {
118             this.attachedComponent = attachedComponent;
119 
120             label.setBorder(new EmptyBorder(borderWidth, borderWidth,
121                     borderWidth, borderWidth));
122             label.setBackground(fillColor);
123             label.setOpaque(true);
124             label.setFont(new Font("system"012));
125 
126             setOpaque(false);
127             this.setBorder(new BalloonBorder(fillColor, offset));
128             this.setLayout(new BorderLayout());
129             add(label);
130 
131             setVisible(false);
132 
133             // if the attached component is moved while the balloon tip is
134             // visible, we need to move as well
135             attachedComponent.addComponentListener(new ComponentAdapter() {
136                 public void componentMoved(ComponentEvent e) {
137                     if (isShowing()) {
138                         determineAndSetLocation();
139                     }
140                 }
141             });
142 
143         }
144 
145         private void determineAndSetLocation() {
146             Point location = attachedComponent.getLocation();
147             setBounds(location.x, location.y - getPreferredSize().height,
148                     getPreferredSize().width, getPreferredSize().height);
149         }
150 
151         public void setText(String text) {
152             label.setText(text);
153         }
154 
155         public void setIcon(Icon icon) {
156             label.setIcon(icon);
157         }
158 
159         public void setIconTextGap(int iconTextGap) {
160             label.setIconTextGap(iconTextGap);
161         }
162 
163         public void setVisible(boolean show) {
164             if (show) {
165                 determineAndSetLocation();
166                 findShowPlace();
167             }
168             super.setVisible(show);
169         }
170 
171         private void findShowPlace() {
172             if (haveShowPlace) {
173                 return;
174             }
175             // we use the popup layer of the top level container (frame or
176             // dialog) to show the balloon tip
177             // first we need to determine the top level container
178             Container parent = attachedComponent.getParent();
179             JLayeredPane layeredPane;
180             while (true) {
181                 if (parent instanceof JFrame) {
182                     layeredPane = ((JFrame) parent).getLayeredPane();
183                     break;
184                 } else if (parent instanceof JDialog) {
185                     layeredPane = ((JDialog) parent).getLayeredPane();
186                     break;
187                 }
188                 parent = parent.getParent();
189             }
190             layeredPane.add(this, JLayeredPane.POPUP_LAYER);
191             haveShowPlace = true;
192         }
193     }
194 }
195 

测试代码:
<!----> 1 package ruislan.examples;
 2 
 3 import java.awt.Container;
 4 import java.awt.Dimension;
 5 import java.awt.GridBagLayout;
 6 import java.awt.Toolkit;
 7 
 8 import javax.swing.JFrame;
 9 
10 import ruislan.MyJTextField;
11 
12 public class MyJTextFieldTest {
13 
14     public static void main(String[] args) {
15         JFrame frame = new JFrame();
16         Container contentPane = frame.getContentPane();
17         contentPane.setLayout(new GridBagLayout());
18         final MyJTextField textField = new MyJTextField();
19         textField.setNumberOnly(true);
20         textField.setColumns(15);
21         textField.setMaxTextLength(5);
22         contentPane.add(textField);
23 
24         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
25         frame.setSize(320240);
26         centerWindow(frame);
27         frame.setTitle("MyJTextField");
28         frame.setVisible(true);
29     }
30 
31     public static void centerWindow(Container window) {
32         // get the size of the screen
33         Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
34 
35         // determine the new location of the window
36         int w = window.getSize().width;
37         int h = window.getSize().height;
38         int x = (dim.width - w) / 2;
39         int y = (dim.height - h) / 2;
40 
41         // move the window
42         window.setLocation(x, y);
43     }
44 }
45 

就以上代码解释一下
1. 为什么CoolToolTip不使用JWindow而使用JPanel?
不错,JWindow可以放置在屏幕的任意位置,而且也是我的首选,但是JWindow是调用native代码来绘图,没有提供可以改变形状的API(我 们需要泡泡嘛),所以使用了JPanel,那么这就具有了局限性,第一个就是我们在显示泡泡的时候必须找到最高级的组件来显示,以便覆盖到其下的所有子组 件,第二个就是显示的区域受到了最高级组件的局限,例如JFrame上只有一个MyJTextField,而JFrame.pack了之后大小刚好是 MyJTextField的大小,这样就看不到CoolToolTip了。

2. 为什么CoolToolTip在setVisible的时候才找一个要show的地方?
这个操作在Bernhard Pauler的BalloonTip代码中是由构造方法来完成的,但是这里就会出现一个问题,对,NullPointer,因为Swing不像SWT,是 在component.add(child)方法调用的时候才设置child的Parent,而非在构造child的时候将component放入,所以 我们只有懒加载来避免这个情况发生。说到懒加载我发表一下一个题外意见,在下认为懒加载在swing中不要用得太过频繁,用户体验是第一位的,在下宁愿在 启动程序的时候看进度条也不愿在启动某个视图的时候突然卡死一小会。

3. 还有什么没有做的?
例如当输入Esc、Backspace、Enter等等按键的时候CoolToolTip也会跳出来show一把,我们必须过滤掉它们!

今天就到这里吧,下一次我们让MyJTextField更酷一点,我们为它加上Beep声音,当我们输入了非法字符的时候就beep、beep的叫唤,没有声音也没有泡泡提示的话有些人很可能是以为自己的键盘坏掉了。

本人就对QQ的登录窗口很有意见,每次我开机都是Eclipse和QQ一起打开的,一般操作都是先登录QQ,但是有一天我QQ后打开的,我正在happy coding
分享到:
评论

相关推荐

    带水印(背景)的JTextField

    标题中的“带水印(背景)的JTextField”指的是在Java Swing编程中,为JTextField组件添加水印或背景图像的功能。在Java图形用户界面设计中,JTextField是用于接收单行文本输入的基本组件。而水印效果通常是指在...

    原创:java封装了的JTextField,可以达到google输入框的效果

    在标准的`JTextField`中,虽然没有内置的自动联想或提示功能,但开发者可以通过自定义和扩展`JTextField`的功能来实现类似Google输入框的效果。 这篇原创文章描述的是如何在Java中封装`JTextField`,以实现输入时的...

    java JTextField组件的使用

    Java Swing库中的JTextField组件是用于创建用户输入文本的简单单行字段,它是GUI应用程序中常见的一种交互元素。本文将详细介绍JTextField的使用方法、功能特性以及如何在实际编程中应用。 1. **JTextField简介** ...

    JTextField输入时实现位数监听

    // 这里可以进行错误提示,或者移除超出部分的字符 String text = document.getText(0, maxChars); ((PlainDocument) document).replace(0, length, text); } } } ``` 接下来,我们需要将这个监听器添加到`...

    控制JTextField的输入

    博客中可能还提到了`ConstStr.java`这个文件,这可能是一个包含常量字符串的类,如用于提示信息或错误消息的字符串。在控制`JTextField`输入时,这些常量可以用来显示用户输入不合法的警告或错误信息。 总的来说,...

    Java 模仿谷歌搜索框中输入下拉提示(自动补全)功能 源代码

    模仿谷歌搜索框中输入下拉提示(自动补全)功能,访问数据库调去数据,内有数据库SQL文件,数据库JDBC连接方式,记得填写正确的username="" password="" 在tomcat 的lib文件夹中 中导入mysql 驱动包【mysql包文件夹中有...

    点击提示框提示信息消失

    当鼠标点击文本框,提示信息消失 提示信息框,最多允许输入150个汉字 &lt;textarea id="info" rows="5" cols="50" &lt;/div&gt;

    java swing文本框(密码框)没有内容时,占位显示默认信息(仿IOS)

    在设计用户界面时,我们有时希望在这些文本框内没有输入内容时显示默认提示文字,就像iOS系统的文本框那样。这种效果可以通过一些技巧来实现,而标题和描述中提到的方法就是通过在文本框上方添加一个不可点击的`...

    java文本框自动提示

    你可以在`JTextField`上使用`AutoCompleteDecorator`装饰器,然后提供一个数据源,JAutoComplete会自动处理后续的匹配和提示显示。 5. **性能优化**: 当数据源非常大时,为了提高性能,可以使用模糊搜索算法(如...

    java Swing 气泡浮动提示窗口代码

    在Swing中,有时候我们需要实现一种特殊的效果,那就是“气泡浮动提示窗口”,这种窗口通常用作快速信息提示或者新闻预览,它会在用户界面上以非侵入性的方式短暂出现,然后消失。本篇文章将详细介绍如何在Java ...

    textField限制输出长度

    在IT行业中,特别是涉及到用户界面(UI)设计和开发时,`textField` 是一个常见的元素,用于接收用户的文本输入。...在实际项目中,根据具体需求,还可以进一步优化,例如添加输入提示、错误提示等。

    java gui登录页面和消息提示框.zip

    - **Swing组件**:通常使用JFrame作为主窗口,JLabel和JTextField用于显示提示和输入用户名与密码,JButton用于触发登录事件。此外,可能还使用了JPasswordField来隐藏密码输入。 - **事件监听**:使用...

    Swing组件下载(常用组件)

    14. JTextField, JTextArea: 用于输入文本,JTextField适合单行输入,JTextArea则支持多行文本。 15. JScrollBar, JSlider: 分别提供垂直和水平滚动条以及滑块组件,用于调整视图或数值。 16. JProgressBar: 显示...

    基于Java的实例源码-搜索自动提示 Autotips.zip

    在Java Swing或JavaFX这样的图形用户界面(GUI)库中,我们可以创建一个JTextField或类似的文本输入组件,并为其添加KeyListener或DocumentListener。当用户输入时,这些监听器会接收到事件,然后调用后台服务或方法...

    AutoText:Java Swing 库,允许将自动完成的可能性添加到文本组件(JTextComponent - JTextField - JFormattedTextField 等)

    7. **用户交互设计**: 考虑到用户体验,自动完成的提示信息应该清晰易读,同时提供方便的方式来接受建议或关闭提示。此外,还应允许用户禁用自动完成功能。 总的来说,AutoText库为Java Swing开发者提供了一种简单...

    java浏览器

    JTextField jtfAddress; //输入html文件地址或网址 JButton jbGo; //转到文件按钮 JTextPane jtpShow; //显示文件 JLabel jlInfo; //提示信息 public HTTPBrowserDemo() { super("韩公达制作的html浏览器")...

    学生信息系统

    JOptionPane.showMessageDialog(null, "请选择你要修改的内容", "温馨提示", JOptionPane.INFORMATION_MESSAGE); }else{ editFrame ef=new editFrame(this); ef.学号.setText((String)table....

    超市管理系统 Java Swing + MySQL JDBC开发

    添加两个JLabel用于显示查询提示信息;添加JTextField用于输入商品商品名称;添加2个JButton,分别用来实现商品查询及添加商品,效果图如图1所示。 2、在“商品名称”对应的JTextField中输入商品名称,单击“查询”...

    java实现QQ登录页面

    例如,我们可以创建一个JFrame作为主窗口,然后在其中添加两个JLabel分别显示用户名和密码提示,两个JTextField用于输入,最后是一个JButton作为登录按钮。 ```java import javax.swing.JFrame; import javax.swing...

Global site tag (gtag.js) - Google Analytics