X

Geertjan's Blog

  • February 20, 2011

Co-ordinating JRadioButtons in the NetBeans Platform Toolbar

Geertjan Wielenga
Product Manager
I now have a solution for co-ordinating JRadioButtons (and, as a consequence, JCheckBoxes and their related menu item equivalents, as well) in the NetBeans Platform toolbar. In the screenshot below, there are three radio buttons in the toolbar ("Zoom In", "Zoom Out", and "Pan"), which work as one might expect:

I started by creating a separate class for co-ordinating the listening to changes in item state. I.e., whenever a different radio button is selected, existing listeners are removed and new ones are added, while the cursor is changed and a message is displayed in the status bar:

public class ButtonGroupItemListener {
public static ZoomMouseListener zoomMouseListener;
public static PanMouseListener panMouseListener;
public static PanMouseMotionListener panMouseMotionListener;
private static ImagePanel imagePanel;
protected static PanUtility pan;
public static ItemListener il = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
imagePanel.removeMouseListener(zoomMouseListener);
imagePanel.removeMouseListener(panMouseListener);
imagePanel.removeMouseMotionListener(panMouseMotionListener);
JRadioButton source = (JRadioButton) e.getItemSelectable();
String name = source.getName();
if (name.equals("ZoomIn")) {
zoomMouseListener = new ZoomMouseListener(1.1);
imagePanel.addMouseListener(zoomMouseListener);
ImageIcon ICON = ImageUtilities.loadImageIcon("toolbarButtonGraphics/general/ZoomIn16.gif", true);
Cursor c = Toolkit.getDefaultToolkit().createCustomCursor(ICON.getImage(), new Point(0, 0), "ZOOMIN");
imagePanel.setCursor(c);
StatusDisplayer.getDefault().setStatusText("Zoom in enabled...");
} else if (name.equals("ZoomOut")) {
zoomMouseListener = new ZoomMouseListener(0.9);
imagePanel.addMouseListener(zoomMouseListener);
ImageIcon ICON = ImageUtilities.loadImageIcon("toolbarButtonGraphics/general/ZoomOut16.gif", true);
Cursor c = Toolkit.getDefaultToolkit().createCustomCursor(ICON.getImage(), new Point(0, 0), "ZOOMOUT");
imagePanel.setCursor(c);
StatusDisplayer.getDefault().setStatusText("Zoom out enabled...");
} else if (name.equals("Pan")) {
pan = new PanUtility();
panMouseListener = new PanMouseListener();
panMouseMotionListener = new PanMouseMotionListener();
imagePanel.addMouseListener(panMouseListener);
imagePanel.addMouseMotionListener(panMouseMotionListener);
Cursor c = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
imagePanel.setCursor(c);
StatusDisplayer.getDefault().setStatusText("Pan enabled...");
}
}
};
public static ItemListener getListener(ImagePanel panel) {
imagePanel = panel;
return il;
}
...
...
...

Take note of the accessor above. It is used in each Action that defines one of the radio buttons.

For example, here is the "ZoomInAction", take note especially of the lines in bold:

public class ZoomInAction extends AbstractAction implements Presenter.Toolbar, LookupListener {
private final Lookup.Result result;
private ImagePanel imagePanel;
private JRadioButton zoomInRadioButton;private ItemListener il = ButtonGroupItemListener.getListener(imagePanel);
private final ImageIcon ICON = ImageUtilities.loadImageIcon("toolbarButtonGraphics/general/ZoomIn16.gif", true);
public ZoomInAction() {
result = Utilities.actionsGlobalContext().lookupResult(ImagePanel.class);
result.addLookupListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
//not needed
}
@Override
public Component getToolbarPresenter() {
zoomInRadioButton = new JRadioButton("Zoom In");
zoomInRadioButton.setName("ZoomIn");
zoomInRadioButton.setEnabled(false);
ButtonGroup local = ButtonGroupHelper.returnGroup();
local.add(zoomInRadioButton);
return zoomInRadioButton;
}
@Override
public void resultChanged(LookupEvent ev) {
if (result.allInstances().iterator().hasNext()) {
imagePanel = (ImagePanel) result.allInstances().iterator().next();
zoomInRadioButton.setEnabled(true);zoomInRadioButton.addItemListener(il);
if (zoomInRadioButton.isSelected()) {
Cursor c = Toolkit.getDefaultToolkit().createCustomCursor(ICON.getImage(), new Point(0, 0), "ZOOMIN");
imagePanel.setCursor(c);
StatusDisplayer.getDefault().setStatusText("Zoom in enabled...");
}
} else {
zoomInRadioButton.setSelected(false);
zoomInRadioButton.setEnabled(false);zoomInRadioButton.removeItemListener(il);
Cursor c = Cursor.getDefaultCursor();
imagePanel.setCursor(c);
}
}
}

That's how my radio button solution works. Don't know if it's optimal, but it gets the job done.

Join the discussion

Comments ( 1 )
  • Walter Laan Wednesday, February 23, 2011

    A static listener is that really needed for Netbeans?

    I would create MouseMode enum and a method ImagePanel#setMouseMode(MouseMode) to avoid the code duplication you have.

    Swing Actions do have a selected property but it's only updated if it is not null (eg in the Action constructor call putValue(SELECTED_KEY, false);).

    You can just set the action to the JRadioButton and check selected in the actionPerformed and call the setMouseMode method. Then the static item listener is not needed and everything is neatly contained in the Action (with the logic of what to do when the mouse mode changes in the ImagePanel where it belongs).


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.