Controlling base text direction in a custom component
This section applies to JViews rich client.
If the custom graphic object is a primitive (not a container) and does not have any text, then nothing is required.
Where the custom graphic object has some text or it is a container including child objects that have text, two approaches are available.
By methods of IlvBaseTextDirectionInterface
This functionality is the minimum required for objects that are not subclasses of
IlvGraphic. All
IlvGraphic objects implement this interface as well. Any container that displays text should implement
IlvBaseTextDirectionInterface.
This interface defines the following methods:
public void setBaseTextDirection(int textDir) changes the base text direction of the object.
public int getBaseTextDirection() returns the stored base text direction of the object.
public int getResolvedBaseTextDirection() returns only one of
LTR,
RTL, or
Contextual. It should resolve component direction by taking
Component Orientation of the GUI into account. It should resolve the Inherited direction by taking the resolved base text direction of a parent container (if any) into account. If there is no parent container, it should return one of
LTR,
RTL, or
Contextual as default value.
Implementation of these methods from scratch requires in depth understanding of the logic and mechanism of control over base text direction in JViews. If such knowledge is not available, a simpler approach can be used. See
By subclasses of IlvGraphic.
By subclasses of IlvGraphic
The public methods mentioned in
By methods of IlvBaseTextDirectionInterface and some additional ones used for handling base text direction are available in the class
IlvGraphic. To control base text direction in a custom graphic object, you can extend this class to use the bidi functionality already implemented in it. The easiest way to do so is by taking as base class
IlvBidiGraphic, which contains the full implementations of all methods of
IlvBaseTextDirectionInterface.
Subclasses of IlvBidiGraphic should implement:
public boolean isBaseTextDirectionSensitive() to return true when the resolved base text direction has any effect on the bounding box of the graphic object.
public boolean usesBidiMarkers() should return true if the in-place editing implementation uses bidi markers; the implementation from
IlvBidiGraphic always returns false.
public void baseTextDirectionChanged(int, int) to react whenever the resolved base text direction changes. For example, if internal drawing caches are affected by the resolved base text direction, they should be cleaned inside this method. If the current class is an
IlvGraphicBag, the implementation does not need to call
baseTextDirectionChanged(int, int) recursively on all contained subobjects, because the implementation of
IlvBidiGraphic does this automatically.
public void draw(Graphics, IlvTransformer) to draw the text by taking the resolved base text direction into account.
public IlvRect boundingBox(IlvTransformer) to take the resolved base text direction into account.
Implementations of other methods, such as
contains,
intersects,
inside, might also need to take the resolved base text direction into account.
If you cannot use IlvBidiGraphic as base class, then you can subclass IlvGraphic directly.
You must implement more methods, because IlvGraphic contains only empty or partial implementations:
Define
baseTextDirection as a bean property.
Implement
setBaseTextDirection and
getBaseTextDirection.
int _baseTextDirection;
public void setBaseTextDirection(int baseTextDirection)
{
if (baseTextDirection == _baseTextDirection)
return;
int oldBTDir = getResolvedBaseTextDirection();
_baseTextDirection = baseTextDirection;
int newBTDir = getResolvedBaseTextDirection();
if (oldBTDir != newBTDir)
baseTextDirectionChanged(oldBTDir, newBTDir);
}
public int getBaseTextDirection()
{
return _baseTextDirection;
}
If the class is an
IlvGraphicSet, you must use a different variant that notifies all contained objects if the resolved base text direction changes:
int _baseTextDirection;
public void setBaseTextDirection(int baseTextDirection)
{
if (baseTextDirection == _baseTextDirection)
return;
IlvGraphicVector v = IlvGraphicUtil.startBidiChange(this);
try {
_baseTextDirection = baseTextDirection;
} finally {
// this calls applyToObject on all contained objects
// and calls baseTextDirectionChanged on this and all
// contained objects when needed.
IlvGraphicUtil.stopBidiChange(this, v, false);
}
}
public int getBaseTextDirection()
{
return _baseTextDirection;
}
Override
setBaseTextDirectionDuringConstruction to change the data member without any notification:
protected void setBaseTextDirectionDuringConstruction(int baseTextDirection)
{
_baseTextDirection = baseTextDirection;
}
Override the other methods already mentioned for
IlvBidiGraphic. (See the methods listed under
[no title] for details.
Rendering
Whichever approach you take (IlvBaseTextDirectionInterface methods or subclasses of IlvGraphic), when text is rendered you must enforce its real base text direction.
JViews provides for the following techniques:
Using
TextLayout attributes when
TextLayout.draw is used for text display.
Using Unicode Control Characters when
Graphics2D.drawString is used for text display.
Using ICU for bidi text reordering when
Graphics2D.drawGlyphVector is used for text display.
Using the Swing API, for example,
applyComponentOrientation, when text is displayed by using a Swing input field.
Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.