2015-12-06 72 views
1

以下代碼動態創建原本在其中具有新行字符(可能爲圖像和其他窗格)的TextFlow和Text。如何在使用FXML和JavaFX動態創建TextFlow時保留新行字符

InputStream stream = new ByteArrayInputStream(text.toString().getBytes(StandardCharsets.UTF_8)); 
     TextFlow element = new FXMLLoader().load(stream); 

但是,帶FXML的ByteArrayInputStream方法會去掉所有新行。

嘗試使用兩種Windows & Unix末尾的字符,而不是那應該有所作爲的,但是當你嘗試不同的組合時,你會得到這一點。

通常這是recommended to use a BufferedReader以獲得新的線路,但在這裏我沒有控制。其他加載方法似乎採用URL和資源鏈接,但是這是一個受操縱的字符串。

一個例子

Java代碼:

package simpleexample; 

import java.io.ByteArrayInputStream; 
import java.io.InputStream; 
import java.nio.charset.StandardCharsets; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.scene.text.TextFlow; 
import javafx.stage.Stage; 

import com.jcabi.xml.XMLDocument; 

public class TestFxmlWithBreaks extends Application { 


    @Override 
    public void start(Stage primaryStage) { 
    Scene scene = new Scene(createEntry(), 750, 750, Color.web("#666970")); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    } 


    private VBox createEntry() { 
    VBox entryBox = new VBox(); 
    entryBox.setFillWidth(true); 

    entryBox.setSpacing(20); 
    entryBox.setMaxWidth(750); 

    try { 
     XMLDocument test = new XMLDocument(this.getClass().getResourceAsStream("inputFxml.xml")); 
     System.out.println(test.toString()); 

     InputStream stream = new ByteArrayInputStream(test.toString().getBytes(StandardCharsets.UTF_8)); 
     TextFlow element = new FXMLLoader().load(stream); 
     element.setMaxWidth(750); 

     entryBox.getChildren().add(element); 
    } catch (Exception e) { 
     //log something 
    } 

    return entryBox; 
    } 


    public static void main(String[] args) { 
    launch(args); 
    } 



} 

inputFxml.xml:

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.text.*?><TextFlow xmlns:fx="http://javafx.com/fxml" styleClass="paragraph"> 
<Text style="-fx-font-size: 20;">A list of stuff</Text> 
<Text> 
* stuff 
* more stuff 
* even more stuff, all with new lines 
</Text> 
<Text style="-fx-font-size: 15;">This should demonstrate it</Text> 
</TextFlow> 
+0

你能舉一個'text.toString()'的例子嗎?即以某種方式製作[MCVE]?很難看出你在做什麼......爲什麼不用FXML創建使用Java的'TextFlow',並生成文本內容呢? –

+0

沒問題,先生。我已經添加了一個簡單的例子。這裏的XMLDocument本質上是一個no-op,但實際上會有XSL轉換。我無法使用java創建它,因爲有很多第三方內容正在轉換。我只是不想使用getResourceAsStream或一些這樣的情況下,它的工作方式不同。 println按照我的預期打印整個文檔。 –

+0

是的。這應該只是工作。儘管如此:如果你只是以「普通」的方式加載該FXML文件('TextFlow textFlow = FXMLLoader.load(getClass()。getResource(「inputFxml.fxml」));注意它與流沒有任何關係。 ')你會得到同樣的結果。我會看看我能否在稍後找出解決方法。 –

回答

0

因此,除非更好的解決方案是可用的,我選擇了插入的哈克方法一個標記字符串,然後在fxml加載後替換它。

不是很好,但足夠我的用例。

public void markNewLinesInXmlTextNodes(Node node) { //w3c node 
    for(int i = 0 ; i < node.getChildNodes().getLength() ; i++) { 
     Node child = node.getChildNodes().item(i); 
     markNewLinesInXmlTextNodes(child); 
    } 
    if (node instanceof Element) { 
     Element el = (Element) node; 
     if (el.getTagName().toLowerCase().equals("text")) { 
     el.setTextContent(el.getTextContent().replaceAll("\n", "_LINEBREAK_")); 
     } 
    } 
    } 

    public void addNewLinesInFxTextNodes(javafx.scene.Node node) { 
    if (node instanceof javafx.scene.Parent) { 
     javafx.scene.Parent parent = (javafx.scene.Parent) node; 
     for(int i = 0 ; i < parent.getChildrenUnmodifiable().size() ; i++) { 
     javafx.scene.Node child = parent.getChildrenUnmodifiable().get(i); 
     addNewLinesInFxTextNodes(child); 
     } 
    } 
    if (node instanceof javafx.scene.text.Text) { 
     Text el = (Text) node; 
     el.setText(el.getText().replaceAll("_LINEBREAK_", "\n")); 
    } 
    } 
相關問題