Getting Java.Lang.Reflect.Invocationtargetexception While Adding a Button to Layout

JavaFX InvocationTargetException thrown when trying to create a Button

You're getting this because you're using controlsfx (which contains the Button class) which requires a module called graphics

....(in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.layout to unnamed module

If you're using Java11 you need to add the graphics module to the VM options.

If you're using Java12 you need to remove the VM options in order for it to work.

Check out this article Set Up JavaFx on IntelliJ

getting java.lang.reflect.InvocationTargetException while adding a button to layout

From the error I'm assuming you're using JavaFX 11 (or at least JavaFX 9+). Note that the ultimate problem is not the InvocationTargetException but the IllegalAccessError:

Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.scene.control.ControlHelper (in unnamed module @0x46b3f4cf) cannot access class com.sun.javafx.scene.layout.RegionHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.layout to unnamed module @0x46b3f4cf

This is telling you code in the "unnamed module" is trying to access internals of the javafx.graphics module. As this is not allowed the error is thrown. But the real problem here is that ControlHelper is in the unnamed module but it's supposed to be in the javafx.controls module, if the package name is anything to go by. This problem is caused by having javafx.graphics on the modulepath but javafx.controls on the classpath.

Make sure you have both modules (and javafx.base) on the --module-path. As your code is not modular (no module-info file) you will also have to tell the module system to resolve it by using:

--add-modules javafx.controls

You don't have to include javafx.graphics in the --add-modules command because javafx.controls requires javafx.graphics (and javafx.graphics requires javafx.base). As all modules are on the modulepath they will be resolved.

How you set these commands is dependent on how you launch your application (e.g. command-line, IDE, Maven, Gradle, etc...).

If you ever make your code modular you won't need to use the --add-modules command, just put the appropriate requires directives in your module-info file. For example:

module app {
requires javafx.controls;
}

JavaFX InvocationTargetException when pressing button in Pane

The reason your code doesn't work is that you are expecting the canvas to be injected from the FXML into your KrushkalA instance. This simply isn't how this works: @FXML-injection is done by the FXMLLoader when the FXML file is loaded, and any @FXML-annotated fields in the controller instance are initialized with corresponding elements in the FXML file with matching fx:id. Even if you add a fx:id attribute to the canvas defined in the FXML, there's no way that the FXMLLoader can possibly know about the KrushkalA object (which isn't even created at that point, though it wouldn't help if it were).

The whole premise here seems flawed anyway. It's generally a bad idea to allow references to your UI elements to escape from the controller. Suppose at some point in the future you decide you don't want to draw this with a Canvas any more (e.g. you might decide to add Lines, or some other node, to a Pane). In this case, you really should only need to modify the FXML and controller class; if you have allowed your KrushkalA class access to the canvas, then you would need to change that too, and you'd need to look at whether that class passed the canvas reference to anyone else. Maintaining this gets much more difficult if you break encapsulation in this way.

If your KrushkalA class is really just implementing the algorithm, it shouldn't have anything to do with the UI. I think here you are creating a maze (or, more abstractly, a spanning tree for a graph), so your drawMaze() method should just compute the maze and return the result. At it's core, a maze is just a collection of boundaries (or edges) between cells (nodes), so I think I would define a Boundary class with some simple representation of which boundary it is (maybe int x, int y, and boolean horizontal fields, or something else convenient); then you would have:

public class KrushkalA {

public List<Boundary> drawMaze() {
List<Boundary> maze = new ArrayList<>();
// implementation of algorithm...
return maze ;
}
}

Then back in your controller, you would do:

public class MazeController {

@FXML
private Canvas canvas ;

@FXML
private void doKrushkal(ActionEvent e) {
KrushkalA kruAlg = new KrushkalA();
List<Boundary> maze = kruAlg.drawMaze();
// now render maze on canvas, using data in the List<Boundary> from above
renderMaze(maze);
}

private void renderMaze(List<Boundary> maze) {
// clear canvas, iterate through boundaries in maze,
// and draw lines in appropriate place, etc.
}
}

And, of course, add fx:id="canvas" to the <Canvas> element in the FXML.

This approach properly manages separation of concerns and abides by the single responsibility principle: the controller only has responsibility for updating the UI, and doesn't concern itself with how the algorithm is implemented, and the KrushkalA class only has responsibility for implementing the algorithm, and doesn't care how the UI is rendered (or even if there is a UI...).


If you really wanted the algorithm class to render the maze on the canvas, which I strongly do not recommend, then of course you could just pass the canvas to it:

    @FXML
private void doKrushkal(ActionEvent e) {
KrushkalA kruAlg = new KrushkalA();
kruAlg.drawMaze(canvas);
}

and

public class KrushkalA {

public void drawMaze(Canvas canvas) {
// compute maze AND render it on canvas...
}
}

Showing error Caused by: java.lang.reflect.InvocationTargetException

You are calling findViewById before setting the View, so when you call tvAddress.setText, tvAddress is null. Start with this code instead :

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.map);

manager = (LocationManager) getSystemService(LOCATION_SERVICE);
tvAddress = (TextView) findViewById(R.id.tvaddress);
btncurrent= (Button)findViewById(R.id.btncurrent);

locationClient = new LocationClient(this, this, this);

}

Also, you got the error wrong, the real cause is this :

Caused by: java.lang.NullPointerException
at com.mamun.tasktest.MapActivity.marker(MapActivity.java:129)

Take your time to read the stack trace carefully and look for places where it points to classes you wrote, it is always a good place to start for investigating bugs ;)

java.lang.reflect.InvocationTargetException When get value from TextField - Javafx

Thanks for your comment Jose Pereda.

Just a simple careless mistake.
As Jose Pereda said, I added @FXML annotation for textone and it worked fine.



Related Topics



Leave a reply



Submit