87 lines
3.0 KiB
Kotlin
87 lines
3.0 KiB
Kotlin
package com.jaytux.altgraph.swing
|
|
|
|
import com.jaytux.altgraph.layout.PseudoForestLayout
|
|
import java.awt.*
|
|
import java.awt.RenderingHints.KEY_ANTIALIASING
|
|
import java.awt.RenderingHints.VALUE_ANTIALIAS_ON
|
|
import java.awt.geom.AffineTransform
|
|
import java.awt.geom.Ellipse2D
|
|
import javax.swing.JLabel
|
|
|
|
class DefaultVertexComponent(
|
|
label: String,
|
|
private var _shape: Shape = Ellipse2D.Double(0.0, 0.0, 30.0, 30.0),
|
|
var labelOffset: Point = Point(20, 7),
|
|
) : IDrawable {
|
|
val label = JLabel(label)
|
|
private lateinit var _preferredSize: Dimension
|
|
private var _arrowTarget: Point = Point(0, 0)
|
|
private var _arrowTargetOffset: Float = 0.0f
|
|
var fillColor: Color = Color.LIGHT_GRAY
|
|
var borderStroke: Stroke = BasicStroke(1.0f)
|
|
var borderColor: Color = Color.BLACK
|
|
|
|
var shape: Shape
|
|
get() = _shape
|
|
set(value) {
|
|
_shape = value
|
|
_arrowTarget = Point(value.bounds.width / 2, value.bounds.height / 2)
|
|
_arrowTargetOffset = (value.bounds.width + value.bounds.height).toFloat() / 4.0f
|
|
updatePreferredSize()
|
|
}
|
|
|
|
init {
|
|
updatePreferredSize()
|
|
shape = _shape // to initialize arrow target and offset
|
|
}
|
|
|
|
fun updatePreferredSize() {
|
|
val bounds = shape.bounds
|
|
val textSize = label.preferredSize
|
|
|
|
val cx = bounds.width / 2; val cy = bounds.height / 2
|
|
val tx = cx + labelOffset.x; val ty = cy + labelOffset.y - textSize.height / 2
|
|
|
|
val textRect = Rectangle(tx, ty, textSize.width, textSize.height)
|
|
val total = bounds.union(textRect)
|
|
_preferredSize = Dimension(total.width, total.height)
|
|
}
|
|
|
|
override fun draw(graphics: Graphics2D) {
|
|
val g = graphics.create() as Graphics2D
|
|
g.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON)
|
|
val shapeBounds = shape.bounds
|
|
val cx = shapeBounds.width / 2; val cy = shapeBounds.height / 2
|
|
val tx = AffineTransform.getTranslateInstance((cx - shapeBounds.centerX), (cy - shapeBounds.centerY))
|
|
val transShape = tx.createTransformedShape(shape)
|
|
|
|
g.color = fillColor
|
|
g.fill(transShape)
|
|
g.color = borderColor
|
|
g.stroke = borderStroke
|
|
g.draw(transShape)
|
|
|
|
val textSize = label.preferredSize
|
|
val lx = cx + labelOffset.x; val ly = cy + labelOffset.y - textSize.height / 2
|
|
label.size = textSize
|
|
g.translate(lx, ly)
|
|
label.paint(g)
|
|
|
|
g.dispose()
|
|
}
|
|
|
|
fun vertexSize(): PseudoForestLayout.VertexSize {
|
|
val size = _preferredSize
|
|
val lSize = label.preferredSize
|
|
return PseudoForestLayout.VertexSize(size.graph(), labelOffset.graph(), lSize.graph())
|
|
}
|
|
|
|
fun asRenderData(): IVertexRenderer.RenderData =
|
|
IVertexRenderer.RenderData(this, _arrowTarget, _arrowTargetOffset)
|
|
}
|
|
|
|
fun <V> defaultRenderer(
|
|
toString: (V) -> String = { it.toString() }
|
|
) : IVertexRenderer<V> = IVertexRenderer { v: V ->
|
|
DefaultVertexComponent(toString(v)).asRenderData()
|
|
} |