I am getting null pointer exception when I try spawning an item(Mushroom) when the player collides with a particular coin(As in MARIO game). I have been following this tutorial but I want the inputs to be buttons and not the keys. I have created 4 buttons and added to the stage . The inputs are working perfectly . But I am getting exception when,
I simply add the buttons to the stage and the input is still using keys
I am not getting exception when,
I remove all the buttons from the code and the input is using keys.
Here is my code for adding buttons to the stage ,
public class PlayScreen implements Screen, InputProcessor
{
.......
private Array<Item> items;
private LinkedBlockingQueue<ItemDef> itemsToSpawn;
private TextureAtlas atlas = new TextureAtlas("move_sprites.pack"); //contains the mushroom as well as the player packed together
public PlayScreen(MyGame game) {
.............
stage = new Stage();
atlas = new TextureAtlas("ui/button_pack.pack");
skin = new Skin(atlas);
white = new BitmapFont(Gdx.files.internal("fonts/white.fnt"), false);
black = new BitmapFont(Gdx.files.internal("fonts/black.fnt"), false);
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.up = skin.getDrawable("buttonin");
textButtonStyle.down = skin.getDrawable("buttonout");
textButtonStyle.pressedOffsetX = 1;
textButtonStyle.font = black;
buttonright = new TextButton("Right", textButtonStyle);
buttonleft = new TextButton("Left", textButtonStyle);
//table.setBounds(500, 5, 250, 150);
buttonleft.setPosition(350, 5);
buttonleft.setHeight(100);
buttonleft.setWidth(100);
buttonright.setPosition(100, 5);
buttonright.setHeight(100);
buttonright.setWidth(100);
buttonup = new TextButton("up", textButtonStyle);
buttonup.setPosition(600, 5);
buttonup.setHeight(100);
buttonup.setWidth(100);
stage.addActor(buttonup);
stage.addActor(buttonright);
stage.addActor(buttonleft);
Gdx.input.setInputProcessor(stage);
......
}
//create a new method
public void spawnItem(ItemDef idef)
{
itemsToSpawn.add(idef);
}
public void handleSpawingItems()
{
if (!itemsToSpawn.isEmpty()) {
ItemDef idef = itemsToSpawn.poll(); //poll is pop
if (idef.type == Mushroom.class) {
items.add(new Mushroom(this, idef.position.x, idef.position.y));
}
}
}
public void update(float dt) {
handleInput(dt);
handleSpawingItems();
........
}
//Giving inputs using buttons
public void handleInput(float dt)
{
if (gamehero.currentState != Hero.State.DEAD) {
buttonup.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
gamehero.heroBody.setLinearVelocity(0, 4f);
}
return true;
}
}
);
}
}
public void render(float delta)
{
......
update(delta);
stage.act();
stage.draw();
}
}
}
Mushroom Class..
public class Mushroom extends Item {
public Mushroom(PlayScreen screen, float x, float y) {
super(screen, x, y);
//mush is one of the sprite packed together using texture packer. Exception is thrown in the below line
setRegion(screen.getAtlas().findRegion("mush"), 0, 0, 16, 16);
velocity = new Vector2(0.7f, 0); //velocity of mushroom
}
I am triggering this mushroom when mario head collides with coin like below,
public class Coins extends InteractiveTileObject {
....
public void onHeadHit(Hero hero) {
if (object.getProperties().containsKey("mushroom")) {
Gdx.app.log("coins", "collision");
//Exception occurs in the below line too. When the collision occurs, spawnItem method is called in the main class
screen.spawnItem(new ItemDef(new Vector2(body.getPosition().x, body.getPosition().y + 16 / MyGame.PPM), Mushroom.class));
}
ItemDef Class,
public class ItemDef {
public Vector2 position;
public Class<?> type;
public ItemDef(Vector2 position, Class<?> type)
{
this.position = position;
this.type = type;
}
}
Exception occurs if I just add a button to my code and gave the input using keys. Problem lies in spawning the mushroom if I just add a button to my code. Its weird. Please help. I am a beginner . Thanks in advance
I found the cause for this Exception.
I have given the same name for 2 TextureAtlas while declaring,
private TextureAtlas atlas = new TextureAtlas("move_sprites.pack");
and the other,
atlas = new TextureAtlas("ui/button_pack.pack");
But I am referring the first TextureAtlas in other class. Since I have declared the TextureAtlas only once but used for two different packs, It threw null pointer exception as there was name conflict. Thanks for all your answers.
Related
#FXML
private void handleDeleteAction(ActionEvent event) {
for (Transaction transaction : transactionsTable.getSelectionModel().getSelectedItems()) {
RemoveTransactionsCommand removeTransactionsCommand = new RemoveTransactionsCommand(transaction, transactionsTable.getSelectionModel().getSelectedItems(), data);
commandRegistry.executeCommand(removeTransactionsCommand);
}
}
Why it won't work in case where I select more than one row, I mean it delete one row (sometimes two, but can't find what decide about it)
Here is command implementation:
public class RemoveTransactionsCommand implements Command {
private ObservableList<Transaction> selectedItems;
private Transaction transactionToRemove;
private Account account;
public RemoveTransactionsCommand(Transaction transactionToRemove, ObservableList<Transaction> selectedItems, Account account) {
this.account = account;
this.transactionToRemove = transactionToRemove;
this.selectedItems = selectedItems;
}
#Override
public String getName() {
int presentSize = selectedItems.size();
return presentSize + "transaction/s removed";
}
#Override
public void execute() {
account.removeTransaction(transactionToRemove);
}
}
And removal command:
public void removeTransaction(Transaction transaction) {
this.transactions.remove(transaction);
}
Additionally I wanted to know the size of actual delete operation but what I pass as a 2nd argument isn't static and for example when every row is deleted it will be 0.
Any advices how to improve it?
Full project can be found here
The problem is that the selected items list may change when the list of items in the table changes. So the list gets modified while you are trying to iterate through it.
You should create a copy of the list of selected items and iterate through it instead:
#FXML
private void handleDeleteAction(ActionEvent event) {
List<Transaction> selectedTransactions = new ArrayList<>(transactionTable.getSelectionModel().getSelectedItems());
for (Transaction transaction : selectedTransactions) {
RemoveTransactionsCommand removeTransactionsCommand = new RemoveTransactionsCommand(transaction, selectedTransactions, data);
commandRegistry.executeCommand(removeTransactionsCommand);
}
}
(and change the type of selectedItems in RemoveTransactionsCommand to List<Transaction>).
My code currently reads my Gmail inbox via IMAP (imaps) and javamail, and once it finds an email with zip/xap attachment, it displays a stage (window) asking whether to download the file, yes or no.
I want the stage to close once I make a selection, and then return to the place within the loop from which the call came. My problem arises because you cannot launch an application more than once, so I read here that I should write Platform.setImplicitExit(false); in the start method, and then use primartyStage.hide() (?) and then something like Platform.runLater(() -> primaryStage.show()); when I need to display the stage again later.
The problem occuring now is that the flow of command begins in Mail.java's doit() method which loops through my inbox, and launch(args) occurs within a for loop within the method. This means launch(args) then calls start to set the scene, and show the stage. Since there is a Controller.java and fxml associated, the Controller class has an event handler for the stage's buttons which "intercept" the flow once start has shown the stage. Therefore when I click Yes or No it hides the stage but then just hangs there. As if it can't return to the start method to continue the loop from where launch(args) occurred. How do I properly hide/show the stage whenever necessary, allowing the loop to continue whether yes or no was clicked.
Here is the code for Mail.java and Controller.java. Thanks a lot!
Mail.java
[Other variables set here]
public static int launchCount = 0;#FXML public Text subjectHolder;
public static ReceiveMailImap obj = new ReceiveMailImap();
public static void main(String[] args) throws IOException, MessagingException {
ReceiveMailImap.doit();
}
#Override
public void start(Stage primaryStage) throws Exception {
loader = new FXMLLoader(getClass().getResource("prompts.fxml"));
root = loader.load();
controller = loader.getController();
controller.setPrimaryStage(primaryStage);
scene = new Scene(root, 450, 250);
controller.setPrimaryScene(scene);
scene.getStylesheets().add("styleMain.css");
Platform.setImplicitExit(false);
primaryStage.setTitle("Download this file?");
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void doit() throws MessagingException, IOException {
Folder inbox = null;
Store store = null;
try {
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);
store = session.getStore("imaps");
store.connect("imap.gmail.com", "myAccount#gmail.com", "Password");
inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_WRITE);
Message[] messages = inbox.getMessages();
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(UIDFolder.FetchProfileItem.FLAGS);
fp.add(UIDFolder.FetchProfileItem.CONTENT_INFO);
fp.add("X-mailer");
inbox.fetch(messages, fp);
int doc = 0;
int maxDocs = 400;
for (int i = messages.length - 1; i >= 0; i--) {
Message message = messages[i];
if (doc < maxDocs) {
doc++;
message.getSubject();
if (!hasAttachments(message)) {
continue;
}
String from = "Sender Unknown";
if (message.getReplyTo().length >= 1) {
from = message.getReplyTo()[0].toString();
} else if (message.getFrom().length >= 1) {
from = message.getFrom()[0].toString();
}
subject = message.getSubject();
if (from.contains("myAccount#gmail.com")) {
saveAttachment(message.getContent());
message.setFlag(Flags.Flag.SEEN, true);
}
}
}
} finally {
if (inbox != null) {
inbox.close(true);
}
if (store != null) {
store.close();
}
}
}
public static boolean hasAttachments(Message msg) throws MessagingException, IOException {
if (msg.isMimeType("multipart/mixed")) {
Multipart mp = (Multipart) msg.getContent();
if (mp.getCount() > 1) return true;
}
return false;
}
public static void saveAttachment(Object content)
throws IOException, MessagingException {
out = null; in = null;
try {
if (content instanceof Multipart) {
Multipart multi = ((Multipart) content);
parts = multi.getCount();
for (int j = 0; j < parts; ++j) {
part = (MimeBodyPart) multi.getBodyPart(j);
if (part.getContent() instanceof Multipart) {
// part-within-a-part, do some recursion...
saveAttachment(part.getContent());
} else {
int allow = 0;
if (part.isMimeType("application/x-silverlight-app")) {
extension = "xap";
allow = 1;
} else {
extension = "zip";
allow = 1;
}
if (allow == 1) {
if (launchCount == 0) {
launch(args);
launchCount++;
} else {
Platform.runLater(() -> primaryStage.show());
}
} else {
continue;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if ( in != null) { in .close();
}
if (out != null) {
out.flush();
out.close();
}
}
}
public static File createFolder(String subject) {
JFileChooser fr = new JFileChooser();
FileSystemView myDocs = fr.getFileSystemView();
String myDocuments = myDocs.getDefaultDirectory().toString();
dir = new File(myDocuments + "\\" + subject);
savePathNoExtension = dir.toString();
dir.mkdir();
System.out.println("Just created: " + dir);
return dir;
}
}
Controller.java
public class Controller implements Initializable {
#FXML
private Text subjectHolder;
public Button yesButton, noButton;
public ReceiveMailImap subject;
#Override
public void initialize(URL url, ResourceBundle rb) {
subject= new ReceiveMailImap();
subjectHolder.setText(subject.returnSubject());
}
public Stage primaryStage;
public Scene scene;
#FXML
ComboBox<String> fieldCombo;
public void setPrimaryStage(Stage stage) {
this.primaryStage = stage;
}
public void setPrimaryScene(Scene scene) {
this.scene = scene;
}
public String buttonPressed(ActionEvent e) throws IOException, MessagingException {
Object source = e.getSource();
if(source==yesButton){
System.out.println("How to tell Mail.java that user clicked Yes?");
return "POSITIVE";}
else{subject.dlOrNot("no");
System.out.println("How to tell Mail.java that user clicked No?");
primaryStage.hide();
return "NEGATIVE";}
}
}
There are a lot of issues with the code you have posted, but let me just try to address the ones you ask about.
The reason the code hangs is that Application.launch(...)
does not return until the application has exited
In general, you've kind of misunderstood the entire lifecycle of a JavaFX application here. You should think of the start(...) method as the equivalent of the main(...) method in a "traditional" Java application. The only thing to be aware of is that start(...) is executed on the FX Application Thread, so if you need to execute any blocking code, you need to put it in a background thread.
The start(...) method is passed a Stage instance for convenience, as the most common thing to do is to create a scene graph and display it in a stage. You are under no obligation to use this stage though, you can ignore it and just create your own stages as and when you need.
I think you can basically structure your code as follows (though, to be honest, I have quite a lot of trouble understanding what you're doing):
public class Mail extends Application {
#Override
public void start(Stage ignored) throws Exception {
Platform.setImplicitExit(false);
Message[] messages = /* retrieve messages */ ;
for (Message message : messages) {
if ( /* need to display window */) {
showMessage(message);
}
}
}
private void showMessage(Message message) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("prompts.fxml"));
Parent root = loader.load();
Controller controller = loader.getController();
Scene scene = new Scene(root, 450, 250);
stage.setScene(scene);
stage.initStyle(StageStyle.UNDECORATED);
stage.setTitle(...);
// showAndWait will block execution until the window is hidden, so
// you can query which button was pressed afterwards:
stage.showAndWait();
if (controller.wasYesPressed()) {
// ...
}
}
// for IDEs that don't support directly launching a JavaFX Application:
public static void main(String[] args) {
launch(args);
}
}
Obviously your logic for decided whether to show a window is more complex, but this will give you the basic structure.
To check which button was pressed, use showAndWait as above and then in your controller do
public class Controller {
#FXML
private Button yesButton ;
private boolean yesButtonPressed = false ;
public boolean wasYesPressed() {
return yesButtonPressed ;
}
// use different handlers for different buttons:
#FXML
private void yesButtonPressed() {
yesButtonPressed = true ;
closeWindow();
}
#FXML
private void noButtonPressed() {
yesButtonPressed = false ; // not really needed, but makes things clearer
closeWindow();
}
private void closeWindow() {
// can use any #FXML-injected node here:
yesButton.getScene().getWindow().hide();
}
}
In my application, I have multiple fragments on a single activity. Now I want to write a test case to check if these fragments are loading properly. To begin with, I passed some touch event to scroll to a particular fragment and then I am trying to fetch the name of this fragment. Below is my code for the test case:-
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity>
{
MainActivity mMainActivity;
ActionBar tactionbar;
Fragment tFragment;
public static final int TEST_POSITION = 2;
private static String mSelection ;
private int mPos = 0;
public MainActivityTest()
{
super(MainActivity.class);
}
protected void setUp() throws Exception
{
super.setUp();
mMainActivity = (MainActivity) getActivity();
tactionbar = mfoneclay.getActionBar();
}
public void testPreConditions()
{
assertNotNull(mMainActivity);
assertNotNull(tactionbar);
}
public void testFragmentUI()
{
mMainActivity.runOnUiThread(
new Runnable(){
public void run()
{
mMainActivity.getCurrentFocus();
}
});
for (int i = 1; i <= TEST_POSITION; i++)
{
this.sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
mPos = tactionbar.getSelectedNavigationIndex();
}
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
mSelection = (String)tactionbar.getTabAt(mPos).getText();
String resultText = "Exclusive";
assertEquals(resultText,mSelection);
}
}
Here, "Exclusive" is the name of one of my tab to which I am navigating to via the touch event. Now, while running the test case, I can see that it is properly navigating to the "Exclusive" fragment, but the result shows the value of the msection variable as the name of the activity and not the fragments name. What am I doing wrong?
Got the solution. It was so stupid of me to use the wrong components to fetch the fragment. It turns out that I have to use "ViewPager" to fetch the fragments.
In the beginning, I create a new FPSAnimator(drawable,FPS,true);
Is it possible to speed up or slow down (i.e, change the FPS of animating) the animating speed after FPSAnimator started?
FPSAnimator has a method named .setFPS() . It works after the animator has already been started. Here is the link for you.
EDIT:
When Animator starts it is not possible to change FPS again and some methods such as this is not working or my level of coding is not enough to use it.
So here I will give you a small Java example about how to change FPS after you first start the Animator.
Lets assume we have a simple snake game with OpenGL (libjogl) and your main method is;
public static void main(String[] args) {
GLCanvas canvas = new GLCanvas();
Frame frame = new Frame("Snake");
frame.setSize(500, 500);
frame.add(canvas);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
Animator animator = new FPSAnimator(canvas, fps);
SnakeGameScene scene = new SnakeGameScene(animator);
canvas.requestFocus();
canvas.addGLEventListener(scene);
canvas.addKeyListener(scene);
animator.start();
}
Here you have your frame, Canvas WindowListener, Animator, the thing OpenGL animate, in this case it is SnakeGameScene... If we change the main and the class where main method is, to make animator fps changable by some trigger. The code I will show will change it with key presses. Therefore, it is in SnakeGameScene's keyPressed #Overrides.
#Override
public void keyPressed(KeyEvent k) {
int keyCode = k. getKeyCode();
try{
if(this.lockKeyAfterPressed){
switch(keyCode){
case KeyEvent.VK_UP:
this.snake.setDirection(Direction.UP);
lockKeyAfterPressed =false;
break;
case KeyEvent.VK_DOWN:
this.snake.setDirection(Direction.DOWN);
lockKeyAfterPressed =false;
break;
case KeyEvent.VK_LEFT:
this.snake.setDirection(Direction.LEFT);
lockKeyAfterPressed =false;
break;
case KeyEvent.VK_RIGHT:
this.snake.setDirection(Direction.RIGHT);
lockKeyAfterPressed =false;
break;
case KeyEvent.VK_Z: // n1
Application.increaseFPS();
break;
case KeyEvent.VK_X://n2
Application.decreaseFPS();
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
In this part, relevant cases are the last two cases, n1 and n2. When respective key is pressed it either increase or decrease. But as I said above we need to stop the animator first. So we change the main class as followes;
public class Application {
private static int fps = 1;
private static Animator animator;
private static GLCanvas canvas;
public static void setAnimator(Animator animator){Application.animator = animator;}
public static int getFps() {return fps;}
public static void setFps(int fps) {Application.fps = fps;}
public static void increaseFPS(){
animator.stop();
setFps((getFps()+1));
Application.updateAnimator();
}
public static void decreaseFPS(){
animator.stop();
setFps((getFps()-1));
if(getFps() <1){setFps(1);}
Application.updateAnimator();
}
private static void updateAnimator(){
Application.setAnimator(new FPSAnimator(canvas, fps));
animator.start();
}
public static void main(String[] args) {
canvas = new GLCanvas();
Frame frame = new Frame("Snake");
frame.setSize(500, 500);frame.add(canvas);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
animator = new FPSAnimator(canvas, fps);
SnakeGameScene scene = new SnakeGameScene(animator);
canvas.requestFocus();
canvas.addGLEventListener(scene);
canvas.addKeyListener(scene);
animator.start();
}
}
Here, you do not create Canvas, animator and Fps in main method, they must be in the Class. When the respective key is pressed the system will stop the animator,then create a new animator with an updated fps and sets it as animator, the start the animator instance again.
Sorry if I overkill, add irrelevant codes, make description and syntax mistake.
Hope it helps you.
I want to know whether how to capture the button clicked with AspectJ and get its parameter (eg. button name). I think for having more generalized capturing with AspectJ, it shoudl be used MouseListener so it can capture other UI elements in general!
Example:
In a GUI example I have defined 2 buttons that take some actions
public JButton btn1 = new JButton("Test1");
public JButton btn2 = new JButton("Test2");
btn1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//take some actions
}
}
btn2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//take some actions
}
}
How to capture these buttons with AspectJ, and get their parameters (eg. name)?
It is possible. I have provided two examples. The first that prints out for every JButton that has an ActionListener. The other example only prints out if a specific buttons is clicked.
Prints the text for every JButton clicked with an ActionListener:
#Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent)")
public void buttonPointcut(ActionEvent actionEvent) {}
#Before("buttonPointcut(actionEvent)")
public void beforeButtonPointcut(ActionEvent actionEvent) {
if (actionEvent.getSource() instanceof JButton) {
JButton clickedButton = (JButton) actionEvent.getSource();
System.out.println("Button name: " + clickedButton.getText());
}
}
Prints the text for a specific JButton:
public static JButton j1;
#Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent) && if()")
public static boolean button1Pointcut(ActionEvent actionEvent) {
return (actionEvent.getSource() == j1);
}
#Before("button1Pointcut(actionEvent)")
public void beforeButton1Pointcut(ActionEvent actionEvent) {
// logic before the actionPerformed() method is executed for the j1 button..
}
UPDATED:
You can do this in many different ways. For example add your buttons to the aspect directly. But I prefere to use a enum object between (ButtonManager in this case), so the code does not know about the aspect. And since the ButtonManager is an enum object, it is easy for the aspect to retrieve values from it.
I just tested it with a Swing button class from Oracle and it works. In the Swing class:
b1 = new JButton("Disable middle button", leftButtonIcon);
ButtonManager.addJButton(b1);
AspectJ is extremely powerful when it comes to manipulating classes, but it can not weave advises into specific objects since objects is not created at the time of weaving. So you can only work with objects at runtime and that is why I have added the addJButton(..) method above. That enables the aspect to check the advised button against a list of registered buttons.
The ButtonManager class:
public enum ButtonManager {
;
private static Collection<JButton> buttonList = new LinkedList<JButton>();
public static void addJButton(JButton jButton) {
buttonList.add(jButton);
}
public static Collection<JButton> getButtonList() {
return buttonList;
}
}
Modified pointcut and advice to only print the name of the buttons registered in the ButtonManager:
#Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent) && if()")
public static boolean buttonListPointcut(ActionEvent actionEvent) {
Collection<JButton> buttonList = ButtonManager.getButtonList();
JButton registeredButton = null;
for (JButton jButton : buttonList) {
if (actionEvent.getSource() == jButton) {
registeredButton = jButton;
}
}
return registeredButton != null;
}
#Before("buttonListPointcut(actionEvent)")
public void beforeButtonListPointcut(ActionEvent actionEvent) {
JButton clickedButton = (JButton) actionEvent.getSource();
System.out.println("Registered button name: " + clickedButton.getText());
}
UPDATED 2
Okay, I believe I understand what you want. You want to listen to mouse events. That is possible. The downside is that you have to register all your GUI components that you want to listen for clicks with a mouse listener. It is not enough to register the JPanel of the JFrame with a MouseListener. So if you only have registered an ActionListener for your buttons, you also have to add a mouse listener.
I have created a quick solution that works for me. It only shows that it works. I have not tried to make the solution generic with many different GUI objects. But that should be quite easy to refactor in when you have got the basics to work.
In the Swing class:
private class MouseListener extends MouseInputAdapter {
public void mouseClicked(MouseEvent e) {}
}
In the init method of the Swing class:
MouseListener myListener = new MouseListener();
btn1.addMouseListener(myListener);
btn2.addMouseListener(myListener);
In the Aspect class:
#Pointcut("execution(* *.mouseClicked(*)) && args(mouseEvent)")
public void mouseEventPointcut(MouseEvent mouseEvent) {}
#Before("mouseEventPointcut(mouseEvent)")
public void beforeMouseEventPointcut(MouseEvent mouseEvent) {
if (mouseEvent.getSource() instanceof JButton) {
JButton clickedButton = (JButton) mouseEvent.getSource();
System.out.println("aspectJ --> mouseClicked: " + clickedButton.getText());
}
}
This results in the following output in the console:
aspectJ --> mouseClicked: Test1
I hope it helps!