Friday, September 25, 2009

Dynamically change color of Node icon(2)

I blogged about the way to change the color of an icon dynamically here. Now, I have encountered that when I add those icons to a list of nodes or menu items, all icons get the color of the last one changed. Hmpf.

It looks like that ImageUtilities.loadImage(..) somehow caches the icon and hence even when assuming working on a new copy we still work on the common one.

The way I got it working was to forcefully create a new BufferedImage and merge in the one just loaded. The new code looks like this



private BufferedImage icon16;
private BufferedImage icon32;
public static final String PROP_ID = "id";
public static final String PROP_NAME = "displayName";
public static final String PROP_COMMENT = "comment";
public static final String PROP_COLOR = "color";
public static final String PROP_ICON16 = "icon16";
public static final String PROP_ICON32 = "icon32";

// ...

public Image getSmallImage() {
int width = icon16.getWidth();
int height = icon16.getHeight();

BufferedImage newImage = new BufferedImage(width,height,BufferedImage.TYPE_4BYTE_ABGR);
newImage = (BufferedImage)ImageUtilities.mergeImages(icon16, newImage, 0, 0);

for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = newImage.getRGB(x, y);
if (newImage.getRGB(x, y) < 0) {
rgb = some_method_returning_the_RGB_for_a_selected_color;
newImage.setRGB(x, y, rgb);
}
}
}
return newImage;
}

// ...

private void loadIcons() {
String iconId = props.getProperty(PROP_ICON16);
icon16 = (BufferedImage)ImageUtilities.loadImage(iconId);
iconId = props.getProperty(PROP_ICON32);
icon32 = (BufferedImage)ImageUtilities.loadImage(iconId);
}




And it now respects each individual color.

Friday, September 18, 2009

Update build zip distribution with additional files

Inspired by a discussion on the NetBeans Developer Forum, (dev@openide.netbeans.org), and seen multiple struggeling with this, I would like to capture how to add some files or directories to the ZIP distro file on build

Suppose you have a directory in your sandbox you would like to add to the distro. This could be source code from an OpenSource project you have edited and hence have to make public, or some other directories. You may already have choosen to add the target build-launchers to copy those to the build directory like:

<target name="build-launchers" depends="suite.build-launchers">
<copy todir="${build.launcher.dir}">
<fileset dir="MyExtraDirectory"/>
</copy>
</target>

You can hereafter add the target which will add this directory to the zip file build simply by leveraging ant commands


<!-- Customized build-zip target to copy reports to the distribution -->
<target name="build-zip" depends=quot;suite.build-zip">
<!-- Update the just created ZIP with additional directories/data -->
<echo message="Adding MyExtraDirectory ..."/>
<zip destfile="${dist.dir}/${app.name}.zip" update="true">
<zipfileset dir="${build.launcher.dir}/MyExtraDirectory/" prefix="${app.name}/MyExtraDirectory"/>
</zip>
</target>


Done.

Thursday, September 10, 2009

Clipping with Visual Library

For a while I had trouble with clipping but I never gave it the attention needed to figure it out. Now I really needed it and here my findings.

I had a Scene on top I was drawing a Rectangle represented in a Widget using resizeable Border, sitting in a LayerWidget on the Scene.

I wanted
A) The Scene not to extend into the negative numbers when the user dragged the Rectangle to the left (over the x=0 line)
B) The Rectangle to be clipped when exiting to the left
C) The Rectangle to be clipped when exiting to the right border of the Scene

The solution is

scene.setMaximumBounds(new Rectangle(0,0,width,height));
scene.setMaximumSize(new Dimension(width,height));
scene.validate();
scene.setCheckClipping(true);

In addition you have to set clipping on the LayerWidget holding the Widget representing the Rectangular

myLayerWidget.setCheckClipping(true);

This last line makes sure that the rectangle is still partly visible when it gets dragged over the edges of the defined scene size. If you would omit this last setting, the rectangle would be clipped in its total when outside the edge of the scene and you do not get the partly clipped image.

Wednesday, September 2, 2009

Property Sheet Props not visual updating

I just run into an issue which was discussed a couple of month ago here on the NetBeans Dev mailing list. (see here)

Now, assuming we have the scenario of the MyBean as model as shown as an example in Wade Chandlers first answer. Now also assume you have a MyBeanNode which is representing this data.

Also assume you have the MyBeanNode listening to PropertyChanges to MyBean via some line like

myBean.addPropertyChangeListener(WeakListeners.
propertyChange(this, myBean));


The propertyChange(...) method in MyBeanNode will do needed updates to the model etc.

So far so good.

Now I was tempted to add the option to allow to Rename the object.

1) I added canRename() to the MyBeanNode and let it return true.
2) I added the Action[] getActions(..) method and made sure to add the SystemAction.get(RenameAction.class)
3) I added the setName(..) method

Happy a Rename popup was available and when I rename the object the Node name was changed - but - the name field in the Property Window was still showing the old value. Even though when doing some refreshing action like collapsing and expanding the property Sheet Set it was showing the correct value.

Hmpf - very similar to the problem the person in the discussion encountered.

Now .. the solution is to add the following line to the setName(String name) method of your MyBeanNode

this.firePropertyChange("name", oldname, newname)

Note, this is fire'ring a property change event to all listening to changes in the Node - while the pcs.firePropertyChange(...) call in the MyBean was sending it to its listeners - which was the MyBeanNode in this case.

Without knowing I assume that the PropertySheet's GUI is listening to PropertyChanges in the Node ? Well - anyhow - this solved my problem and the problem discussed in the link above.