如何在GUI应用程序的javafx窗格中显示Jfreechart?

时间:2015-02-16 08:29:37

标签: java javafx jfreechart

我是JavaFX的新手,我在尝试在JavaFX StackPane上显示JFreechart时遇到了困难。这个StackPane是从在SceneBuilder上构建的FXML文件引用的。我成功设置了控制器,我在控制器中使用@FXML引用识别StackPane。我尝试使用ChartCanvas并将其添加到此stackPane,但我无法使其工作。我真的不知道我对这种特殊情况有什么其他选择。

这是我的主要内容:

public class SolarSizerAppMain extends Application {

private Stage primaryStage;
private BorderPane rootLayout;

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("PV Sizer App");

    initRootLayout();

    showSolarSizerOverview();
}

/**
 * Initializes the root Layout
 */
private void initRootLayout() {
    try {
        // load root layout from fxml file.
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(SolarSizerAppMain.class.getResource("view/RootLayout.fxml"));
        rootLayout = (BorderPane) loader.load();

        // show the scene containinf the root layout
        Scene scene = new Scene(rootLayout);
        primaryStage.setScene(scene);
        primaryStage.show();

    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * show the solar sizer overview inside the root layout
 */
private void showSolarSizerOverview() {
    try {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(SolarSizerAppMain.class.getResource("view/EnergyOverview.fxml"));
        AnchorPane sizerOverview = (AnchorPane) loader.load();

        // set the energy overview into the center of root layout.
        rootLayout.setCenter(sizerOverview);

        // give the controller access to the main app.
        EnergyOverviewController controller = loader.getController();
        controller.setSolarSizerAppMain(this);
        controller.showChartPanel();
    } catch (IOException e) {
        e.printStackTrace();
    }
}



/**
 * Returns the main stage
 * 
 * @return
 */
public Stage getPrimaryStage() {
    return primaryStage;
}

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

}

这是我的Controller类:

public class EnergyOverviewController {

@FXML
private TableView<Meter> meterTable;

@FXML
private TableColumn<Meter, String> meterNumberColumn;

@FXML
private TableColumn<Meter, String> startDateColumn;

@FXML
private TableColumn<Meter, String> endDateColumn;

@FXML
private TableColumn<Meter, Boolean> activatedColumn;

@FXML
private Button addMeterButton, deleteMeterButton;

@FXML
private StackPane chartPane;

@FXML
private SplitPane mainSplitPane;

// reference to the main
private SolarSizerAppMain solarSizerAppMain;

// reference to the database
private Database database;

private TimeSeriesCollection consumptionCollection;

private TimeSeriesCollection temperatureCollection;

private XYItemRenderer consumptionRenderer;

/**
 * Contructorof the controller
 */
public EnergyOverviewController() {
    database = new Database();
}

/**
 * Initializes the controller class. This method is automatically called
 * after fxml file has been loaded.
 */
@FXML
private void initialize() {
    // first check if there are current meters
    if (database.getMeters() != null) {
        // initialize the meter table with all the columns.
        meterNumberColumn.setCellValueFactory(cellData -> cellData.getValue().getMeterNumber());
        startDateColumn.setCellValueFactory(cellData -> Assistant.parsePropertiesString(cellData.getValue()
                .getStartDate().toString()));
        endDateColumn.setCellValueFactory(cellData -> Assistant.parsePropertiesString(cellData.getValue()
                .getEndDate().toString()));
    } else {
        //TODO: Handle if there are no meters with a dialog
    }

}


/**
 * Handles the meter import once the btn has been clicked
 */
@FXML 
private void handleMeterImport(){
    //TODO: do the meter import
    FileChooser fileChooser = new FileChooser();

    //set the extension filter
    FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
    fileChooser.setInitialDirectory(new File("C:/Users/Uzquianoj1/Google Drive/Thesis/TMY3 Database"));
    fileChooser.getExtensionFilters().add(extFilter);

    //show open file dialog
    File file = fileChooser.showOpenDialog(solarSizerAppMain.getPrimaryStage());
    showProgressDialog(file);
}

/**
 * Method to display the chart
 */
public void showChartPanel() {
    TimeSeriesCollection consumptionCollection = new TimeSeriesCollection();
    String chartTitle = "Interval Data";
    String xAxisLabel = "Date";
    String yAxisLabel = "Consumption kWh";

    consumptionRenderer = new XYAreaRenderer();
    JFreeChart timeSeriesChart = ChartComponentsFactory.createTimeSeriesChart(
            chartTitle, xAxisLabel, yAxisLabel, consumptionCollection,
            consumptionRenderer, "15 minutes");
    ChartCanvas canvas = new ChartCanvas(timeSeriesChart);
    chartPane.getChildren().add(canvas);//not working
}

@FXML
private void handleDeleteMeter(){
    //TODO: Handle the deletion of a meter. 
}

public void setSolarSizerAppMain(SolarSizerAppMain mainApp){
    solarSizerAppMain = mainApp;

}

}

此链接是我的fxml所在的位置raw text fxml,我在这里调用我希望将图表放入&#34; chartPane&#34;。

的窗格。

非常感谢任何指导或建议。

1 个答案:

答案 0 :(得分:0)

如果您使用的是Java8,则可以使用SwingNode来托管诸如ChartPanel之类的摇摆组件。 SwingNode是一个JavaFX组件,允许您设置将在JavaFX场景中显示的swing组件。

必须仍然遵守Swing和JavaFX的相应线程规则。这意味着必须始终在Swing EDT上创建和更新ChartPanel,并且必须始终在JavaFX应用程序线程上更新SwingNode。根据应用程序的设计方式,这可能会非常复杂。