`
rcyl2003
  • 浏览: 231771 次
  • 性别: 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
分享到:
评论

相关推荐

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

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

    点击提示框提示信息消失

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

    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中输入商品名称,单击“查询”...

    JDBC实验报告.doc

    " "(3)左边面板中输入学生信息,点击"添加"按钮,将此学生信息插入stuinfo表 " "中,弹出插入是否成功的提示框。 " "(4)点击"删除"按钮,依据上边学号值删除该学生记录,弹出删除是否成功的提" "示框。 " "(5...

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

    JTextField及JPasswordField的空值处理,思路是采用图层Lable,并利用lable的无点击特性,类似ios文本框的空值默认显示。

    java 端口扫描工具 端口扫描

    //错误提示框 public static JDialog DLGError=new JDialog(main,"错误!"); public static JLabel DLGINFO=new JLabel(""); public static JLabel type=new JLabel("请选择:"); //扫描类型 public static...

    java万年历课程设计

    private JLabel l = new JLabel("小提示:可直接输入年份,提高查询效率!"); private JLabel lt = new JLabel();//系统时间 private JLabel ld = new JLabel();//日期是否被选择 private int lastTime; ...

    用户登录Java程序

    private JTextField usernameField,emailField; private TextField teleField; private JPasswordField passwordField; private JButton registButton,cancelButton; public Text() { super("用户...

    Java写的网页浏览器,仿IE基础功能.rar

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

    java万年历源代码

    private JLabel l = new JLabel("小提示:可直接输入年份,提高查询效率!"); private JLabel lt = new JLabel();//系统时间 private JLabel ld = new JLabel();//日期是否被选择 private int lastTime; ...

    基于SQL数据库的学生信息管理系统代码+报告

    登录界面:登录界面是有帐号,密码两个JTextField,管理员帐号一字母A开头,教师帐号一字母T开头,学生帐号以字母S开头,登录帐号或密码输入错误会弹出相应的提示对话框。 学生信息管理模块:管理员用于添加和...

    JAVA聊天客户端代码

    import javax.swing.JTextField; /** * 客户端窗体 */ public class ClientFrame extends JFrame implements ActionListener, KeyListener { JButton but; JTextArea message; JTextField text; Socket s; ...

    数据库实验完整版 通讯录

    private JTextField[] jtfArray={ new JTextField(), new JTextField(30), new JTextField(30), new JTextField(30), new JTextField(30), new JTextField(30), new JTextField(30), new ...

    简易计算器java代码

    算数一”、“运算数二”、“运算结果”这些提示标签使用组件JLabel (或Label),输入运算数和输出运算结果使用JTextField(或 TextField),“相加”、“相减”和“全部清零”使用按钮JButton (或Button)。 请...

    java课程设计九宫格数独.doc

    对象: 属于ShuDu1主类的对象: MenuBar、Menu、MenuItem、JComboBox 属于ShuDuAns类的对象:JTextField 属于String类的对象:atext[i][j] 属于JtextField类的对象:text[i][j]、 属于JPanel类的对象:apanel[ ]、...

    Java实现MVC球体

    //提示用户输入球体半径 private JTextField radiusTextField;//接受用户输入球体半径 //private JLabel radiusRang; private JLabel areaLab;//显示球体面积 private JTextField areaTextField;//显示输入...

    JAVA课程设计报告-完整版.docx

    \//提示信息的初始化 36 background2 = new JLabel(\请使用学号和姓名查询!\ background3 = new JLabel(\请使用学号和姓名查询!\ student = new ArrayList ; xingming1=new JLabel(\学生姓名:\//录入界面各个组件...

Global site tag (gtag.js) - Google Analytics