java - 动态更新观察者中的饼图?
问题描述
我正在使用饼图在JFrame
使用 JFreeChart 包中显示一些统计信息。我正在使用PieDataset
要传递给该createChart
方法。此外,数据集设置为动态更新,因为我在我的应用程序中使用了观察者模式,我对其进行了彻底的调试。我的问题是,尽管能够动态更新数据集,但框架上的饼图并未按原样更新,可能无法获取新的(更新的)值并显示结果。我想知道是否有其他方法可以动态更新饼图。
public void update(Observable observable, Object o) {
if (o instanceof Game || o instanceof GameController) {
String label = "<html><head><h1>World Domination View</h1></head><body> ";
territoriesList = Game.getInstance().getGameMap().getTerritories();
String[] name = new String[Game.getInstance().getNumPlayers()] ;
Float[] value = new Float[Game.getInstance().getNumPlayers()];
for (int i = 0; i < Game.getInstance().getNumPlayers(); i++) {
int tempTerritoryCount = 0;
float percentage = 0;
for (Territory territory : territoriesList) {
if (territory.getOwner() == Game.getInstance().getPlayerById(i)) {
tempTerritoryCount += 1;
}
}
percentage = (float) 100.0 * tempTerritoryCount / Game.getInstance().getGameMap().getTerritories().size();
label = label + Game.getInstance().getPlayerById(i).getName() + " owns " + percentage
+ " % territories and owns " + PhaseView.getInstance().curPArmies + "<br/>";
worldDominationViewLabel.setText(label);
//dt = createDataset(Game.getInstance().getPlayerById(i).getName(),percentage);
//createDataset(Game.getInstance().getPlayerById(i).getName(),percentage);
//for(int j=0; j<Game.getInstance().getNumPlayers();j++){
name[i] = Game.getInstance().getPlayerById(i).getName();
//}
if(name[i] != null)
{
value[i] = percentage;
}
}
dt = createDataset(name,value);
chartPanel = new ChartPanel(createChart(dt));
chartPanel.setBounds(1024,0,310,300);//390
chartPanel.setVisible(true);
frameFromPhase.add(chartPanel);
worldDominationViewLabel.setText(label + "</body></html>");}}
//the dataset definition
public static PieDataset createDataset(String[] plname,Float[] value){
DefaultPieDataset dataset = new DefaultPieDataset();
for(int i =0; i< plname.length;i++){
dataset.setValue(plname[i],value[i]);
}
return dataset;
}
//chart definition
public static JFreeChart createChart(PieDataset dataset ) {
JFreeChart chart = ChartFactory.createPieChart(
"Player Map Domination: Territorywise", // chart title
dataset, // data
true, // include legend
true,
false);
return chart;
}
解决方案
正如这里所建议的,不要在每次更改时创建新的数据集和图表;相反,“更新图表的数据模型,PieDataset
然后监听视图将随之而来。” 接口的实现Observer
可以在其方法中更新图表的模型update()
,就像罐子的动作处理程序一样JButton
。从这个完整的例子开始,我添加了一个空饼图View
并修改update()
为通过调用setValue()
图表的数据集来跟踪猜测。
class View extends JPanel {
private static final String s = "Click a button.";
private static final int SIZE = 256;
private Model model;
private ColorIcon icon = new ColorIcon(SIZE, Color.gray);
private JLabel label = new JLabel(s, icon, JLabel.CENTER);
DefaultPieDataset dataset = new DefaultPieDataset();
public View(Model model) {
super(new BorderLayout());
this.model = model;
label.setVerticalTextPosition(JLabel.BOTTOM);
label.setHorizontalTextPosition(JLabel.CENTER);
this.add(label, BorderLayout.CENTER);
this.add(genButtonPanel(), BorderLayout.SOUTH);
PiePlot plot = new PiePlot(dataset);
plot.setSimpleLabels(true);
JFreeChart chart = new JFreeChart(null, null, plot, false);
this.add(new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
}, BorderLayout.WEST);
model.addObserver(new ModelObserver());
}
…
private class ModelObserver implements Observer {
private int pass, fail;
@Override
public void update(Observable o, Object arg) {
if (arg == null) {
label.setText(s);
icon.color = Color.gray;
} else {
if ((Boolean) arg) {
label.setText("Win!");
dataset.setValue("Pass", ++pass);
} else {
label.setText("Keep trying.");
dataset.setValue("Fail", ++fail);
}
}
}
}
…
}
推荐阅读
- spring-websocket - 在 Spring WebSocket 中使用 convertAndSendToUser 方法的标头问题
- kubernetes - DigitalOcean 上的 Kubernetes 集群证书颁发机构
- sql - 在两个日期之间插入值
- kotlin - 改造 kotlin 预期 begin_object 但是 begin_array
- lotus-notes - 用 query_string 分割多个参数的最简单方法是什么?
- flutter - 如何在 Flutter 中等待 setState?
- validation - 量角器:验证强制性输入或处理承诺
- gcloud - 如何验证我在 Google Cloud 中使用的项目 ID 是否正确
- sql-server - 我们如何创建一个将列限制为 x 个相同值的表约束?
- python - 将数据框特定列中的 Nan 值替换为另一个数据框特定列中的值