<Swing Dev> [9] Review request for 8132119 Provide public API for text related methods in SwingUtilities2
Alexander Scherbatiy
alexandr.scherbatiy at oracle.com
Mon Mar 21 14:41:48 UTC 2016
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.
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
>>
>
More information about the swing-dev
mailing list