首页 文章

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

提问于
浏览
0

这个问题在这里已有答案:

我是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,我在这里调用我希望将图表放入"chartPane"的窗格 .

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

1 回答

  • 0

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

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

相关问题