Alosyius
Alosyius

Reputation: 9121

Java undecorated jFrame not working on Windows

I have a basic little notification class that works perfectly on Mac but on Windows it produces the following results as seen on the image:

enter image description here

My class:

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();
            }
    }    
}

So for some strange reason the first one displays correctly but the others after that do not.

This is how im calling my notification class:

Notification ntf = new Notification((NotificationParent)this, from, msg, time, channel, conversationName, name);

Any ideas how this can be fixed?

Upvotes: 0

Views: 1156

Answers (1)

david a.
david a.

Reputation: 5291

In the constructor, you are calling setDefaultLookAndFeelDecorated(true). This does not affect the first frame (as that is already created), but influences all the subsequent ones, that then get the default decorations the current window manager defines - which might be different on Mac and on Win.

Simply removing the call should resolve the problem.

Upvotes: 1

Related Questions