转自 一文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
分享到:
相关推荐
标题中的“带水印(背景)的JTextField”指的是在Java Swing编程中,为JTextField组件添加水印或背景图像的功能。在Java图形用户界面设计中,JTextField是用于接收单行文本输入的基本组件。而水印效果通常是指在...
在标准的`JTextField`中,虽然没有内置的自动联想或提示功能,但开发者可以通过自定义和扩展`JTextField`的功能来实现类似Google输入框的效果。 这篇原创文章描述的是如何在Java中封装`JTextField`,以实现输入时的...
Java Swing库中的JTextField组件是用于创建用户输入文本的简单单行字段,它是GUI应用程序中常见的一种交互元素。本文将详细介绍JTextField的使用方法、功能特性以及如何在实际编程中应用。 1. **JTextField简介** ...
// 这里可以进行错误提示,或者移除超出部分的字符 String text = document.getText(0, maxChars); ((PlainDocument) document).replace(0, length, text); } } } ``` 接下来,我们需要将这个监听器添加到`...
博客中可能还提到了`ConstStr.java`这个文件,这可能是一个包含常量字符串的类,如用于提示信息或错误消息的字符串。在控制`JTextField`输入时,这些常量可以用来显示用户输入不合法的警告或错误信息。 总的来说,...
模仿谷歌搜索框中输入下拉提示(自动补全)功能,访问数据库调去数据,内有数据库SQL文件,数据库JDBC连接方式,记得填写正确的username="" password="" 在tomcat 的lib文件夹中 中导入mysql 驱动包【mysql包文件夹中有...
当鼠标点击文本框,提示信息消失 提示信息框,最多允许输入150个汉字 <textarea id="info" rows="5" cols="50" </div>
在设计用户界面时,我们有时希望在这些文本框内没有输入内容时显示默认提示文字,就像iOS系统的文本框那样。这种效果可以通过一些技巧来实现,而标题和描述中提到的方法就是通过在文本框上方添加一个不可点击的`...
你可以在`JTextField`上使用`AutoCompleteDecorator`装饰器,然后提供一个数据源,JAutoComplete会自动处理后续的匹配和提示显示。 5. **性能优化**: 当数据源非常大时,为了提高性能,可以使用模糊搜索算法(如...
在Swing中,有时候我们需要实现一种特殊的效果,那就是“气泡浮动提示窗口”,这种窗口通常用作快速信息提示或者新闻预览,它会在用户界面上以非侵入性的方式短暂出现,然后消失。本篇文章将详细介绍如何在Java ...
在IT行业中,特别是涉及到用户界面(UI)设计和开发时,`textField` 是一个常见的元素,用于接收用户的文本输入。...在实际项目中,根据具体需求,还可以进一步优化,例如添加输入提示、错误提示等。
- **Swing组件**:通常使用JFrame作为主窗口,JLabel和JTextField用于显示提示和输入用户名与密码,JButton用于触发登录事件。此外,可能还使用了JPasswordField来隐藏密码输入。 - **事件监听**:使用...
14. JTextField, JTextArea: 用于输入文本,JTextField适合单行输入,JTextArea则支持多行文本。 15. JScrollBar, JSlider: 分别提供垂直和水平滚动条以及滑块组件,用于调整视图或数值。 16. JProgressBar: 显示...
在Java Swing或JavaFX这样的图形用户界面(GUI)库中,我们可以创建一个JTextField或类似的文本输入组件,并为其添加KeyListener或DocumentListener。当用户输入时,这些监听器会接收到事件,然后调用后台服务或方法...
7. **用户交互设计**: 考虑到用户体验,自动完成的提示信息应该清晰易读,同时提供方便的方式来接受建议或关闭提示。此外,还应允许用户禁用自动完成功能。 总的来说,AutoText库为Java Swing开发者提供了一种简单...
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中输入商品名称,单击“查询”...
例如,我们可以创建一个JFrame作为主窗口,然后在其中添加两个JLabel分别显示用户名和密码提示,两个JTextField用于输入,最后是一个JButton作为登录按钮。 ```java import javax.swing.JFrame; import javax.swing...