Subscribe: The Rabbit Hole
http://rabbit-hole.blogspot.com/rss.xml
Added By: Feedage Forager Feedage Grade B rated
Language: English
Tags:
code  int  java  jna  material timothy  native  rights reserved  thread  timothy wall all  user  wall all rights  window 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: The Rabbit Hole

The Rabbit Hole



Things I've found on the way to Getting There



Last Build Date: Wed, 06 Sep 2017 03:02:37 +0000

 



Potamus update

Fri, 20 Sep 2013 11:46:00 +0000

The GAE cost profiling graphs have gotten a facelift, now using flot instead of Google visualizations. I rapidly hit the limit of the GViz capabilities (one notable shortcoming is the lack of support for sparsely-populated data). Most of the controls are now completely client-side, which makes it a lot easier to tweak the graph to get just the information you'd like. Flot generally provides more CSS-level control over styling, and a nice plugin system to allow for mixing features.




Sun, 30 Jun 2013 13:13:00 +0000

App Engine real-time cost profiling is available on github.  Some assembly required.



Cost profiling on Google App Engine

Wed, 10 Apr 2013 13:39:00 +0000

I've recently been measuring costs for various operations that are currently being performed on Google App Engine.  Google provides some cost estimates on the app engine dashboard, and you can get historical daily totals, but it's generally not straightforward to answer the question "How much does this operation cost (or is going to cost if I ramp up)?".

The google-provided appstats is fine for profiling individual requests, but sometimes you need a much more comprehensive view.

With a Chrome extension to monitor the app engine dashboard numbers, and a small app engine app to collect data, I've managed to collect some interesting intra-day profile data, as well as provide a means for fairly accurate estimates of discrete operations.

Group view (for multiple app IDs).  The artifact on the left is due to two days' worth of missing data.  The lower graph has an obvious daily cron job, while the upper has much more distributed activity:

 Zoomed view (detail for a single app ID).  On this graph, you can see some annotations have been added; the data collector provides an API for applications to post events that can be overlaid on the cost data, making it easy to pick start and end points and calculating the cost for the selected span:


This project is now available on github.  The Chrome extension is based on the OSE (Offline Statistics Estimator) which scrapes usage data and applies customizable usage rates from the GAE dashboard pages.




Enable cProfile in Google App Engine

Wed, 30 Jan 2013 13:49:00 +0000

If it's not readily apparent to you how to enable CPU profiling on Google App Engine (it certainly wasn't to me, aside from a few hand waves at cProfile), this code snippet should get you up and running so you can focus on finding the data you need rather than the implied interfaces you have to mimic.  It uses the standard WSGI middleware hook to wrap an incoming request in a cProfile call, formatting and dumping the resulting stats to the log when the request returns:


def cprofile_wsgi_middleware(app):
    """
    Call this middleware hook to enable cProfile on each request.  Statistics are dumped to
    the log at the end of the request.
    :param app: WSGI app object
    :return: WSGI middleware wrapper
    """

    def _cprofile_wsgi_wrapper(environ, start_response):
        import cProfile, cStringIO, pstats
        profile = cProfile.Profile()
        try:
            return profile.runcall(app, environ, start_response)
        finally:
            stream = cStringIO.StringIO()
            stats = pstats.Stats(profile, stream=stream)
            stats.strip_dirs().sort_stats('cumulative', 'time', 'calls').print_stats(25)
            logging.info('cProfile data:\n%s', stream.getvalue())
    return _cprofile_wsgi_wrapper

def webapp_add_wsgi_middleware(app):
    return cprofile_wsgi_middleware(app)



Thread termination/exit handlers

Sat, 22 Sep 2012 13:57:00 +0000

