我第一次在个人项目上玩JavaFX。
我希望能够更新Tab中的内容(添加PieChart),但是从FXML控制器外部,任何人都可以告诉我这是否可能?我如何获得相关标签的参考,是否有办法指定我添加的项目的位置?
更新:添加了一些示例代码。
希望这能清楚地说明我正在尝试做什么:
界面:
interface ChartStrategy {
public void DisplayChart(Info info)
}
两个实现:
public class BarChartStrategy extends ChartStrategy {
public void DisplayChart(Info info)
{
// Create bar charts on specific tabs in the UI
}
}
public class PieChartStrategy extends ChartStrategy {
public void DisplayChart(Info info)
{
// Create pie charts on specific tabs in the UI
}
}
背景信息:
public class ChartContext {
private ChartStrategy strategy;
public void setChartStrategy(ChartStrategy strategy) {
this.strategy = strategy;
}
public void drawGraphs(Info info) {
strategy.DisplayChart(info);
}
}
在我的控制器中,我正在读取一个用户选择的文件来解析生成图表的数据,例如。
@FXML
private void handleButtonAction(ActionEvent event) {
// Load the file and parse the data
...
ChartContext charts = new ChartContext();
charts.setChartStrategy(new PieChartStrategy());
}
所以我最初的想法是我可以在实现中从DisplayChart函数中绘制图表,但似乎这不是一个好主意 - 任何人都可以在这里给出一些关于让它工作的最佳方法的建议吗?
答案 0 :(得分:1)
我会稍微重构一下。
首先,让策略显示图表有点不灵活。您正在为策略赋予两个职责:首先决定如何直观地表示数据(选择图表),然后在某处实际显示它。这违反了单一责任原则。
所以我会这样做
interface ChartStrategy {
public Chart generateChart(Info info)
}
当然,类似于实现。然后,策略的责任就是提供一个图表:上下文可以决定如何处理它。
(您还可以考虑在此处返回Chart
是否过于严格:或许您只是希望它返回Parent
或Node
。然后您的“图表”可能是,例如,一个TableView
。)
在策略模式的理论描述中,至少在我的解释中,“上下文”只代表“使用策略的东西”。所以你的上下文可能是一个视图或控制器(取决于你选择的MVC变体......)。作为一个简单的例子,你可能会有像
这样的东西public class ChartTab {
private ChartStrategy chartGenerator ;
public void setChartGenerator(ChartStrategy chartGenerator) {
this.chartGenerator = chartGenerator ;
}
public Tab createChartTab(Info info) {
Tab tab = new Tab();
tab.setContent(chartGenerator.generateChart(info));
return tab ;
}
}
然后在你的控制器中
@FXML
private TabPane tabPane ;
@FXML
private void handleButtonAction(ActionEvent event) {
// Load the file and parse the data
...
ChartTab chartTab = new ChartTab();
chartTab.setChartGenerator(new PieChartStrategy());
tabPane.getTabs().add(chartTab.getTab(info));
}
也可以将控制器视为上下文(如果对于固定控制器,您只是创建一种图表,这取决于您如何拆分FXML文件及其相应的控制器):
public class MyController {
private ChartStrategy chartGenerator ;
@FXML
private TabPane tabPane ;
public MyController(ChartStrategy chartGenerator) {
this.chartGenerator = chartGenerator ;
}
@FXML
private void handleButtonAction(ActionEvent event) {
// Load the file and parse the data
...
Tab tab = new Tab();
tab.setContent(chartGenerator.generateChart(info));
tabPane.getTabs().add(tab);
}
}
请注意,此控制器没有no-arg构造函数,因此您无法在FXML文件中使用fx:controller
属性(即从FXML文件中删除该属性)。相反,你会做
FXMLLoader loader = new FXMLLoader("/path/to/DataDisplay.fxml");
MyController controller = new MyController(new PieChartStrategy());
loader.setController(controller);
Parent root = loader.load();
现在你有一个FXML和控制器,它具有生成图表并在选项卡窗格(或其他)中显示它们的功能,但是生成哪种图表的细节被分解为可插拔策略。你仍然有适当的MVC(或MVP等)封装,其中UI的细节保持私有的视图控制器(这里它真的是一个演示者,但谁在计算...)对。换句话说,策略对视图的其余部分一无所知,这是应该的。