Q:

How to implement a lazy property in Kotlin that requires another property?

I need a rectangle that needs to be initialized on call.
Here is my code;
class EpheButton private constructor(
    private val text: String,
    private val x: Float,
    private val y: Float,
    private val projectionMatrix: Matrix4) : Disposable {
private val spriteBatch: SpriteBatch = SpriteBatch()
private val bitmapFont: BitmapFont = BitmapFont()
private val shapeRenderer: ShapeRenderer = ShapeRenderer()

private val textWidth: Float
private val textHeight: Float
private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) }

init {
    bitmapFont.data.setScale(2f)
    bitmapFont.region.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
    bitmapFont.color = Color.BLUE
    val layout = GlyphLayout()
    layout.setText(bitmapFont, text)
    textWidth = layout.width
    textHeight = layout.height
}

I get errors for the line private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) } which says that;

Variable 'textWidth' must be initialized
  Variable 'textHeight' must be initialized

But I am already initializing them on the init{} code block.
What am I doing wrong?

A:

In kotlin , you have to initialize a variable before using it, You are using lazy initializer for Rectangle but compiler doesn't know the the status of textWidth and textHeight
So class looks like this 
class EpheButton private constructor(
    private val text: String,
    private val x: Float,
    private val y: Float,
    private val projectionMatrix: Matrix4) : Disposable {
private val spriteBatch: SpriteBatch = SpriteBatch()
private val bitmapFont: BitmapFont = BitmapFont()
private val shapeRenderer: ShapeRenderer = ShapeRenderer()

private val textWidth: Float
private val textHeight: Float
init {
    bitmapFont.data.setScale(2f)
    bitmapFont.region.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
    bitmapFont.color = Color.BLUE
    val layout = GlyphLayout()
    layout.setText(bitmapFont, text)
    textWidth = layout.width
    textHeight = layout.height
}
private val rectangle :Rectangle by lazy { Rectangle(x, y, textWidth, textHeight) }

Updated :-
Why order of initialization matter's here ?
We can call this weired behavior to Null-Safty of Kotlin. When we change the order of init block and variable declaration , we are breaking this rule. 

From Kotlin official documentaion :-
Kotlin's type system is aimed to eliminate NullPointerException's from
  our code. The only possible causes of NPE's may be

An explicit call to throw NullPointerException();
Usage of the !! operator that is described below;
External Java code has caused it;
There's some data inconsistency with regard to initialization (an uninitialized this available in a constructor is used somewhere).

Other than this four conditions , it always ensure that a variable is initialized at compile time . so same with our case it just ensuring that the used variable must be initialized before it used. 