I'd been hunting for a while for a good solution to automatically call cleanup operations on exit from threads I didn't own.  Windows (XP onward) has a pretty straightforward solution if you're working with a DLL, but for pthreads on most other platforms, the solution is not as obvious.Some folks have been using JNA to allow Java code to be invoked as callbacks from various streaming (video, sound) libraries.  If these callbacks come from threads instantiated from native code, the JVM has to (at least temporarily) map the thread into Java space for the duration of the callback.  If the callbacks are frequent, and always come in on the same native thread, we don't want to incur the mapping overhead on every invocation.  The solution, then is to avoid detaching the thread when the callback finishes.Now we have a new problem.  When the native thread actually terminates, the JVM has no idea that the thread went away because it's only really got a placeholder Thread object, and hasn't hooked up all the plumbing it normally does to detect that the thread has gone away and clean up/GC the mapped Thread object.  Thus the need for a thread exit handler.  In some cases, you may not care about the minimal object overhead, for instance if you've just got a few native threads.  However, with a lot of threads coming and going (we can't force folks to thread-pool).WindowsOn Windows, if you have a DllMain function defined, you'll get notices when threads and processes attach/detach your DLL's code.  This works out nicely, we can make the VM detach the current thread when we get that message:// Store thread-local information required to detach the thread// (in my case, only a JVM reference was required)// TlsSetValue is only set when we recognize that we need the // extra cleanupstatic DWORD dwTlsIndex;BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: dwTlsIndex = TlsAlloc(); if (dwTlsIndex == TLS_OUT_OF_INDEXES) { return FALSE; } break; case DLL_PROCESS_DETACH: TlsFree(dwTlsIndex); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: { extern void detach_thread(); detach_thread(TlsGetValue(dwTlsIndex)); break; } default: break; } return TRUE;} Easy enough.  Note that TlsSetValue is called elsewhere only when the callback decides it doesn't want to detach immediately (rather than every time a native thread attaches).  Callbacks normally detach on exit if they weren't attached to begin with.POSIX Threads (pthreads)The pthreads library is a different beast.  Searches for "thread termination handler" don't turn up much, except for the stack-based pthread_cancel_push/pop, which seems to do the right thing, but have to arrive in pairs.  It's actually in the pthreads implementation of thread-local storage that we find a way to attach a termination handler to a given thread.When you define a given thread-local variable in pthreads (a "key" in pthreads lingo), you can provide a destructor function to be used to clean up the storage...on thread exit.  It was a little hard to find since it's not a thread termination handler per se, but rather a mechanism to clean up thread local storage.  I'd overlooked it several times because I wasn't looking for thread local storage solutions.// Basic plumbing to create a unique key identifying// specific thread-local storagestatic pthread_key_t key;static void make_key() { extern void detach_thread(); pthread_key_create(&key, detach_thread);} ... // This code gets called whenever we identify that // a thread needs detach-on-exit behavior static pthread_once_t key_once = PTHREAD_ONCE_INIT; pthread_once(&key_once, make_key); if (!jvm || pthread_getspecific(key) == NULL) { pthread_setspecific(key, jvm); } ...Now detach_threa[...]



WebStart unit tests

Sat, 10 Oct 2009 12:32:00 +0000

I had a few bits of JNA functionality that were only active when in a web start environment, which made it a bit tricky to add tests for them that could be run at the same time as all my other tests. The functionality also showed up as a big splot of missing code coverage under clover, so I decided to tinker just a bit to see if I could somehow simulate a web start environment for the unit tests.

I managed to come up with a JUnit-based test fixture which ensures its test methods are all run in a web start environment. This works well under Windows and OSX; unfortunately *nix variations use NetX which needs some extra hand-holding when first run.

Finding the right hooks involved standard hacking to find whether the most configurability was offered by invoking the javaws executable or adding the javaws classes to my classpath and hooking directly into the Java. I ended up doing a Runtime.exec to ensure the running environment wouldn't interfere with that of Web Start.

The main obstacle to be overcome was signed code. You can get web start to run unsigned code by tweaking the local policy file to allow the code we're testing, but when you include any native code via the tag, JNLP requires the tag, which seems to re-trigger the requirement for signed code. Self-signing the code is no big deal, but that triggers web-starts authorization dialogs to allow the unknown CA to be used. Fortunately, the somewhat obscure deployment properties file can be used to temporarily allow the self-signed certs and bypass the dialogs. The tests can be run entirely without user input (except in the case of *nix, where NetX is not sufficiently configurable -- you have to dismiss the dialog on the first test run).

Unfortunately the exit codes for javaws don't correspond to the codes passed to System.exit by Java code, so I had to have the test fixture communicate to the running javaws instance via socket. Failures are transmitted by the fixture in such a way that you can't tell that the test is running in a separate process.

I encapsulated the deployment config, JNLP file creation, javaws launch, and test case execution into a single class, WebStartTest, which runs a few self tests and can be extended to add whatever other tests you need to run under web start. The JNLP is partly hard-coded to include files set up sepecifically for JNA testing, but should be trivial to change to accommodate a different project.

