JavaFX-TextFlow中的下标和上标文本
我一直试图在JavaFX中获得简单的富文本:我希望使用连续文本,其中一些字符是粗体、下标或上标。这在普通文本或标签类中是不可能的。我尝试了JavaFX-TextFlow中的下标和上标文本,java,javafx,javafx-8,Java,Javafx,Javafx 8,我一直试图在JavaFX中获得简单的富文本:我希望使用连续文本,其中一些字符是粗体、下标或上标。这在普通文本或标签类中是不可能的。我尝试了WebView,但没有成功,因为尽管它会显示这样的文本,但它的大小与内容不匹配,因此占据了无法控制的大部分屏幕 现在我正在尝试使用TextFlow。我可以成功地将文本对象链接在一起,其中一些对象可以加粗。然而,下标和上标被证明更加困难。下标可以通过减小字体大小来模拟,但是上标需要将Text对象提升到其他对象之上。我找不到这样做的方法:TextFlow专门忽略T
WebView
,但没有成功,因为尽管它会显示这样的文本,但它的大小与内容不匹配,因此占据了无法控制的大部分屏幕
现在我正在尝试使用TextFlow
。我可以成功地将文本
对象链接在一起,其中一些对象可以加粗。然而,下标和上标被证明更加困难。下标可以通过减小字体大小来模拟,但是上标需要将Text
对象提升到其他对象之上。我找不到这样做的方法:TextFlow
专门忽略Text
对象的翻译属性,并且我无法覆盖所讨论的Text
上的getBaselineOffset()
,因为它是最终的
我必须把文本
s放入HBox吗?JavaFX中真的不支持这个吗?我想做的事情并不复杂;对于下标和上标并没有本机支持,这似乎令人难以置信
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class TextFlowBuilder
{
private static final String BOLD = "<b>";
private static final String UN_BOLD = "</b>";
private static final String SUPERSCRIPT = "<sup>";
private static final String UN_SUPERSCRIPT = "</sup>";
private static final String SUBSCRIPT = "<sub>";
private static final String UN_SUBSCRIPT = "</sub>";
private static final Pattern NOT_JUST_WHITESPACE = Pattern.compile("\\S");
private static final Pattern CHARACTER_CODE = Pattern.compile("&#(\\d+);");
public static TextFlow htmlToTextFlow(final String html, final int fontSize, final TextAlignment alignment)
{
final String[] split = html.split("(?<=>)|(?=<)"); //Split before and after tags, splitting it into a series of tags and tag contents.
final List<Text> texts = new LinkedList<>();
boolean b = false;
boolean sup = false;
boolean sub = false;
for (String segment : split)
{
switch (segment)
{
case BOLD:
b = true;
break;
case UN_BOLD:
b = false;
break;
case SUPERSCRIPT:
sup = true;
break;
case UN_SUPERSCRIPT:
sup = false;
break;
case SUBSCRIPT:
sub = true;
break;
case UN_SUBSCRIPT:
sub = false;
break;
default:
//Add as text if string is not a tag, and is more than just whitespace.
if (segment.length() > 0
&& NOT_JUST_WHITESPACE.matcher(segment).find()
&& !segment.startsWith("<"))
{
final Matcher m = CHARACTER_CODE.matcher(segment);
while (m.find())
{
final String specialChar = Character.toString((char)Integer.parseInt(m.group(1)));
segment = m.replaceFirst(specialChar);
}
final Text t = new Text(segment);
String style = "";
if (b)
style += "-fx-font-weight: bold; ";
if (sup)
{
style += String.format("-fx-font-size: %f.3; ", fontSize/1.75);
//Need to move text to above the rest
}
else if (sub)
{
style += String.format("-fx-font-size: %f.3; ", fontSize/1.75);
}
else
{
style += String.format("-fx-font-size: %d; ", fontSize);
}
t.setStyle(style);
texts.add(t);
}
}
}
final Text[] textsAsArray = new Text[texts.size()];
final TextFlow tf = new TextFlow(texts.toArray(textsAsArray));
tf.setTextAlignment(alignment);
return tf;
}
}
导入javafx.scene.text.text;
导入javafx.scene.text.TextAlignment;
导入javafx.scene.text.TextFlow;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.regex.Matcher;
导入java.util.regex.Pattern;
公共最终类TextFlowBuilder
{
私有静态最终字符串BOLD=“”;
私有静态最终字符串UN_BOLD=“”;
私有静态最终字符串上标=”;
私有静态最终字符串UN_SUPERSCRIPT=“”;
私有静态最终字符串下标=”;
私有静态最终字符串UN_SUBSCRIPT=“”;
私有静态最终模式不只是\u WHITESPACE=Pattern.compile(“\\S”);
私有静态最终模式字符_CODE=Pattern.compile((\\d+));
公共静态文本流HTMLTOXTFLOW(最终字符串html、最终int fontSize、最终文本对齐)
{
最后一个字符串[]split=html.split((?)|(?=使用-fx-translate-y
您可以上下控制文本
您也可以使用RichTextFX
可用于创建具有不同样式的可编辑文本区域,并支持上标和下标在文本对象上设置translateY属性(在代码中,不确定是否通过CSS)确实有效-可能自提出问题以来,它发生了一些变化
下面是一个演示:
TextFlow container = new TextFlow();
Text normal = new Text("Normal");
Text sup = new Text("sup");
Text sub = new Text("sub");
sup.setTranslateY(normal.getFont().getSize() * -0.3);
sub.setTranslateY(normal.getFont().getSize() * 0.3);
container.getChildren().addAll(normal, sup, sub);
下面是它的样子:
我在Mac上使用JavaFX 11,以防这会影响到它是否真正起作用。如问题中所述,“TextFlow特别忽略文本对象的翻译属性“。因此,这是行不通的。您可以通过将翻译的标签对象放入TextFlow中来绕过它,但您仍然需要根据字体大小修改翻译,这确实不是一个好的解决方案。我想问是否有更好的方法。