synchronized static Paint getVerticalGradient(String name,
            int height, int y,
            float[] positions,
            Color[] colors) {
        if (verticalGradients == null) {
            verticalGradients = new Hashtable<String, TexturePaint>();
        }

        String key = name + " " + height + " " + y;
        TexturePaint paint = verticalGradients.get(key);
        if (paint == null) {
            height = Math.max(height, 1); // before a component is laid out, it may be 0x0
            BufferedImage bi = new BufferedImage(1, height, BufferedImage.TYPE_INT_ARGB);
            int[] array = new int[height];
            for (int a = 0; a < array.length; a++) {
                float f = a;
                f = f / ((array.length - 1));
                boolean hit = false;
                findMatch:
                    for (int b = 1; b < positions.length; b++) {
                        if ((f >= positions[b - 1]) && (f < positions[b])) {
                            float p = (f - positions[b - 1]) / (positions[b] - positions[b - 1]);
                            array[a] = tween(colors[b - 1], colors[b], p).getRGB();
                            hit = true;
                            break findMatch;
                        }
                    }
                if (!hit) {
                    array[a] = colors[colors.length - 1].getRGB();
                }
            }
            bi.getRaster().setDataElements(0, 0, 1, height, array);
            paint = new TexturePaint(bi, new Rectangle(0, y, 1, height));
            verticalGradients.put(key, paint);
        }
        return paint;
    }