This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 98762
Collapse All | Expand All

(-)graph/examples/src/org/netbeans/modules/visual/examples/RunDialog.java (+1 lines)
Lines 77-82 Link Here
77
        "test.keyboard.EnterKeyProcessingTest",
77
        "test.keyboard.EnterKeyProcessingTest",
78
        "test.keyboard.EnterKeyTest",
78
        "test.keyboard.EnterKeyTest",
79
        "test.keyboard.KeyboardTest",
79
        "test.keyboard.KeyboardTest",
80
        "test.label.LabelGlyphVectorTest",
80
        "test.label.LabelOrientationTest",
81
        "test.label.LabelOrientationTest",
81
        "test.layout.CardLayoutWithLabelTest",
82
        "test.layout.CardLayoutWithLabelTest",
82
        "test.layout.FlowLayoutTest",
83
        "test.layout.FlowLayoutTest",
(-)graph/examples/src/test/label/LabelGlyphVectorTest.java (+61 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package test.label;
21
22
import org.netbeans.api.visual.action.ActionFactory;
23
import org.netbeans.api.visual.widget.LabelWidget;
24
import org.netbeans.api.visual.widget.LayerWidget;
25
import org.netbeans.api.visual.widget.Scene;
26
import test.SceneSupport;
27
28
import java.awt.*;
29
30
/**
31
 * @author David Kaspar
32
 */
33
public class LabelGlyphVectorTest {
34
35
    public static void main (String[] args) {
36
        Scene scene = new Scene ();
37
        scene.getActions ().addAction (ActionFactory.createZoomAction (1.1, false));
38
        scene.getActions ().addAction (ActionFactory.createPanAction ());
39
40
        LayerWidget layer = new LayerWidget (scene);
41
        scene.addChild (layer);
42
43
        createLabel (layer, 100, 100, "We are glyph-vector labels");
44
        createLabel (layer, 100, 150, "Zoom the scene in/out using Ctrl+MouseWheel");
45
        createLabel (layer, 100, 200, "The labels should be rendered correctly all the time (not clipping)");
46
47
        SceneSupport.show (scene);
48
    }
49
50
    private static void createLabel (LayerWidget layer, int x, int y, String label) {
51
        LabelWidget widget = new LabelWidget (layer.getScene (), label);
52
        widget.setOpaque (true);
53
        widget.setBackground (Color.GREEN);
54
        widget.setUseGlyphVector (true);
55
        widget.setAlignment (LabelWidget.Alignment.CENTER);
56
        widget.setVerticalAlignment (LabelWidget.VerticalAlignment.CENTER);
57
        widget.setPreferredLocation (new Point (x, y));
58
        layer.addChild (widget);
59
    }
60
61
}
(-)graph/lib/apichanges.xml (+16 lines)
Lines 444-449 Link Here
444
            <class package="org.netbeans.api.visual.widget" name="Widget" link="yes"/>
444
            <class package="org.netbeans.api.visual.widget" name="Widget" link="yes"/>
445
            <issue number="108856"/>
445
            <issue number="108856"/>
446
        </change>
446
        </change>
447
448
        <change>
449
            <api name="general"/>
450
            <summary>Accurate LabelWidget rendering using glyph vector</summary>
451
            <version major="2" minor="7"/>
452
            <date day="1" month="8" year="2007"/>
453
            <author login="dkaspar"/>
454
            <compatibility semantic="compatible" addition="yes"/>
455
            <description>
456
                LabelWidget now has useGlyphVector property. If true then the text in a LabelWidget is converted into glyph-vector (a shape)
457
		that is rendered. This allows accurate rendering independently on zoom-factor of a scene.
458
                Note that the glyph-vector rendering is slower than regular rendering.
459
            </description>
460
            <class package="org.netbeans.api.visual.widget" name="LabelWidget" link="yes"/>
461
            <issue number="98762"/>
462
        </change>
447
    </changes>
463
    </changes>
448
464
449
    <htmlcontents>
465
    <htmlcontents>
(-)graph/lib/manifest.mf (-1 / +1 lines)
Lines 1-4 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.visual
2
OpenIDE-Module: org.netbeans.api.visual
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties
4
OpenIDE-Module-Specification-Version: 2.6
4
OpenIDE-Module-Specification-Version: 2.8
(-)graph/lib/src/org/netbeans/api/visual/widget/LabelWidget.java (-11 / +88 lines)
Lines 21-26 Link Here
21
import org.netbeans.modules.visual.util.GeomUtil;
21
import org.netbeans.modules.visual.util.GeomUtil;
22
22
23
import java.awt.*;
23
import java.awt.*;
24
import java.awt.font.FontRenderContext;
25
import java.awt.font.GlyphVector;
24
import java.awt.geom.AffineTransform;
26
import java.awt.geom.AffineTransform;
25
import java.awt.geom.Rectangle2D;
27
import java.awt.geom.Rectangle2D;
26
28
Lines 60-65 Link Here
60
    private VerticalAlignment verticalAlignment = VerticalAlignment.BASELINE;
62
    private VerticalAlignment verticalAlignment = VerticalAlignment.BASELINE;
61
    private Orientation orientation = Orientation.NORMAL;
63
    private Orientation orientation = Orientation.NORMAL;
62
    private boolean paintAsDisabled;
64
    private boolean paintAsDisabled;
65
    private boolean useGlyphVector = false;
66
67
    private GlyphVector cacheGlyphVector;
68
    private String cacheLabel;
69
    private Font cacheFont;
63
70
64
    /**
71
    /**
65
     * Creates a label widget.
72
     * Creates a label widget.
Lines 174-189 Link Here
174
    }
181
    }
175
182
176
    /**
183
    /**
184
     * Returns whether the label widget is using glyph vector for rendering text.
185
     * @return true, if the label widget is using glyph vector
186
     */
187
    public boolean isUseGlyphVector () {
188
        return useGlyphVector;
189
    }
190
191
    /**
192
     * Sets whether the label widget is using glyph vector for rendering text.
193
     * <p>
194
     * Note that using glyph vector could slow-down the rendering performance.
195
     * Note that if you are not using glyph vector then the text may be clipped when a scene has zoom factor different from 1.0.
196
     * @param useGlyphVector if true, then a glyph vector is used for rendering text
197
     */
198
    public void setUseGlyphVector (boolean useGlyphVector) {
199
        if (this.useGlyphVector == useGlyphVector)
200
            return;
201
        this.useGlyphVector = useGlyphVector;
202
        cacheGlyphVector = null;
203
        cacheLabel = null;
204
        cacheFont = null;
205
        revalidate ();
206
    }
207
208
    private void assureGlyphVector () {
209
        Font font = getFont ();
210
        FontRenderContext fontRenderContext = getGraphics ().getFontRenderContext ();
211
        if (cacheGlyphVector != null  &&  cacheFont == font  &&  cacheLabel == label)
212
            return;
213
        cacheFont = font;
214
        cacheLabel = label;
215
        cacheGlyphVector = font.createGlyphVector (new FontRenderContext (new AffineTransform (), fontRenderContext.isAntiAliased (), fontRenderContext.usesFractionalMetrics ()), cacheLabel);
216
    }
217
218
    /**
177
     * Calculates a client area for the label.
219
     * Calculates a client area for the label.
178
     * @return the client area
220
     * @return the client area
179
     */
221
     */
180
    protected Rectangle calculateClientArea () {
222
    protected Rectangle calculateClientArea () {
181
        if (label == null)
223
        if (label == null)
182
            return super.calculateClientArea ();
224
            return super.calculateClientArea ();
183
        Graphics2D gr = getGraphics ();
225
        Rectangle rectangle;
184
        FontMetrics fontMetrics = gr.getFontMetrics (getFont ());
226
        if (useGlyphVector) {
185
        Rectangle2D stringBounds = fontMetrics.getStringBounds (label, gr);
227
            assureGlyphVector ();
186
        Rectangle rectangle = GeomUtil.roundRectangle (stringBounds);
228
            rectangle = GeomUtil.roundRectangle (cacheGlyphVector.getVisualBounds ());
229
            rectangle.grow (1, 1); // WORKAROUND - even text antialiasing is included into the boundary
230
        } else {
231
            Graphics2D gr = getGraphics ();
232
            FontMetrics fontMetrics = gr.getFontMetrics (getFont ());
233
            Rectangle2D stringBounds = fontMetrics.getStringBounds (label, gr);
234
            rectangle = GeomUtil.roundRectangle (stringBounds);
235
        }
187
        switch (orientation) {
236
        switch (orientation) {
188
            case NORMAL:
237
            case NORMAL:
189
                return rectangle;
238
                return rectangle;
Lines 201-207 Link Here
201
        if (label == null)
250
        if (label == null)
202
            return;
251
            return;
203
        Graphics2D gr = getGraphics ();
252
        Graphics2D gr = getGraphics ();
204
        gr.setFont (getFont ());
253
        if (useGlyphVector)
254
            assureGlyphVector ();
255
        else
256
            gr.setFont (getFont ());
205
257
206
        FontMetrics fontMetrics = gr.getFontMetrics ();
258
        FontMetrics fontMetrics = gr.getFontMetrics ();
207
        Rectangle clientArea = getClientArea ();
259
        Rectangle clientArea = getClientArea ();
Lines 220-229 Link Here
220
                        x = clientArea.x;
272
                        x = clientArea.x;
221
                        break;
273
                        break;
222
                    case CENTER:
274
                    case CENTER:
223
                        x = clientArea.x + (clientArea.width - fontMetrics.stringWidth (label)) / 2;
275
                        if (useGlyphVector)
276
                            x = clientArea.x + (clientArea.width - getCacheGlyphVectorWidth ()) / 2;
277
                        else
278
                            x = clientArea.x + (clientArea.width - fontMetrics.stringWidth (label)) / 2;
224
                        break;
279
                        break;
225
                    case RIGHT:
280
                    case RIGHT:
226
                        x = clientArea.x + clientArea.width - fontMetrics.stringWidth (label);
281
                        if (useGlyphVector)
282
                            x = clientArea.x + clientArea.width - getCacheGlyphVectorWidth ();
283
                        else
284
                            x = clientArea.x + clientArea.width - fontMetrics.stringWidth (label);
227
                        break;
285
                        break;
228
                    default:
286
                    default:
229
                        return;
287
                        return;
Lines 271-280 Link Here
271
                        y = 0;
329
                        y = 0;
272
                        break;
330
                        break;
273
                    case TOP:
331
                    case TOP:
332
                        if (useGlyphVector)
333
                            y = clientArea.y + getCacheGlyphVectorWidth ();
334
                        else
274
                        y = clientArea.y + fontMetrics.stringWidth (label);
335
                        y = clientArea.y + fontMetrics.stringWidth (label);
275
                        break;
336
                        break;
276
                    case CENTER:
337
                    case CENTER:
277
                        y = clientArea.y + (clientArea.height + fontMetrics.stringWidth (label)) / 2;
338
                        if (useGlyphVector)
339
                            y = clientArea.y + (clientArea.height + getCacheGlyphVectorWidth ()) / 2;
340
                        else
341
                            y = clientArea.y + (clientArea.height + fontMetrics.stringWidth (label)) / 2;
278
                        break;
342
                        break;
279
                    case BOTTOM:
343
                    case BOTTOM:
280
                        y = clientArea.y + clientArea.height;
344
                        y = clientArea.y + clientArea.height;
Lines 304-318 Link Here
304
        if (paintAsDisabled  &&  background instanceof Color) {
368
        if (paintAsDisabled  &&  background instanceof Color) {
305
            Color color = ((Color) background);
369
            Color color = ((Color) background);
306
            gr.setColor (color.brighter ());
370
            gr.setColor (color.brighter ());
307
            gr.drawString (label, 1, 1);
371
            if (useGlyphVector)
372
                gr.fill (cacheGlyphVector.getOutline (1, 1));
373
            else
374
                gr.drawString (label, 1, 1);
308
            gr.setColor (color.darker ());
375
            gr.setColor (color.darker ());
309
            gr.drawString (label, 0, 0);
376
            if (useGlyphVector)
377
                gr.fill (cacheGlyphVector.getOutline ());
378
            else
379
                gr.drawString (label, 0, 0);
310
        } else {
380
        } else {
311
            gr.setColor (getForeground ());
381
            gr.setColor (getForeground ());
312
            gr.drawString (label, 0, 0);
382
            if (useGlyphVector)
383
                gr.fill (cacheGlyphVector.getOutline ());
384
            else
385
                gr.drawString (label, 0, 0);
313
        }
386
        }
314
        
387
        
315
        gr.setTransform(previousTransform);
388
        gr.setTransform(previousTransform);
389
    }
390
391
    private int getCacheGlyphVectorWidth () {
392
        return GeomUtil.roundRectangle (cacheGlyphVector.getVisualBounds ()).width;
316
    }
393
    }
317
394
318
}
395
}
(-)graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html (+3 lines)
Lines 419-424 Link Here
419
<p>
419
<p>
420
Since version 2.1 the LabelWidget allows rendering vertical labels. It can be set by calling <code>LabelWidget.setOrientation</code> method. Default value is <code>LabelWidget.Orientation.NORMAL</code> which renders labels horizontally. The other value is <code>LabelWidget.Orientation.ROTATE_90</code> which makes the label to render vertically.
420
Since version 2.1 the LabelWidget allows rendering vertical labels. It can be set by calling <code>LabelWidget.setOrientation</code> method. Default value is <code>LabelWidget.Orientation.NORMAL</code> which renders labels horizontally. The other value is <code>LabelWidget.Orientation.ROTATE_90</code> which makes the label to render vertically.
421
421
422
<p>
423
Since version 2.8 the LabelWidget allows to use glyph-vector for rendering. This allows accurate text rendering independently on a scene zoom-factor (no more clipped text while zooming onto a scene).
424
422
<h3><a name="ImageWidget">ImageWidget</a></h3>
425
<h3><a name="ImageWidget">ImageWidget</a></h3>
423
426
424
<p>
427
<p>
(-)graph/www/documentation.html (+1 lines)
Lines 148-153 Link Here
148
<li><strong>test.keyboard.EnterKeyProcessingTest</strong> - test of processing enter key
148
<li><strong>test.keyboard.EnterKeyProcessingTest</strong> - test of processing enter key
149
<li><strong>test.keyboard.EnterKeyTest</strong> - test of cooperation of Swing with an enter key processing within in-place editor
149
<li><strong>test.keyboard.EnterKeyTest</strong> - test of cooperation of Swing with an enter key processing within in-place editor
150
<li><strong>test.keyboard.KeyboardTest</strong> - test of <code>CycleObjectSceneFocusAction</code>
150
<li><strong>test.keyboard.KeyboardTest</strong> - test of <code>CycleObjectSceneFocusAction</code>
151
<li><strong>test.label.LabelGlyphVectorTest</stong> - test of <code>LabelWidget</code> rendering using glyph vector
151
<li><strong>test.label.LabelOrientationTest</stong> - test of orientation vs. alignment of text in <code>LabelWidget</code>
152
<li><strong>test.label.LabelOrientationTest</stong> - test of orientation vs. alignment of text in <code>LabelWidget</code>
152
<li><strong>test.layout.CardLayoutWithLabelTest</strong> - how to create non-jumping widget with card layout and label widget as child
153
<li><strong>test.layout.CardLayoutWithLabelTest</strong> - how to create non-jumping widget with card layout and label widget as child
153
<li><strong>test.layout.FlowLayoutTest</strong> - test of bugfix #105400 - FlowLayout does not work correctly with negative location of child widgets
154
<li><strong>test.layout.FlowLayoutTest</strong> - test of bugfix #105400 - FlowLayout does not work correctly with negative location of child widgets

Return to bug 98762