import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JWindow;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
public class ToolTip {
// 氣泡提示寬
private int _width = 160;
// 氣泡提示高
private int _height = 170;
// 設定循環的步長
private int _step = 30;
// 每步時間
private int _stepTime = 30;
// 顯示時間
private int _displayTime = 6000;
// 目前申請的氣泡提示數量
private int _countOfToolTip = 0;
// 當前最大氣泡數
private int _maxToolTip = 0;
// 在屏幕上顯示的最大氣泡提示數量
private int _maxToolTipSceen;
// 字體
private Font _font;
//X軸坐標
private int pointX;
//Y軸坐標
private int pointY;
//是否設置該氣泡的屏幕坐標
private boolean setLocationBool;
private int offset;
// 邊框顏色
private Color _bgColor;
// 背景顏色
private Color _border;
// 消息顏色
private Color _messageColor;
// 差值設定
int _gap;
// 是否要求至頂(jre1.5以上版本方可執行)
boolean _useTop = true;
/**
* 構造函數,初始化默認氣泡提示設置
*
*/
public ToolTip(int pointX,int pointY,boolean setLocationBool) {
this.pointX = pointX;
this.pointY = pointY;
this.setLocationBool = setLocationBool;
// 設定字體
_font = new Font("宋體", 0, 12);
// 設定邊框顏色
_bgColor = new Color(255, 255, 225);
_border = Color.BLACK;
_messageColor = Color.BLACK;
_useTop = true;
// 通過調用方法,強制獲知是否支持自動窗體置頂
try {
JWindow.class.getMethod("setAlwaysOnTop",
new Class[] { Boolean.class });
} catch (Exception e) {
_useTop = false;
}
}
/**
* 重構JWindow用于顯示單一氣泡提示框
*
*/
class ToolTipSingle extends JWindow {
private static final long serialVersionUID = 1L;
private JLabel _iconLabel = new JLabel();
private JTextArea _message = new JTextArea();
public ToolTipSingle() {
initComponents();
}
private void initComponents() {
setSize(_width, _height);
_message.setFont(getMessageFont());
JPanel externalPanel = new JPanel(new BorderLayout(1, 1));
externalPanel.setBackground(_bgColor);
// 通過設定水平與垂直差值獲得內部面板
JPanel innerPanel = new JPanel(new BorderLayout(getGap(), getGap()));
innerPanel.setBackground(_bgColor);
_message.setBackground(_bgColor);
_message.setMargin(new Insets(4, 4, 4, 4));
_message.setLineWrap(true);
_message.setWrapStyleWord(true);
// 創建具有指定高亮和陰影顏色的陰刻浮雕化邊框
BevelBorder etchedBorder = (BevelBorder) BorderFactory
.createBevelBorder(BevelBorder.LOWERED,
new Color(45,92,162),
new Color(43,66,97),
new Color(45,92,162),
new Color(84,123,200));
// 設定外部面板內容邊框為風化效果
externalPanel.setBorder(etchedBorder);
// 加載內部面板
externalPanel.add(innerPanel);
_message.setForeground(getMessageColor());
innerPanel.add(_iconLabel, BorderLayout.WEST);
innerPanel.add(_message, BorderLayout.CENTER);
getContentPane().add(externalPanel);
}
/**
* 動畫開始
*
*/
public void animate() {
new Animation(this).start();
}
}
/**
* 此類處則動畫處理
*
*/
class Animation extends Thread {
ToolTipSingle _single;
public Animation(ToolTipSingle single) {
this._single = single;
}
/**
* 調用動畫效果,移動窗體坐標
*
* @param posx
* @param startY
* @param endY
* @throws InterruptedException
*/
private void animateVertically(int posx, int startY, int endY,boolean setLocationBool)
throws InterruptedException {
_single.setLocation(posx, startY);
if (endY < startY) {
for (int i = startY; i > endY; i -= _step) {
if(setLocationBool){
_single.setLocation(posx, startY);
}else{
_single.setLocation(posx, i);
}
Thread.sleep(_stepTime);
}
} else {
for (int i = startY; i < endY; i += _step) {
if(setLocationBool){
_single.setLocation(posx, startY);
}else{
_single.setLocation(posx, i);
}
Thread.sleep(_stepTime);
}
}
if(setLocationBool){
_single.setLocation(posx, startY);
}else{
_single.setLocation(posx, endY);
}
}
/**
* 開始動畫處理
*/
public void run() {
try {
boolean animate = true;
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
Rectangle screenRect = ge.getMaximumWindowBounds();
int screenHeight = (int) screenRect.height;
int startYPosition;
int stopYPosition;
if (screenRect.y > 0) {
animate = false;
}
_maxToolTipSceen = screenHeight / _height;
int posx = (int) screenRect.width - _width - 5;
if(setLocationBool){
_single.setLocation(posx, screenHeight);
}else{
_single.setLocation(pointX, pointY);
}
_single.setVisible(true);
if (_useTop) {
_single.setAlwaysOnTop(true);
}
if (animate) {
startYPosition = screenHeight;
stopYPosition = startYPosition - _height - offset;
if (_countOfToolTip > 0) {
stopYPosition = stopYPosition
- (_maxToolTip % _maxToolTipSceen * _height);
} else {
_maxToolTip = 0;
}
} else {
startYPosition = screenRect.y - _height;
stopYPosition = screenRect.y;
if (_countOfToolTip > 0) {
stopYPosition = stopYPosition
+ (_maxToolTip % _maxToolTipSceen * _height);
} else {
_maxToolTip = 0;
}
}
_countOfToolTip++;
_maxToolTip++;
if(setLocationBool){
animateVertically(pointX,pointY,stopYPosition,setLocationBool);
}else{
animateVertically(posx, startYPosition, stopYPosition,setLocationBool);
}
Thread.sleep(_displayTime);
if(!setLocationBool){
animateVertically(posx, stopYPosition, startYPosition,setLocationBool);
}
_countOfToolTip--;
_single.setVisible(false);
_single.dispose();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/**
* 設定顯示的圖片及信息
*
* @param icon
* @param msg
*/
public void setToolTip(Icon icon, String msg) {
ToolTipSingle single = new ToolTipSingle();
if (icon != null) {
single._iconLabel.setIcon(icon);
}
single._message.setText(msg);
single.animate();
}
/**
* 設定顯示的信息
*
* @param msg
*/
public void setToolTip(String msg) {
setToolTip(null, msg);
}
/**
* 獲得當前消息字體
*
* @return
*/
public Font getMessageFont() {
return _font;
}
/**
* 設置當前消息字體
*
* @param font
*/
public void setMessageFont(Font font) {
_font = font;
}
/**
* 獲得邊框顏色
*
* @return
*/
public Color getBorderColor() {
return _border;
}
/**
* 設置邊框顏色
*
* @param _bgColor
*/
public void setBorderColor(Color borderColor) {
this._border = borderColor;
}
/**
* 獲得顯示時間
*
* @return
*/
public int getDisplayTime() {
return _displayTime;
}
/**
* 設置顯示時間
*
* @param displayTime
*/
public void setDisplayTime(int displayTime) {
this._displayTime = displayTime;
}
/**
* 獲得差值
*
* @return
*/
public int getGap() {
return _gap;
}
/**
* 設定差值
*
* @param gap
*/
public void setGap(int gap) {
this._gap = gap;
}
/**
* 獲得信息顏色
*
* @return
*/
public Color getMessageColor() {
return _messageColor;
}
/**
* 設定信息顏色
*
* @param messageColor
*/
public void setMessageColor(Color messageColor) {
this._messageColor = messageColor;
}
/**
* 獲得循環步長
*
* @return
*/
public int getStep() {
return _step;
}
/**
* 設定循環步長
*
* @param _step
*/
public void setStep(int _step) {
this._step = _step;
}
public int getStepTime() {
return _stepTime;
}
public void setStepTime(int _stepTime) {
this._stepTime = _stepTime;
}
public Color getBackgroundColor() {
return _bgColor;
}
public void setBackgroundColor(Color bgColor) {
this._bgColor = bgColor;
}
public int getHeight() {
return _height;
}
public void setHeight(int height) {
this._height = height;
}
public int getWidth() {
return _width;
}
public void setWidth(int width) {
this._width = width;
}
public static void main(String[] args) {
ToolTip tip = new ToolTip(350,200,false);//true代表特定設置該氣泡的坐標,50,100分別代表該氣泡的X,Y軸坐標
tip.setToolTip(null,"“程序員”就是特指越寫程序身材越“圓”那群人 -- cping1982"+"\r\n"+"------------"+"\r\n"+"ffffffffff");
}
}