1 原理
Swing默认的JToolTip只能显示文本,有时我们需要在ToolTip上显示格式化文本、图像甚至组件,应该怎样来实现呢?Swing中的ToolTip是用组件JToolTip来实现的,那么我们可以自定义一个类继承自JToolTip,然后重载它的paintComponent(Graphics)方法,在此方法中我们告诉Swing如何绘制ToolTip自己;因为所有的JComponent都是Container的子类,因此我们可以向自己的ToolTip中添加组件,就像在容器中添加组件一样,JComponent.paintChildren(Graphics)方法可以绘制容器中的子组件,我们甚至可以不考虑如何绘制ToolTip中的组件。
JComponent.createToolTip()方法返回用于显示toolTip的JToolTip实例,组件通常不应该重载此方法,但它可用于显示不同于(默认实现)的toolTip。方法签名为:
public JToolTip createToolTip();
我们在需要显示自定义toolTip的类中重载此方法,返回一个自定义的ToolTip实例,就可以实现显示自定义的toolTip了。
同时,组件的setToolTipText(String)方法依然是有效的,调用我们自定义组件的此方法可以设置提示文本,在createToolTip()方法返回的自定义的ToolTip实例中,调用JToolTip.getTipText()方法就可以获得这个文本。
2 实例代码
2.1 定义一个JToolTip的子类
- package test.ui.wnd;
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.Graphics;
- import java.awt.Graphics2D;
- import java.awt.Paint;
- import javax.swing.JButton;
- import javax.swing.JToolTip;
- public class MyToolTip extends JToolTip {
- private static final long serialVersionUID = 1L;
- private JButton jb;
- public MyToolTip() {
- super();
- jb = new JButton("Push me!");
- jb.setLocation(10, 30);
- jb.setSize(100,30);
- add(jb);
- }
- public Dimension getPreferredSize() {
- return new Dimension(200,100);
- }
- public void paintComponent(Graphics g) {
- Graphics2D g2d = (Graphics2D)g;
- int width = (int)(getPreferredSize().getWidth());
- int height = (int)(getPreferredSize().getHeight());
- Paint oldPaint = g2d.getPaint();
- g2d.setPaint(Color.CYAN);
- g2d.fillRect(0, 0, width, height);
- g2d.setPaint(oldPaint);
- if (getTipText() != null) {
- g2d.drawString(getTipText(), 10, 20);
- }
- }
- public void paintChildren(Graphics g) {
- jb.repaint();
- }
- public JButton getButton() {
- return jb;
- }
- }
package test.ui.wnd;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import javax.swing.JButton;
import javax.swing.JToolTip;
public class MyToolTip extends JToolTip {
private static final long serialVersionUID = 1L;
private JButton jb;
public MyToolTip() {
super();
jb = new JButton("Push me!");
jb.setLocation(10, 30);
jb.setSize(100,30);
add(jb);
}
public Dimension getPreferredSize() {
return new Dimension(200,100);
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
int width = (int)(getPreferredSize().getWidth());
int height = (int)(getPreferredSize().getHeight());
Paint oldPaint = g2d.getPaint();
g2d.setPaint(Color.CYAN);
g2d.fillRect(0, 0, width, height);
g2d.setPaint(oldPaint);
if (getTipText() != null) {
g2d.drawString(getTipText(), 10, 20);
}
}
public void paintChildren(Graphics g) {
jb.repaint();
}
public JButton getButton() {
return jb;
}
}
2.2 自定义一个组件
- package test.ui.wnd;
- import java.awt.event.ActionListener;
- import javax.swing.JButton;
- import javax.swing.JToolTip;
- public class MyButton extends JButton {
- private static final long serialVersionUID = -4212536258012660909L;
- private MyToolTip toolTip;
- private ActionListener toolTipBtnListener;
- public MyButton() {
- super();
- }
- public JButton getToolTipButton() {
- if (toolTip != null) {
- return toolTip.getButton();
- } else {
- return null;
- }
- }
- public void addToolTipBtnListener(ActionListener l) {
- toolTipBtnListener = l;
- }
- public JToolTip createToolTip() {
- if (toolTip == null) {
- toolTip = new MyToolTip();
- toolTip.getButton().addActionListener(toolTipBtnListener);
- }
- return toolTip;
- }
- }
package test.ui.wnd;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JToolTip;
public class MyButton extends JButton {
private static final long serialVersionUID = -4212536258012660909L;
private MyToolTip toolTip;
private ActionListener toolTipBtnListener;
public MyButton() {
super();
}
public JButton getToolTipButton() {
if (toolTip != null) {
return toolTip.getButton();
} else {
return null;
}
}
public void addToolTipBtnListener(ActionListener l) {
toolTipBtnListener = l;
}
public JToolTip createToolTip() {
if (toolTip == null) {
toolTip = new MyToolTip();
toolTip.getButton().addActionListener(toolTipBtnListener);
}
return toolTip;
}
}
2.3 测试主类
- package test.ui.wnd;
- import java.awt.Container;
- import java.awt.FlowLayout;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import javax.swing.JFrame;
- import javax.swing.JTextField;
- public class MyToolTipTest extends JFrame implements ActionListener {
- private static final long serialVersionUID = -8760252318430347150L;
- private MyButton mb;
- private JTextField jtf;
- public MyToolTipTest() {
- setSize(600,400);
- setLocation(200,200);
- setTitle("自定义ToolTip测试");
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- Container c = getContentPane();
- c.setLayout(new FlowLayout(FlowLayout.CENTER));
- mb = new MyButton();
- mb.setText("Button");
- mb.addActionListener(this);
- mb.setToolTipText("这是一个自定义的ToolTip");
- mb.addToolTipBtnListener(this);
- jtf = new JTextField(20);
- c.add(mb);
- c.add(jtf);
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == mb) {
- jtf.setText("From \"Button\"");
- } else if (e.getSource() == mb.getToolTipButton()) {
- jtf.setText("From \"Push me\" in the tooltip");
- }
- }
- public static void main(String[] args) {
- MyToolTipTest test = new MyToolTipTest();
- test.setVisible(true);
- }
- }
package test.ui.wnd;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class MyToolTipTest extends JFrame implements ActionListener {
private static final long serialVersionUID = -8760252318430347150L;
private MyButton mb;
private JTextField jtf;
public MyToolTipTest() {
setSize(600,400);
setLocation(200,200);
setTitle("自定义ToolTip测试");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout(FlowLayout.CENTER));
mb = new MyButton();
mb.setText("Button");
mb.addActionListener(this);
mb.setToolTipText("这是一个自定义的ToolTip");
mb.addToolTipBtnListener(this);
jtf = new JTextField(20);
c.add(mb);
c.add(jtf);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == mb) {
jtf.setText("From \"Button\"");
} else if (e.getSource() == mb.getToolTipButton()) {
jtf.setText("From \"Push me\" in the tooltip");
}
}
public static void main(String[] args) {
MyToolTipTest test = new MyToolTipTest();
test.setVisible(true);
}
}
3 运行效果
自己的ToolTip显示时的效果图
响应ToolTip上组件的发出的事件