<Swing Dev> [9] Review request for 8132119 Provide public API for text related methods in SwingUtilities2
Sergey Bylokhov
Sergey.Bylokhov at oracle.com
Mon Mar 21 20:38:59 UTC 2016
On 21.03.16 17:41, Alexander Scherbatiy wrote:
>
> On 18/03/16 19:49, Alexander Scherbatiy wrote:
>>
>> Could you review the updated fix:
>> http://cr.openjdk.java.net/~alexsch/8132119/webrev.08/
>>
>> - Public TextUIDrawing interface is added to the javax.swing.plaf
>> package
>> - TextUIDrawing methods description does not mention component
>> properties to be more general
>> - TextUIDrawing methods are made default
>> - L&F sets an instance of the TextUIDrawing to look and feel
>> defaults using "uiDrawing.text" property
>> - ComponentUI class is not changed
>> - Each ComponentUI reads TextUIDrawing from UI defaults
>> - There is an interesting issue described in
>> http://mail.openjdk.java.net/pipermail/swing-dev/2016-March/005509.html
>> which is related to the fact that MetalLabelUI returns a static
>> field from createUI() method.
>> TitleBorder creates a JLabel but does not put it to any component
>> hierarchy. In this case SwingUtilities.updateComponentTreeUI() method
>> calls MetalLabelUI.uninstallDefaults() on the static metalLabelUI
>> field and sets a new LabelUI for ordinary labels. The TitleBorder
>> label UI is not changed in this case and it still uses the
>> metalLabelUI field which is not initialized.
>> It seems that other applications can also use components just for
>> drawing and have the same issue.
>> For this case the textUIDrawing field is not cleared in the
>> uninstallDefaults but just set to a static default value which should
>> not lead to memory leaks.
>
> I used JMH for an average time measuring of a test method which calls
> text UI drawing class from a SynthLookAndFeel method:
> ------------
> @Benchmark
> @BenchmarkMode(Mode.SampleTime)
> @OutputTimeUnit(TimeUnit.MICROSECONDS)
> public void testDrawMethod() throws Exception {
> int N = 10000;
> JComponent component = new JLabel(TEXT);
> SynthGraphicsUtils synthGrapicsUtils = new SynthGraphicsUtils();
> ...
> for (int i = 0; i < N; i++) {
> synthGrapicsUtils.computeStringWidth(synthContext, font,
> fontMetrics, TEXT);
> synthGrapicsUtils.paintText(synthContext, g, TEXT, 10, 10, 0);
> }
> }
> ------------
>
> Here is the full code of the tested method:
> http://cr.openjdk.java.net/~alexsch/8132119/jmh/test.00/TextUIDrawingBenchmark.java
>
>
> I used 3 samples with different JDK:
> Sample 1: JDK without fixes
> Sample 2: JDK where instance of TextUIDrawing class is placed in base
> ComponentUI class.
> Sample 3: JDK where instance of TextUIDrawing is loaded for each
> necessary UI class from UIManager "uiDrawing.text" property.
can you please provide the second patch as well?
>
> In the Sample 2 SynthGraphicsUtils retrieves a TextUIDrawing instance
> from the provided JComponent.getUI() class.
> In the Sample 3 SynthGraphicsUtils gets a TextUIDrawing instance from
> UIManager property.
>
> The calculated average time in microseconds is:
> Sample 1: 20976.041 ± 60.181
> Sample 2: 21556.180 ± 89.476
> Sample 3: 23607.186 ± 62.319
>
> If just roughly use a formula like:
> method_time = initialization_time + loop_count *
> (time_for_same_operation + time_for different_operations)
> it is possible to get a time estimation for different operation like:
> (method_time2 - method_time1) / loop_count
>
> Such time difference calculation gives:
> 0.08 microseconds for Sample 2
> 0.26 microseconds for Sample 3
>
> Thanks,
> Alexandr.
>
>>
>> Thanks,
>> Alexandr.
>>
>> On 29/01/16 19:51, Alexander Scherbatiy wrote:
>>> On 25/01/16 13:44, Andrej Golovnin wrote:
>>>> Hi Alexandr,
>>>>
>>>>> Could you review the updated fix:
>>>>> http://cr.openjdk.java.net/~alexsch/8132119/webrev.07/
>>>> ....
>>>>> - public TextUIDrawing interface is added to the javax.swing.plaf
>>>>> package
>>>>> - public "TextUIDrawing getTextUIDrawing()" method is added to the
>>>>> ComponentUI class
>>>>> - L&F sets an instance of the TextUIDrawing to look and feel
>>>>> defaults using
>>>>> "uiDrawing.text" property
>>>>> - Look and Feel delegates use the instance of the TextUIDrawing for
>>>>> text
>>>>> drawing and measuring
>>>> Some thoughts on the current design/implementation:
>>>>
>>>> By adding a field to the ComponentUI class the current
>>>> implementation increases
>>>> memory consumption for all Swing applications. And you get the
>>>> feeling that
>>>> there are different implementations of TextUIDrawing per ComponentUI
>>>> instances.
>>>> Personally I can't imagine to have different implementations of
>>>> TextUIDrawing for
>>>> a given LookAndFeel. If I would design/implement it, then I would
>>>> implement it as
>>>> a property of the LookAndFeel class (similar to LayoutStyle) and not
>>>> the ComponentUI.
>>>> Developers can use then the following code to obtain the instance of
>>>> TextUIDrawing:
>>>>
>>>> UIManager.getLookAndFeel().getUIDrawing() // or
>>>> UIManager.getLookAndFeelUIDrawing() // use this static method as a
>>>> short cut for the line above.
>>> LayoutStyle keeps its instance per App context. The same is for the
>>> LookAndFeel
>>> when it is got through UIManager.getLookAndFeel() call.
>>> It means that accessing an instance of a TextUIDrawing will leads
>>> to a time consumption.
>>>
>>> There are 3 main ways of the SwingUtilities2.drawString(...) usage:
>>> 1. ComponentUI classes
>>> 2. Components created in UI (like BasicInternalFrameTitlePane)
>>> 3. Public utilities methods (like WindowsGraphicsUtils.paintText())
>>>
>>> For the cases 1 and 2 it is possible to load and store the
>>> UIDrawing instance during installUI()/updateUI() calls to decrease a
>>> time access to it.
>>>
>>> For the case 3 it is necessary to get LookAndFeel instance each
>>> time (which is taken from an App context)
>>> or use the passed JComponent object. It requires to have a public
>>> method and the associated variable for each instance of
>>> JComponent/ComponentUI/... class.
>>>> You can use this methods then in JDK too.
>>>>
>>>> And maybe rename the TextUIDrawing class to just UIDrawing and add
>>>> more useful methods,
>>>> e.g. a method to create a composite font, a method to convert DLUs
>>>> to pixels.
>>> UIDrawing name may look like it should be used for any UI drawing,
>>> not only for text ones. I am afraid that it can be misleading.
>>>
>>> Thanks,
>>> Alexandr.
>>>
>>>>
>>>> Best regards,
>>>> Andrej Golovnin
>>>
>>
>
--
Best regards, Sergey.
More information about the swing-dev
mailing list