禁用JavaFX图表背景图像的缓存

禁用JavaFX图表背景图像的缓存,java,javafx,javafx-8,Java,Javafx,Javafx 8,我有一个简单的折线图,按下一个按钮就会在一个新窗口中打开。此折线图使用存储在硬盘上的图像作为背景。 如果在计算折线图时关闭窗口,更改(或删除)图像文件并重新打开窗口,则会再次加载旧图像。 我在场景生成器和代码中禁用了折线图的缓存,但没有任何帮助 谁能给我一个提示我错过了什么 下面是我用于测试的线形图控制器的一个简单代码段: @FXML private LineChart<?, ?> lineChart; /** * Initializes the controller class

我有一个简单的折线图,按下一个按钮就会在一个新窗口中打开。此折线图使用存储在硬盘上的图像作为背景。 如果在计算折线图时关闭窗口,更改(或删除)图像文件并重新打开窗口,则会再次加载旧图像。 我在场景生成器和代码中禁用了折线图的缓存,但没有任何帮助

谁能给我一个提示我错过了什么

下面是我用于测试的线形图控制器的一个简单代码段:

@FXML
private LineChart<?, ?> lineChart;

/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    lineChart.setCache(false);
    Node chartNode = lineChart.lookup(".chart-plot-background");
    chartNode.setCache(false);   
    chartNode.setStyle("-fx-background-image: url('file:///C://Temp//histData.png'); -fx-background-position: center center;");
}  

我建议您查看背景图像文件的更改,如果文件更改,请将背景图像设置为null,然后再次将背景图像设置回文件以强制重新加载。请参阅:


出于性能原因,setCache函数禁止JavaFX系统将节点缓存为内存中的映像;i、 当setCache打开时,它会提示JavaFX渲染节点一次,然后将其存储在缓存图像中。我不确定JavaFX是否有单独的缓存用于通过样式加载的图像。如果确实如此,并且这导致我之前的建议不起作用,您可以将图表放在堆栈窗格中,图表位于顶部,背景视图位于图表后面的ImageView,然后在文件查看器检测到图像文件已更改时加载新图像(从而绕过JavaFX CSS系统可能具有或不具有的任何缓存机制)。

我建议您使用不同的名称保存文件,并使用不同的名称调用setStyle。

我已经尝试使用
chartNode.setStyle(“”;
删除背景图像,并使用
chartNode.setStyle(“-fx背景图像:url”)重新设置它('file:///C://Temp//histData2.png“);
但看起来css中设置的url是用sourceimage映射和缓存的。我使用StackPane和ImageView,这是可行的,但它更像是一种解决方法。相应的fxml文件会不会有某种损坏?只是初学者的猜测:)我没有将样式表连接到我的图表,只是以编程方式连接一个样式,因此即使我的fxml出现问题,也应该没有问题。但是我检查了我的文件,一切似乎都正常。创建一个新文件并使用不同的文件名调用setStyle也只是一种解决方法。目前,我使用StackPane和ImageView。This在保持相同文件名的情况下工作。但我不认为css加载的外部文件无法更改和刷新。css很简单—当您更改css属性时—它会转换为目标对象的JavaFX属性。只有在设置不同的值时,属性才会刷新。在我的例子中,有一个按钮和fx图形样式。我从设置css属性改为设置setGraphic。但你不能在节点上调用setGraphic。即使在更改样式、删除或更改初始图像并将样式设置回原始(现在缺少)背景图像后,它也会被加载。我用新的测试用例更新了我的问题,以使我的问题更清楚
<?import javafx.scene.image.*?>
<?import javafx.scene.chart.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" cacheShape="false" prefHeight="500.0" prefWidth="812.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="chartbackgroundtest.ChartController">
   <children>
      <LineChart fx:id="lineChart" cacheShape="false" prefHeight="353.0" prefWidth="611.0" styleClass="mychart">
        <xAxis>
          <CategoryAxis side="BOTTOM" />
        </xAxis>
        <yAxis>
          <NumberAxis side="LEFT" />
        </yAxis>
      </LineChart>
   </children>
</AnchorPane>
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.chart.LineChart;

public class ChartController implements Initializable {
    @FXML
    private LineChart<?, ?> lineChart;

     Node chartNode;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        chartNode = lineChart.lookup(".chart-plot-background");
        lineChart.getStylesheets().clear();

        chartNode.setStyle(null);
        chartNode.setStyle("-fx-background-image: url('file:///C://Temp//histData.png'); -fx-background-position: center;");
        new File("C:\\Temp\\histData.png").renameTo(new File("C:\\Temp\\histData3.png"));
        new File("C:\\Temp\\histData2.png").renameTo(new File("C:\\Temp\\histData.png"));
        new File("C:\\Temp\\histData3.png").renameTo(new File("C:\\Temp\\histData2.png"));

        chartNode.applyCss();
        lineChart.requestLayout();
    }  

}
    @FXML
    private void handleButtonAction(ActionEvent event) {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Chart.fxml"));    
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        Stage dialog = new Stage();
        dialog.initStyle(StageStyle.UTILITY);
        dialog.initModality(Modality.APPLICATION_MODAL);
        try {
            Scene scene = new Scene(loader.load());
            dialog.setScene(scene);
            dialog.show();
        } catch (IOException ex) {
            Logger.getLogger(MainViewController.class.getName()).log(Level.SEVERE, null, ex);
        }    
    }