Rotating a NetBeans Visual Library Widget
- by Geertjan
Trying to create a widget which, when clicked, rotates slightly further on each subsequent click:
Above, the bird where the mouse is visible has been clicked a few times and so has rotated a bit further on each click.
The code isn't quite right yet and I'm hoping someone will take this code, try it out, and help with a nice solution!
public class BirdScene extends Scene {
public BirdScene() {
addChild(new LayerWidget(this));
getActions().addAction(ActionFactory.createAcceptAction(new AcceptProvider() {
public ConnectorState isAcceptable(Widget widget, Point point, Transferable transferable) {
Image dragImage = getImageFromTransferable(transferable);
if (dragImage != null) {
JComponent view = getView();
Graphics2D g2 = (Graphics2D) view.getGraphics();
Rectangle visRect = view.getVisibleRect();
view.paintImmediately(visRect.x, visRect.y, visRect.width, visRect.height);
g2.drawImage(dragImage,
AffineTransform.getTranslateInstance(point.getLocation().getX(),
point.getLocation().getY()),
null);
return ConnectorState.ACCEPT;
} else {
return ConnectorState.REJECT;
}
}
public void accept(Widget widget, final Point point, Transferable transferable) {
addChild(new BirdWidget(getScene(), getImageFromTransferable(transferable), point));
}
}));
}
private Image getImageFromTransferable(Transferable transferable) {
Object o = null;
try {
o = transferable.getTransferData(DataFlavor.imageFlavor);
} catch (IOException ex) {
} catch (UnsupportedFlavorException ex) {
}
return o instanceof Image ? (Image) o : null;
}
private class BirdWidget extends IconNodeWidget {
private int theta = 0;
public BirdWidget(Scene scene, Image imageFromTransferable, Point point) {
super(scene);
setImage(imageFromTransferable);
setPreferredLocation(point);
setCheckClipping(true);
getActions().addAction(ActionFactory.createMoveAction());
getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
public boolean isAimingAllowed(Widget widget, Point localLocation, boolean invertSelection) {
return true;
}
public boolean isSelectionAllowed(Widget widget, Point localLocation, boolean invertSelection) {
return true;
}
public void select(final Widget widget, Point localLocation, boolean invertSelection) {
theta = (theta + 100) % 360;
repaint();
getScene().validate();
}
}));
}
@Override
public void paintWidget() {
final Image image = getImageWidget().getImage();
Graphics2D g = getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle bounds = getClientArea();
AffineTransform newXform = g.getTransform();
int xRot = image.getWidth(null) / 2;
int yRot = image.getWidth(null) / 2;
newXform.rotate(theta * Math.PI / 180, xRot, yRot);
g.setTransform(newXform);
g.drawImage(image, bounds.x, bounds.y, null);
}
}
}
The problem relates to refreshing the scene after the rotation. But it would help if someone would just take the code above, add it to their own application, try it out, see the problem for yourself, and develop it a bit further!