问题
So i am trying to create an application that has values on a chart, which shows normally. However i am also trying to add a mouse event that is called when i click on a particular bar of the bar graph. More specifically it updates a status bar with some more detail pulled from the database.
Group root = new Group();
String[] years = {"Opened", "Closed", "Still Opened"};
CategoryAxis xAxis = new CategoryAxis();
xAxis.setCategories(FXCollections.observableArrayList(years));
NumberAxis yAxis = new NumberAxis("Jobs", 0.0d, 1, .2);
BarChart.Series<String, ObservableList> s1 = new BarChart.Series("51 ", FXCollections.observableArrayList(
new BarChart.Data(years[0], Math.random()),
new BarChart.Data(years[1], Math.random()),
new BarChart.Data(years[2], Math.random())));;
BarChart.Series<String, ObservableList> s2 = new BarChart.Series("52 ", FXCollections.observableArrayList(
new BarChart.Data(years[0], Math.random()),
new BarChart.Data(years[1], Math.random()),
new BarChart.Data(years[2], Math.random())));
BarChart.Series<String, ObservableList> s3 = new BarChart.Series("53 ", FXCollections.observableArrayList(
new BarChart.Data(years[0], Math.random()),
new BarChart.Data(years[1], Math.random()),
new BarChart.Data(years[2], Math.random())));
BarChart.Series<String, ObservableList> s4 = new BarChart.Series("54 ", FXCollections.observableArrayList(
new BarChart.Data(years[0], Math.random()),
new BarChart.Data(years[1], Math.random()),
new BarChart.Data(years[2], Math.random())));
ObservableList barChartData = FXCollections.observableArrayList(s1,s2,s3,s4);
this.statusMessage.setText("Setting listener");
for (XYChart.Data<String, ObservableList> dt : s1.getData())
{
statusMessage.setText("Acting on: " + dt.getXValue());
dt.getNode().setOnMouseClicked((MouseEvent event) -> {
statusMessage.setText("Clicked");
});
}
BarChart chart = new BarChart(xAxis, yAxis, barChartData, 25.0d);
this application will compile with and without the event, but with the event when i create the chart it fails and is unable to show it. I assume its because the event is not being loaded to the bar
The errors i get:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1768) at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1651) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.event.Event.fireEvent(Event.java:204) at javafx.scene.Node.fireEvent(Node.java:8175) at javafx.scene.control.Button.fire(Button.java:185) at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:204) at javafx.scene.Scene$MouseHandler.process(Scene.java:3746) at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3471) at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1695) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2486) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345) at com.sun.glass.ui.View.handleMouseEvent(View.java:526) at com.sun.glass.ui.View.notifyMouse(View.java:898)
回答1:
From the Oracle sample with some stuff cut out. Look down where I added the loop to get the nodes of the bars and added listeners.
package barchartsample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
public class BarChartSample extends Application {
final static String austria = "Austria";
final static String brazil = "Brazil";
@Override public void start(Stage stage) {
stage.setTitle("Bar Chart Sample");
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis();
final BarChart<String,Number> bc = new BarChart(xAxis,yAxis);
bc.setTitle("Country Summary");
xAxis.setLabel("Country");
yAxis.setLabel("Value");
XYChart.Series series1 = new XYChart.Series();
series1.setName("2003");
series1.getData().add(new XYChart.Data(austria, 25601.34));
series1.getData().add(new XYChart.Data(brazil, 20148.82));
Scene scene = new Scene(bc,800,600);
bc.getData().addAll(series1);
//now you can get the nodes.
for (Series<String,Number> serie: bc.getData()){
for (XYChart.Data<String, Number> item: serie.getData()){
item.getNode().setOnMousePressed((MouseEvent event) -> {
System.out.println("you clicked "+item.toString()+serie.toString());
});
}
}
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
来源:https://stackoverflow.com/questions/23186914/javafx-adding-a-mouseevent-to-a-bar-inside-of-a-barchart