Hello,

 Could you review the updated fix:
  http://cr.openjdk.java.net/~alexsch/8132119/webrev.11/

 - @throws tag is added in javadoc for methods in BasicTextUIDrawing class
 -  unchecked exceptions are removed from methods throws declaration

  Thanks,
  Alexandr.

On 08/04/16 22:34, Kevin Rushforth wrote:
Just my $0.02 (feel free to ignore).

Specifying "throws" on a method for an unchecked exception like NPE seems odd. Typically, only checked exceptions are declared. Both checked and unchecked exceptions can and should be documented with @throws.

-- Kevin


Sergey Bylokhov wrote:
On 07.04.16 17:07, Alexander Scherbatiy wrote:
   Could you review the updated fix:
     http://cr.openjdk.java.net/~alexsch/8132119/webrev.10

Looks fine to me, but I am curious how often we use "throws NPE" in public API (especially w/o "@throws NPE" in javadoc).


On 07/04/16 14:09, Sergey Bylokhov wrote:
On 06.04.16 23:23, Alexander Scherbatiy wrote:
Could you review the updated fix:
   http://cr.openjdk.java.net/~alexsch/8132119/webrev.09

There is tiny typos
TextUIDrawing.getClippedString():
    "@param c the component"
    I guess it should be:
    "@param c the component, may be null"
   Updated.
BasicTextUIDrawing:
    There is no dots at the end of the description of the class.

I am not sure but will javadoc automatically copy the @throws tag from
the parent tag? For example @throws NullPointerException to
BasicTextUIDrawing.drawString().

    I added throws NPE to the BasicTextUIDrawing class methods. It
forces copying @throws tag from the parent javadoc.

   Thanks,
   Alexandr.

But I can imagine they may also be handy when someone would typically
want to implement
only one or two out of a larger number in an interface and the default
and you for some
reason don't want to do that with an abstract class (notably you want
an other class to
be able to implement the interface).

So what do I think about the case where the interface is brand new and what you've done is more or less implement a concrete class, but it's
one that
can be mixed in to another class ? Is that an appropriate use ?

Maybe the test to pass in that case is whether the default
implementation
is going to be satisfactory for 90% of uses. If they are frequently
over-ridden
it would not be an appropriate use.
   Using this argument it seems if someone wants to implement the
TextUIDrawing it needs to override all its methods to keep them in sync. Because of this I moved the TextUIDrawing implementation to the separate
javax.swing.plaf.basic.BasicTextUIDrawing class.

I am fine, just one note. Now we have the interface, and the class
without any state, and
 - If the users need to implement the only one method, then it will be
necessary to subclass a BasicTextUIDrawing, which will limit the
possible class hierarchy.
 - If the user most of the time will need to implement all methods to
make them in sync he also can override BasicTextUIDrawing, then why we
need the interface?


Based on that criterion I think it is OK to use here.

Another thought:
When you add default implementations you should also be on the hook
for explaining what that does. It is a deeper contract than you would
otherwise have as an interface and maybe needs to be an @implNote
or you need to call out the default implementation.
ie there is what someone must code to satisfy the contract of the
interface and what is a behaviour in the default method ?
I added the addition "using text properties and anti-aliasing hints
from the provided component" description to the BasicTextUIDrawing
class. There is always a question how many details a method description
should contain. It is not clear for  me should, for example, the used
numeric shaper be listed in the description or not? Especially when
there is an enhancement that the methods implementation should take more
text attributes  into account.

Also here is a link to some comments by Brian Goetz on default
methods :

http://stackoverflow.com/questions/28681737/java-8-default-methods-as-traits-safe/28684917#28684917



  75      * No character is underlined if the index is negative or
greater
  76      * than the string length {@code (index < 0 || index >=
string.length())}
  77      * or if the char value specified at the given index
  78      * is in the low-surrogate range.


I suppose if you point at the last char and it is a hi-surrogate
nothing is underlined in that case either.

But I find the whole writing of this a bit inadequate as if you are
going to
this kind of detail you perhaps also need to say what happens in a
complex
script where what happens is two unicode characters end up as a
ligature,
and/or perhaps you aren't even pointing to a base character.
Maybe it is in fact over-specified. I see that the implementation draws
the underline itself rather than delegate to TextLayout. This might
make sense for performance reasons where it is simple text but some day
this maybe should be re-examined and so I would not over-specify it.

How about :
"The underline will be positioned at the base glyph which
represents the valid char indicated by the index.
If the char index is not valid or is not the index of a
valid unicode code point then no underline is drawn"
   Updated.

   Thanks,
   Alexandr.

-phil.



On 03/24/2016 07:22 AM, Sergey Bylokhov wrote:
On 24.03.16 16:52, Alexander Scherbatiy wrote:
On 24/03/16 10:36, Semyon Sadetsky wrote:
Hi Alexander,

Could you answer one question:
Why did you choose default interface methods to implement
TextUIDrawing and not implement them in DefaultTextUIDrawing having
declarations only in the interface?
AFAIK the common point of view is default methods should be used
rarely because they may lead to unreadable code.

   The only problem which I know about default methods is multiple
inheritance which has its own solution.

What kind of problems? The benefit is obvious: it will not be
necessary to implement all methods if only one of them should be
tweaked.


   Could you give links to discussion or provide use cases where
default
methods leads to the unreadable code and show how does it relate
to the
TextUIDrawing  implementation?

   Thanks,
   Alexandr.
--Semyon

On 3/18/2016 6:49 PM, 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.

  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














Reply via email to