There are probably other ways to test WebStart code, but this fit nicely with the project's existing tests, allowing its WebStart features to be tested by test methods identical to those for the rest of the project.

Full source is here. This has been tested under Sun and IBM JDKs, on Windows, OSX, Solaris/sparc, and GNU/Linux.



JNA: increasing performance with large Structures

Fri, 12 Sep 2008 01:24:00 +0000

If you're using very large structures and using them often, here's a tip that can boost performance by several orders of magnitude. Note that you should follow this tip *only* if you really need the performance boost; otherwise you may wind up obfuscating your code.

By default, when JNA makes a native call it will copy the full contents of a Java Structure to native memory prior to the call and read it all back after the call. If your Structure is very large, this can result in significant overhead reflecting all the fields of the Structure. The reflection dwarfs the actual native communication time.

If you're only reading or writing a single field, it's much faster (although somewhat less elegant) to use the readField(String) and writeField(String) methods to access the data, while disabling the normal read and write. Depending on the size of your structure, you may see two orders of magnitude or more improvement in the native function call time.

Here's an example of performing the same operation two different ways:


class Big extends Structure {
public int toNative;
public int fromNative;
// plus lots more fields
// the more, the bigger the difference in performance

}

class FastBig extends Big {
public void read() { }
public void write() { }
}

Big big = new Big();
big.toNative = 42;
lib.callMyNativeFunction(big);
System.out.println("Got " + big.fromNative);

Big fast = new FastBig();
fast.toNative = 42;
fast.writeField("toNative");
lib.callMyNativeFunction(fast);
System.out.println("Got " + fast.readField("fromNative"));


If you wrap a loop and time these, you'll see what kind of difference it makes. On a test structure with 25 "int" fields, the fast version reduces time by a factor of 10.

Trivia: some other "struct" implementations (e.g. Javolution) use objects for all fields and require an explicit "write" or "set" on each. This reduces data transfer and/or reflection overhead, at the expense of simplicity of assignment and initialization.

JNA:
s.field = 1;
call(s.field);

Javolution:
s.field.set(1);
call(s.field.get());



JNA win64 port

Thu, 04 Sep 2008 15:12:00 +0000

JNA now supports 64-bit windows. The the build is a bit nonstandard, but it's automatic and reproducible. I was hoping to use mingw-64, but that project is not yet sufficient for JNA's purposes. Fortunately, the MS has a free 64-bit cross compiler which does work.

Thanks to the fine folks at Aquafold (actually mostly Niels G. the CTO) for making it possible.

Thanks also to T. Heller of python's ctypes for the initial glue bits.



Decorator Update

Mon, 11 Aug 2008 00:26:00 +0000

Thanks to some input from a few users, the AbstractComponentDecorator has been updated to fix a few visual and behavior artifacts.

Get the latest from Sourceforge SVN.

The decorator component allows you to apply arbitrary decorations to a component without affecting its layout or (necessarily) response to events.

This blog has many different examples of usage beyond simple decorations, including drag images and per-component input blocking.



Embedding DLL File Version Information with mingw32/cygwin

Sat, 19 Jan 2008 22:57:00 +0000

If you look at the properties window for a DLL file in Windows, you'll see a few bits about the file version and copyright info. I couldn't find any information on the web about how to embed that information into a DLL. Not terribly surprising, since it's probably something MSVC inserts automatically, so why would any one need to know how it's done?

Well, I'm building a DLL with cygwin/mingw32, so I do need to know how it's done. Fortunately, Mumit Khan, author of mingw32, wrote a utility called "windres", which compiles w32 resources for use in an executable or DLL. It'll compile directly to object format, which you can simply add to your final link.

For example:

