org.fxmisc.richtext.LineNumberFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of richtextfx Show documentation
Show all versions of richtextfx Show documentation
Rich-text area for JavaFX
package org.fxmisc.richtext;
import java.util.function.IntFunction;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import org.reactfx.collection.LiveList;
import org.reactfx.value.Val;
/**
* Graphic factory that produces labels containing line numbers.
* To customize appearance, use {@code .lineno} style class in CSS stylesheets.
*/
public class LineNumberFactory implements IntFunction {
private static final Insets DEFAULT_INSETS = new Insets(0.0, 5.0, 0.0, 5.0);
private static final Paint DEFAULT_TEXT_FILL = Color.web("#666");
private static final Font DEFAULT_FONT =
Font.font("monospace", FontPosture.ITALIC, 13);
private static final Background DEFAULT_BACKGROUND =
new Background(new BackgroundFill(Color.web("#ddd"), null, null));
public static IntFunction get(GenericStyledArea, ?, ?> area) {
return get(area, digits -> "%1$" + digits + "s");
}
public static IntFunction get(
GenericStyledArea, ?, ?> area,
IntFunction format) {
return new LineNumberFactory(area, format);
}
private final Val nParagraphs;
private final IntFunction format;
private LineNumberFactory(
GenericStyledArea, ?, ?> area,
IntFunction format) {
nParagraphs = LiveList.sizeOf(area.getParagraphs());
this.format = format;
}
@Override
public Node apply(int idx) {
Val formatted = nParagraphs.map(n -> format(idx+1, n));
Label lineNo = new Label();
lineNo.setFont(DEFAULT_FONT);
lineNo.setBackground(DEFAULT_BACKGROUND);
lineNo.setTextFill(DEFAULT_TEXT_FILL);
lineNo.setPadding(DEFAULT_INSETS);
lineNo.setAlignment(Pos.TOP_RIGHT);
lineNo.getStyleClass().add("lineno");
// bind label's text to a Val that stops observing area's paragraphs
// when lineNo is removed from scene
lineNo.textProperty().bind(formatted.conditionOnShowing(lineNo));
return lineNo;
}
private String format(int x, int max) {
int digits = (int) Math.floor(Math.log10(max)) + 1;
return String.format(format.apply(digits), x);
}
}