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 http://i44.tinypic.com/vdzg92.png
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();
}
});
}
}
javax.swing.plaf.metal.MetalLookAndFeel
; more above - trashgod 2012-04-06 17:02
Okay okay. I know this has been answered really well already, and the OP's question was on a Mac, but this answer needs sharin'.
If you are on Windows 7, rollover effects won't work if you have the theme set to "Classic". Set it to "Basic" and rollovers will work.