javaswingjbuttonchangelistener

Java isRollover() method does not produce an event in my swing application


I am reading a great book called Swing: A Beginner's guide. There is this code in the book that creates a button and a label that alerts on button's state change events :

//Demonstrate a change listener and the button model

package swingexample2_6;

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class ChangeDemo {

    JButton jbtn;
    JLabel jlab;

    public ChangeDemo() {
        //Create a new JFrame container
        JFrame jfrm = new JFrame("Button Change Events");

        //Specify FlowLayout for the layout manager
        jfrm.getContentPane().setLayout(new FlowLayout());

        //Give the frame an initial size
        jfrm.setSize(250, 160);

        //Terminate the program when the user closes the application
        jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create an empty label
        jlab = new JLabel();

        //Make a button
        jbtn = new JButton("Press for Change Event Test");

        //--Add change listener
        jbtn.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent ce) {
                ButtonModel mod = jbtn.getModel();
                String what = "";

                if (mod.isEnabled()) {
                    what += "Enabled<br>";
                }
                if (mod.isRollover()) {
                    what += "Rollover<br>";
                }
                if (mod.isArmed()) {
                    what += "Armed<br>";
                }
                if (mod.isPressed()) {
                    what += "Pressed<br>";
                }

                //Notice that this label's text is HTML
                jlab.setText("<html>Current stats:<br>" + what);
            }
        });


        //Add the components to the content pane
        jfrm.getContentPane().add(jbtn);
        jfrm.getContentPane().add(jlab);

        //Display the frame
        jfrm.setVisible(true);
    }

    public static void main(String[] args) {
        //Create the frame on the event dispatching thread
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ChangeDemo();
            }
        });
    }
}

Everything is working fine except for the rollover event. The underlying operating system is Mac OS Lion. Should I blame Lion for this swing problem or am I doing something wrong? Thank you.

Update 1 : My neatbeans settings picture (I hope it helps) settings


Solution

  • Code as tested on Leopard with Java version 1.6.0_26 shown below. The trailing </html> tag fixed a highlighting glitch on rollover.

    Addendum: Using the updated example below, adding setRolloverEnabled(true) allows the model to work as expected. Interestingly, the Mac UI delegate, com.apple.laf.AquaButtonUI, does nothing when isRollover() is true. If it's important to your application, you can take the desired action when the following predicate is true:

    System.getProperty("os.name").startsWith("Mac OS X")
    

    For reference, this example demonstrates setRolloverIcon().

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class ChangeDemo {
    
        private JButton jbtn;
        private JLabel jlab;
    
        public ChangeDemo() {
            JFrame jfrm = new JFrame("Button Change Events");
            jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jfrm.setLayout(new GridLayout(0, 1));
            jlab = new JLabel("", JLabel.CENTER);
            jbtn = new JButton("Press for Change Event Test");
            jbtn.setRolloverEnabled(true);
    
            jbtn.addChangeListener(new ChangeListener() {
    
                @Override
                public void stateChanged(ChangeEvent ce) {
                    ButtonModel mod = jbtn.getModel();
                    String what = "";
    
                    if (mod.isEnabled()) {
                        what += "Enabled<br>";
                    }
                    if (mod.isRollover()) {
                        what += "Rollover<br>";
                    }
                    if (mod.isArmed()) {
                        what += "Armed<br>";
                    }
                    if (mod.isPressed()) {
                        what += "Pressed<br>";
                    }
    
                    //Notice that this label's text is HTML
                    jlab.setText("<html>Current stats:<br>" + what + "</html>");
                }
            });
    
            JPanel panel = new JPanel();
            panel.setBorder(BorderFactory.createEmptyBorder(50, 10, 0, 10));
            panel.add(jbtn);
            jfrm.add(panel);
            jfrm.add(jlab);
    
            jfrm.pack();
            jfrm.setLocationRelativeTo(null);
            jfrm.setVisible(true);
        }
    
        public static void main(String[] args) {
            //Create the frame on the event dispatching thread
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    ChangeDemo changeDemo = new ChangeDemo();
                }
            });
        }
    }