我有一个基本的小通知类,可以在 Mac 上完美运行,但在 Windows 上它会产生以下结果,如图所示:
我的课:
public class Notification extends JFrame {
Timer timer;
private static int count = 0;
private String from;
private String msg;
private String time;
private final JLabel jLabel1;
private final JLabel jLabel2;
private final JLabel jLabel3;
private final JLabel jLabel4;
private NotificationParent parent;
public String clFrom;
public void playSound() {
Properties prop = new Properties();
try {
prop.load(new FileInputStream("config.properties"));
if(notEmpty(prop.getProperty("sound"))) {
try {
AudioInputStream audioIn = AudioSystem.getAudioInputStream(getClass().getResource("/resources/chat_alert.wav"));
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
}catch(Exception e) {
// Could not load sound
}
}
} catch (IOException ex) {
// Could not read config.properties
}
}
public void NotificationStart(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
timer.cancel(); //Terminate the timer thread
dispose(); // Remove the window
count--;
}
}
public Notification(final NotificationParent parent, String from, String msg, String time, final String channel, final String conversationName, final String visitorName) {
this.parent = parent;
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
clFrom = from;
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
setBackground(new Color(0, 0, 0, 0)); // alpha <1 = transparent
setUndecorated(true);
setSize(308,77);
setDefaultLookAndFeelDecorated(true);
setAlwaysOnTop(true);
setVisible(true);
jLabel2.setFont(new java.awt.Font("Lucida Grande", 1, 12));
if(visitorName != null && !visitorName.isEmpty()) {
jLabel2.setText(visitorName + ":");
} else {
jLabel2.setText(from + ":");
}
jLabel2.setBounds(38, 11, 240, 15);
jLabel1.add(jLabel2);
jLabel3.setFont(new java.awt.Font("Lucida Grande", 0, 12));
jLabel3.setText(msg);
jLabel3.setBounds(38, 25, 240, 50);
jLabel1.add(jLabel3);
jLabel4.setBounds(280, 6, 16, 16);
jLabel1.add(jLabel4);
//System.out.println("First number = " + count );
NotificationStart(8);
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/notification.png")));
getContentPane().add(jLabel1);
jLabel1.setBounds(0, 0, 308, 77);
// Position it
GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
int x = (int) rect.getMaxX() - (this.getWidth() + 10);
int y;
if(this.count == 0) {
y = (int) rect.getMinY() - 46 + this.getHeight();
} else {
y = (int) rect.getMinY() + 30 + (this.getHeight() * this.count);
}
this.setLocation(x, y);
Properties prop = new Properties();
try {
prop.load(new FileInputStream("config.properties"));
if(notEmpty(prop.getProperty("notifications"))) {
try {
this.setVisible(true);
} catch(Exception e) {
JOptionPane.showMessageDialog(rootPane, "Your current version of Java does not support desktop notifications.");
try {
prop.setProperty("notifications", "");
prop.store(new FileOutputStream("config.properties"), null);
} catch (IOException ex) {
// Could not save to config.properties
}
}
}
} catch (IOException ex) {
}
this.count = count + 1;
playSound();
/**
* Event listeners
*/
jLabel1.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
// Remove notification if user clicks it
dispose();
parent.selectChannel(channel, conversationName, visitorName);
}
public void mouseEntered(MouseEvent e) {
// Show the close icon
jLabel4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/icnClose.png")));
}
public void mouseExited(MouseEvent e) {
// Hide the close icon
jLabel4.setIcon(null);
}
});
}
public static boolean notEmpty(String s) {
return (s != null && s.length() > 0);
}
public void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(false);
}
// taken from: http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/
private void setTranslucency( Window window){
try {
Class<?> awtUtilitiesClass = Class.forName("com.sun.awt.AWTUtilities");
Method mSetWindowOpacity = awtUtilitiesClass.getMethod("setWindowOpacity", Window.class, float.class);
mSetWindowOpacity.invoke(null, window, Float.valueOf(0.85f));
} catch (NoSuchMethodException ex) {
ex.printStackTrace();
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (InvocationTargetException ex) {
ex.printStackTrace();
}
}
}
因此,出于某种奇怪的原因,第一个显示正确,但之后的其他显示不正确。
这就是我调用我的通知类的方式:
Notification ntf = new Notification((NotificationParent)this, from, msg, time, channel, conversationName, name);
有什么想法可以解决这个问题吗?