% windres -i version.rc -o version.o
So the only thing I needed to figure out was the version resource format (I really didn't want to go grok the resource spec and write it from scratch). Luckily, Java's main DLL (java.dll, what else) has version information in it, and windres can also conveniently dump an exe or dll back into text format.

The java.dll resource info looks like this:

% windres -i java.dll -O rc

// Type: version
// Name: 1
LANGUAGE 0, 0
1 VERSIONINFO
FILEVERSION 6, 0, 30, 5
PRODUCTVERSION 6, 0, 30, 5
FILEFLAGSMASK 0x3f
FILEOS 0x4
FILETYPE 0x2
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "Sun Microsystems, Inc."
VALUE "FileDescription", "Java(TM) Platform SE binary"
VALUE "FileVersion", "6.0.30.5"
VALUE "Full Version", "1.6.0_03-b05"
VALUE "InternalName", "java"
VALUE "LegalCopyright", "Copyright \251 2004"
VALUE "OriginalFilename", "java.dll"
VALUE "ProductName", "Java(TM) Platform SE 6 U3"
VALUE "ProductVersion", "6.0.30.5"
END
END

With just a few tweaks to do a regexp replace on the new template and include the new obj in my build, my released dll now has visible version information (and in this case I'm perfectly happy having absolutely no clue what any of the resource file text actually means :).

(image)



Run your Java program as an NT service

Wed, 12 Sep 2007 15:52:00 +0000

Thomas Boerkel has contributed some mappings and code to the JNA project to facilitate access to Windows' user accounts, registry, and NT services. Included is an abstract class which is capable of installing, uninstalling, and running itself as an NT service. What sets this little gem apart from most available wrappers is that you don't need a Windows executable stub; the complete Windows service API is available to your Java program, including all system events and callbacks.

You can browse the source here. A NetBeans project is included.

I was working on an abstract service class as well but Thomas beat me to completion. Great work, Thomas!

Update: Make sure your classpath and classes are accessible by the local system account, or the service won't be able to start. To see if this is the issue, you can temporarily change the service to start using your user identity; if it works, then the problem is that the local system account doesn't have access.



Is final not final, or just not the final I wanted?

Thu, 06 Sep 2007 18:33:00 +0000

While adding some VM crash protection to JNA, I ran into this situation:


public class Pointer {
public static final int SIZE = Native.POINTER_SIZE;
}

public class Native {
public static final int POINTER_SIZE;
static {
initIDs();
POINTER_SIZE = pointerSize();
}
private static native int pointerSize();
}


I had just moved the native initialization code from Pointer to Native. All the native methods were private, so the only changes were to update those two classes and rename the native methods. But when I reran the test suite, I started getting a host of errors.


There errors were all caused by Pointer.SIZE having a zero value. I figured that since Pointer.SIZE was final, the value it was assigned from must also have been zero. A quick inspection on Native.POINTER_SIZE, however, showed that it was propertly initialized and non-zero. How, then, could Pointer.SIZE be zero if Native.POINTER_SIZE was not?


Anyone who has done any JNI is probably aware that Java access modifiers don't mean anything to native code. My first thought was that perhaps "final" modifiers don't mean anything either. Only problem is that I was never touching that Pointer.SIZE field in native code. Never even accessed it.


Scanning though the native initialization code, I noticed that, among a host of standard JRE classes, a reference to the Pointer class was being created. This turns out to be the cause of my problem: during Native class initialization, the Pointer class was loaded from JNI. When the pointer final field was initialized, it got the value from a not-yet-initialized Native class.


Turns out, this can be duplicated with pure Java code:


public class LoadTest {
public static final int VALUE;
static {
System.out.println("value=" + Secondary.VALUE);
VALUE = 1;
System.out.println("value=" + Secondary.VALUE);
}
}

class Secondary {
public static final int VALUE = LoadTest.VALUE;
}


When loaded, the class prints "value=0" twice, so final is final, just not the value I intended. Here, the problem is more apparent because the class dependency is clearly visible, which wasn't the case with the JNI initialization.


Maybe I'll call this antipattern something curiously obscure, like "Law of the Polygamist's Second Wife".




Demo sources

Mon, 23 Jul 2007 19:14:00 +0000

All source for demos in previous blog entries is now available via SVN on SourceForge. The project page is here.

All sources are provided under the LGPL.



Improved Window Shaping

Wed, 27 Jun 2007 18:05:00 +0000

Thanks to contributions from Olivier Chafik and Chris Deckers, the overhead for setting a window shape mask has been reduced by about two orders of magnitude. In this case, the balloon tip windows no longer have such a noticeable delay before showing.

Linux users should also have fewer issues with this version; some of the library setup previously required is now taken care of automatically by the JNA library.


(image)



Easier Alpha Masks

Sat, 12 May 2007 04:10:00 +0000

The per-pixel alpha masking in this post has been codified into a simple API.

WindowUtils.setWindowTransparent(Window w, boolean transparent);

This effectively gives the window a transparent background. The alpha levels of the window's contents are preserved.

The demo is similar to the previous one but adds a few standard components to the mix.

(image)

UPDATE If you have a linux system and this for some reason doesn't work, please post a comment to that effect, or post a message to users@jna.dev.java.net so we can ensure this works reliably across all linux systems (64-bit is in the works).



Improved Drag Images

Wed, 25 Apr 2007 21:19:00 +0000

A while back I posted some drag/drop handling code that included drag images that were closer to real drag image support, but were restricted to only showing up on windows belonging to the same VM.

Now, thanks to the window masking and transparency utilities provided by JNA, the drag images can escape the bounds of java windows.

(image)

(image)

This wasn't quite as easy as expected, even with the shaped, transparent windows already taken care of.

First, I had intended to use Swing's built-in drag support, given that Shannon Hickey has put so much work into improving it. Unfortunately, that built-in support, while making some operations very easy, makes others impossible. Namely, drag image support requires updating the image's location in response to cursor motion. While it's technically possible to listen for motion outside the drag operation using a global DragSource listener, that's a hacky workaround. So instead, I fall back to raw DnD with DragGestureListener, DragSourceListener, et al. These provide the necessary hooks to move the drag image, and I already have some abstract base classes that provide a basic, customizable implementation.

Next, I uncovered a bug in the JNA example code converting an Icon into a region mask. It turns out that a BufferedImage of type TYPE_BYTE_BINARY applies something like a 50% luminance threshold, when what I really wanted was a zero/non-zero threshold based on the alpha component of the icon's pixels. I tried writing my own binary Composite to do just that, but wound up with errors downstream of the actual composite operation. Fortunately, BufferedImage.getAlphaRaster on a standard ARGB image gives me pretty much what I want.

Finally, once I instantiated a window under the current drag operation, I could no longer drop anywhere. Which makes sense when you consider there is now a window in between the cursor and any place you'd like to drop. I almost gave up thinking this was an intractable problem given that DnD is so tightly wound up with native implementations, but I'm always game for one more variation. Remember that a window region can have holes in it, where events pass through to whatever lies beneath. Well, what if we put a hole right where the cursor is? Since it's directly under the cursor, it's not really apparent, but it allows events to pass through to the underlying drop target. We only need a single pixel, because that's all the DnD system cares about (I initially made it much bigger just so I could be sure I put it in the right place). Voila! It works.



Alpha-mask Transparency for a Window

Wed, 18 Apr 2007 15:45:00 +0000

Finally got per-pixel alpha mask working on w32. The included image isn't the greatest for showing an antialiased edge (it does have one), but if you have something with a drop shadow lying about, just drop it on the demo window and that'll be used instead.

Update This demo works on Windows, OSX and Linux (Linux requires JRE1.5+).

(image)

Update Here's another image to drop on the demo window, which better demonstrates the alpha blending, in case you don't have any handy
(image)

I've got some working X11 code, too, but I need to figure out a decent API to make it happen. OSX lets you just set the window background pixel transparent and then everything you paint in the window is automatically composited with whatever alpha mask you paint with. That could probably work with Swing as well, but you have to magically drop anything with a default background. OSX does this by checking for a magic UIResource color; anything painted with that color is fully transparent.

Update Source is available on BRANCH_V2 from JNA.

I realize I may be an utter dolt, but I find it really hard to follow Microsoft APIs. I've worked with Qt, X11/Xt, and Mac, each of which has its peculiarities of architecture, but those have a consistency (might I say design) that spans more than two or three functions.



Java Transparent Windows (X11 update)

Sat, 14 Apr 2007 02:36:00 +0000

(image)

(image)

Update: If your X11 setup supports it (XFCE, metacity + xcompmgr, compiz, etc), the JNA shaped window demo now has window transparency.

Thanks to Romain Guy for some initial testing and VMWare for making experimental linux installations easier.

Update: BTW, the linux setup I used was ubuntu (after installing xubuntu packages to get xfce; should have started with xubuntu). Note that the transparency is similar to that on OS X and w32, i.e. a single alpha level for the entire window. Next up is to apply a per-pixel alpha mask, if I can scrounge up some samples of how to do it on each platform.

I added some features to JNA to facilitate working with the X11 visual lookups (it returns an array of structures), so a few more files got changed than just the examples jar. If you want the latest and greatest, you'll need to check out from CVS and do 'ant examples-jar'.



Another thing that sucks about applets...

Thu, 05 Apr 2007 16:40:00 +0000

You can't easily make the background color match the web page. You'd think that Applet.setBackground() would just Do the Right Thing.

You don't necessarily want to hard-code a value into the applet, but even if you set a value via javascript/livescript, you've got to do extra work to make it propagate down the hierarchy.

This is also applicable to Swing; you can't set a background color on a parent component and have it propagate to descendants. The first non-opaque component you run into is going to get its background from the UIManager. I really don't want to have to figure out which UIManager colors I have to override just to set the bloody background color of my app.

Maybe the new JSR 296 will do something about this, maybe not, but it'd be nice to have something akin to the old X toolkit's resource specifiction:

*.background: red
*.JCheckBox.background: red
JApplet.*.background: red
named-applet.*.background: red

The idea is that you can isolate or aggregate just about anything in the hierarchy by name or by class, and apply a resource setting to it (I guess they're calling it "injection" these days).



Animated Per-panel Options Pane

Thu, 05 Apr 2007 15:26:00 +0000

Here's another example in the search for an unobtrusive property editor. This one looks a little like the Google Maps thumbnail navigator (at least with respect to its activator).ContentsToggle Button PositioningLayout AnimationThe API is simple:// This component's preferred size will normally be that of its contentcontainer.add(new OptionsPanel(content, options));The purpose of this component is to unobtrusively associate a nontrivial set of options with some content whose display is typically larger than the options themselves. The options display is kept close the the content it modifies, which avoids the user having to go search through menus or play dialog positioning games. Since the options are hidden by default, you also don't have them always using up screen real estate. This sort of thing is often wedged into a docking solution, which is inappropriate if the information doesn't need to be visible at all times. A docking solution also insists on allocating the whole edge of the dock, so if you don't have other junk that has to be in there, you're wasting a lot of space.The OptionsPane component wraps the content in the center of a BorderLayout and keeps the PAGE_END slot available for the options themselves. Toggle Button PositioningNotice that the toggle button isn't affected by the border layout (or any other content, for that matter). The toggle button has been placed in a layer above the rest of the content, so it's always visible and doesn't contribute to any layout complexity.JRootPane root = SwingUtilities.getRootPane(this);if (root != null) { layered = root.getLayeredPane(); if (layered != null) { int layer = JLayeredPane.DEFAULT_LAYER.intValue(); layered.add(toggle, new Integer(layer + 1)); updateButtonLocation(); }} We also want to update the button location whenever the OptionsPane moves. While we could use a ComponentListener, that would update the button's location after the OptionsPane was moved/resized, resulting in some jerkiness to the display. So instead, the button gets moved at the same time as the parent component:public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); updateButtonLocation();}Layout AnimationRather than instantly making the options visible and doing a single relayout, we use a javax.swing.Timer to gradually grow the options from the lower right corner into its final position. The bottom slot of BorderLayout will respect a component's height, but stretch or squash the component to the pane's current width. So changing the height gradually will work, but changing the width will have no effect (the component simply appears to rise from the bottom of the panel, rather than from the lower right).Rather than changing the width, we use an empty border in a JPanel wrapped around the options component. By changing the width of the left border, the options appear to grow from the left to the right.The animation increment is simple (move half the remaining distance), which is pretty good for most purposes. This is the Timer configuration in response to the expansion button click:final int INTERVAL = 50;final int FRACTION = 2;final boolean expanded = isExpanded;Timer timer = new Timer(INTERVAL, new ActionListener() { public void actionPerformed(ActionEvent e) { Insets insets = optionsBox.getInsets(); Insets delta = targetInsets(expanded); Dimension targetSize = targetSize(expanded); int dx = (delta.left - insets.left)/FRACTION; if (dx != 0) { insets.left +[...]



Speech Bubble Update (with Drop Shadow)

Mon, 02 Apr 2007 16:19:00 +0000

(image)
I added a drop shadow to the speech bubble. You don't need it on OSX (OSX provides one automatically), and I don't have compiz or similar compositing window manager installed on linux at the moment (although if anyone is willing to submit/test the corresponding code, I'm happy to include it).

Nothing fancy, just black with 50% alpha. The shadow mask is just the original mask, sheared, scaled, and offset. The drop shadow would probably look nicer with a blurred edge, but that likely requires a variable alpha setting for the window (although you might be able to fake it by varying the edge color). Applying per-pixel alpha masks prior to Windows Vista seems to be non-trivial (this example uses a single alpha value for the entire window).

The JNA function definitions are trivial:


int GetWindowLongA(Pointer hWnd, int nIndex);
int SetWindowLongA(Pointer hWnd, int nIndex, int dwNewLong);
boolean SetLayeredWindowAttributes(Pointer hwnd, int crKey,
byte bAlpha, int dwFlags);


As is the actual usage:


Pointer hWnd = getHWnd(w);
User32 user = User32.INSTANCE;
int flags = user.GetWindowLongA(hWnd, User32.GWL_EXSTYLE) | User32.WS_EX_LAYERED;
user.SetWindowLongA(hWnd, User32.GWL_EXSTYLE, flags);
user.SetLayeredWindowAttributes(hWnd, 0, (byte)(255*alpha), User32.LWA_ALPHA);


The only real trick is that DirectDraw must be disabled in order to get the transparency effect and avoid leaving behind painting artifacts.

java -Dsun.java2d.noddraw=true ...

NOTE: thanks to l2fprod for the hint and the original round, transparent clock!

Update: Demo is now available from the JNA homepage.
(image)



Give your application a speech bubble

Wed, 28 Mar 2007 22:45:00 +0000

As a result of an argument about the best way to present meta-information about complex application objects presented to the user, I had to come up with some concrete alternatives.The problem is that for a given item in the application (in this case an SVN-based revision control client that aggregates and presents large amounts of meta-information about the repository), there may exist information that just doesn't fit in the display. You want to provide the user with a route to the desired information with as few inputs as possible.Tooltips is one alternative, but aren't always appropriate. While you can set (globally) the delay before appearance and the time before dismissal, dismissing them is implicit. In my application, I need the meta information to be displayed or hidden explicitly, so that rules out tooltips (at least without substantial modification of the tooltip manager).A dedicated "inspector" window is another alternative, but kind of heavyweight. We definitely don't want a component that can be activated, since that introduces focus issues. I also didn't want to make it appear to the user that there was a generic "container" that kept resizing and moving, as if it were a tool palette that couldn't decide on its purpose. At a minimum the window has to be undecorated and pretty much behave like a tooltip.What I really wanted was something in between the two. A simple Popup with a unique appearance which could be shown or hidden at will. Apple introduced something like this as Balloon Help years ago, although I think the main problem was that they didn't get the trigger quite right. One reason a lot of expert users don't like tooltips (or balloon help) is that they show up when you don't expect it and you have to wave the mouse to make them go away (usually causing another one to be triggered).Google maps does a nice job with their balloon tips. The trigger is obvious, and the tip itself provides a close button (and now I notice a maximize button as well).So I started out with Popups via PopupFactory and wound up with another demonstration of non-rectangular clipping, brought to you by the JNA project. The API is pretty simple:Component myComponent;Component myBubble;Point where; // location relative to myComponentfinal Popup popup = BalloonManager.getBalloon(myComponent, myBubble, where.x, where.y);popup.show();// Hide the popup on mouse clicksmyBubble.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { popup.hide(); }});The balloon is a simple rounded rectangle with a triangle stuck to the bottom, with the corresponding Area used as the window mask.I originally tried using PopupFactory directly, but it doesn't provide enough control over the intermediate components (the ancestors of the content that you don't really see; there's a pesky medium-weight popup that uses java.awt.Panel, which can't be easily masked). This implementation uses a window for any popup, regardless of whether its fully contained within the parent component.Drop shadows would be nice (maybe someone wants to contribute some compositing code?).All Material Copyright (c) 2006 Timothy Wall All Rights Reserved[...]



Building w32 JNI DLLs with gcc

Tue, 13 Mar 2007 16:41:00 +0000

After a bit of trial and error, I got JNA's native shared library to build (and run, and run tests) using gcc. Unfortunately the available documentation didn't quite work for me (might be a problem with my cygwin installation, but I wasn't the only one with an issue).

gcc-mingw is a version of cygwin gcc that can compile directly to the w32 api, without any of the cygwin emulation layer.


% gcc -dumpspecs | sed s%dllcrt2%/lib/mingw/dllcrt2%g > specs.new
% gcc -mno-cygwin -D_REENTRANT -D_GNU_SOURCE \
-D__int64="long long" -D_JNI_IMPLEMENTATION \
-o
-shared -Wl,--kill-at -specs specs.new -L /lib/mingw


The -mno-cygwin flag tells the compiler to run in mingw mode, i.e. omit all the cygwin unix compatibility layer and compile directly against the w32 api.

GCC's built-in 64-bit type is long long, so we map the type used in the JNI headers, __int64, to that type. Defining _JNI_IMPLEMENTATION ensures the JNI implementation exports its native method declarations.

Defining _REENTRANT and _GNU_SOURCE cause certain additional declarations of C library functions to be included. If you've never heard of them, most likely you don't need them.

The --kill-at flag to the linker ensures all symbols are exported undecorated, i.e. _my_func instead of _my_func@NN, which is the default when a function is declared as __stdcall. You could also use --add-stdcall-alias, which includes both versions of the symbol.

The GCC specs need tweaking or gcc-mingw doesn't find its initialization code for dlls, dllcrt2.o. We also have to nudge gcc-mingw to find the mingw libraries. Normally this is taken care of automatically by gcc, but for some reason my installation of cygwin gcc wouldn't find them, and no amount of -L or explicit object linkage would fix it.

Anyhow, with that out of the way, you don't have to have Microsoft's tools to build JNA or any other JNI library on w32.

I have noted that GCC apparently handles floating point a little differently, since the JNA tests that use FP return values/arguments are failing with the GCC-build dll.



Non-rectangular Windows Update

Tue, 27 Feb 2007 22:30:00 +0000

(image)


Updated to include support for OSX and linux.

While OSX doesn't actually use any native code to do the window mask, JNA support is there if it needed to. Source (and per-platform binaries) is available at http://jna.dev.java.net.

Update
Transparent version of the demo is available here.



Non-rectangular Windows

Sat, 24 Feb 2007 03:22:00 +0000

I've been meaning to play around with shaped windows for a while, but didn't relish the thought of walking through the tedium of JNI configurations and builds. Doing it on one platform is bad enough, but on several? No thanks.

So I thought I'd write a little scriptable shared library access stub once and be done with JNI entirely. Well, turns out it's already been done. Several times.

JNative
NLink
JNA

JNative has some interesting features not found in the others, but actually using it is only slightly better than JNI. NLink is currently w32-only, and has a bit of a COM bent. JNA fit most closely with my objectives, already had implementations for w32 and solaris, and was already platform-agnostic. So I took a couple days to hack in some more features (mostly to get an understanding of the codebase), and here is what I got. The following code is what it takes to make a frame take an arbitrary shape.

User32 user32 = User32.INSTANCE;
GDI32 gdi32 = GDI32.INSTANCE;
JFrame frame = new JFrame(getName());
Pointer p = gdi32.CreateRoundRectRgn(0, -150, 300, 300, 300, 300);
int hWnd = user32.FindWindowA(null, getName());
user32.SetWindowRgn(hWnd, p, true);

Looking up the appropriate w32 calls probably took the most time. How are the w32 libraries defined? How is this for trivial:

public interface User32 extends StdCallLibarary {
User32 INSTANCE = (User32)Native.loadLibary("user32", User32.class);
int FindWindowA(String winClass, String title);
void setWindowRgn(int hWnd, Pointer p, boolean redraw);
}
public interface GDI32 extends StdCallLibrary {
GDI32 INSTANCE = (GDI32)Native.loadLibrary("gdi32", GDI32.class);
Pointer CreateRoundRectRgn(int left, int top, int right, int bottom, int w, int h);
}

Now, somebody's probably going to point me to how SWT has had this functionality for years (does it?), but this is nicely abstracted and based on a very small number of classes. I'll be updating the code at jna.dev.java.net (or maybe opening a new location if I can't get the existing project moved to subversion), but for now, check out the demo by clicking on everyone's favorite orange launch button.

(image)


Permissions required, because this runs some custom native code.

Oh, BTW, this is windows-only for the moment. I'll do X11 next and anyone's free to send me some code snippets for setting window masks on other platforms. I could also use some help porting to PPC and other platforms (a very small amount of native ASM to push arguments to the stack, not too hard).