转自 一文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(255, 255, 225);
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", 0, 12));
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(320, 240);
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
分享到:
相关推荐
模仿谷歌搜索框中输入下拉提示(自动补全)功能,访问数据库调去数据,内有数据库SQL文件,数据库JDBC连接方式,记得填写正确的username="" password="" 在tomcat 的lib文件夹中 中导入mysql 驱动包【mysql包文件夹中有...
当鼠标点击文本框,提示信息消失 提示信息框,最多允许输入150个汉字 <textarea id="info" rows="5" cols="50" </div>
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....
添加两个JLabel用于显示查询提示信息;添加JTextField用于输入商品商品名称;添加2个JButton,分别用来实现商品查询及添加商品,效果图如图1所示。 2、在“商品名称”对应的JTextField中输入商品名称,单击“查询”...
" "(3)左边面板中输入学生信息,点击"添加"按钮,将此学生信息插入stuinfo表 " "中,弹出插入是否成功的提示框。 " "(4)点击"删除"按钮,依据上边学号值删除该学生记录,弹出删除是否成功的提" "示框。 " "(5...
JTextField及JPasswordField的空值处理,思路是采用图层Lable,并利用lable的无点击特性,类似ios文本框的空值默认显示。
//错误提示框 public static JDialog DLGError=new JDialog(main,"错误!"); public static JLabel DLGINFO=new JLabel(""); public static JLabel type=new JLabel("请选择:"); //扫描类型 public static...
private JLabel l = new JLabel("小提示:可直接输入年份,提高查询效率!"); private JLabel lt = new JLabel();//系统时间 private JLabel ld = new JLabel();//日期是否被选择 private int lastTime; ...
private JTextField usernameField,emailField; private TextField teleField; private JPasswordField passwordField; private JButton registButton,cancelButton; public Text() { super("用户...
JTextField jtfAddress; //输入html文件地址或网址 JButton jbGo; //转到文件按钮 JTextPane jtpShow; //显示文件 JLabel jlInfo; //提示信息 public HTTPBrowserDemo(){ super("html浏览器"); //...
private JLabel l = new JLabel("小提示:可直接输入年份,提高查询效率!"); private JLabel lt = new JLabel();//系统时间 private JLabel ld = new JLabel();//日期是否被选择 private int lastTime; ...
登录界面:登录界面是有帐号,密码两个JTextField,管理员帐号一字母A开头,教师帐号一字母T开头,学生帐号以字母S开头,登录帐号或密码输入错误会弹出相应的提示对话框。 学生信息管理模块:管理员用于添加和...
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 ...
算数一”、“运算数二”、“运算结果”这些提示标签使用组件JLabel (或Label),输入运算数和输出运算结果使用JTextField(或 TextField),“相加”、“相减”和“全部清零”使用按钮JButton (或Button)。 请...
对象: 属于ShuDu1主类的对象: MenuBar、Menu、MenuItem、JComboBox 属于ShuDuAns类的对象:JTextField 属于String类的对象:atext[i][j] 属于JtextField类的对象:text[i][j]、 属于JPanel类的对象:apanel[ ]、...
//提示用户输入球体半径 private JTextField radiusTextField;//接受用户输入球体半径 //private JLabel radiusRang; private JLabel areaLab;//显示球体面积 private JTextField areaTextField;//显示输入...
\//提示信息的初始化 36 background2 = new JLabel(\请使用学号和姓名查询!\ background3 = new JLabel(\请使用学号和姓名查询!\ student = new ArrayList ; xingming1=new JLabel(\学生姓名:\//录入界面各个组件...