0

我有一个基本的小通知类,可以在 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);

有什么想法可以解决这个问题吗?

4

1 回答 1

1

在构造函数中,您正在调用setDefaultLookAndFeelDecorated(true). 这不会影响第一帧(因为它已经创建),但会影响所有后续帧,然后获得当前窗口管理器定义的默认装饰 - 这在 Mac 和 Win 上可能不同。

只需删除呼叫即可解决问题。

于 2013-09-29T17:35:22.813 回答