I want to set custom cursor in my java swing app, and then edit it.
I set a custom cusrsor after showing window (in "Window" class).
Later in code (in the other class), I want to chainge it again, so i call this updateCursor()
funcion (in "Window" class again), and it and it won't work. There is no errors or warnings, but the cursor isn't changing - just stays the same. I tried, and I can't find answer anywhere. I appreciate any help.
This is full code - Window.java:
import MainMenu;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
public class Window {
public static final int WIDTH = 817, HEIGHT = 640;
JFrame frame = new JFrame("");
public void open() {
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
frame.setSize(WIDTH - 33, HEIGHT - 25);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.requestFocus();
frame.setFocusTraversalKeysEnabled(true);
frame.addKeyListener(new InputManager());
frame.addMouseListener(new InputManager());
frame.add(new MainMenu());
frame.add(new Game());
loadCursors();
updateCursor(0);
}
public static final int NORMAL = 0, ACTIVE = 1, INACTIVE = 2;
Cursor cursor_normal, cursor_active, cursor_inactive;
public void loadCursors() {
try {
cursor_normal = Toolkit.getDefaultToolkit().createCustomCursor(ImageIO.read(new File(new SpritesManager().cursor_normal)), new Point(0, 0), "custom cursor (normal)");
cursor_active = Toolkit.getDefaultToolkit().createCustomCursor(ImageIO.read(new File(new SpritesManager().cursor_active)), new Point(0, 0), "custom cursor (active)");
cursor_inactive = Toolkit.getDefaultToolkit().createCustomCursor(ImageIO.read(new File(new SpritesManager().cursor_inactive)), new Point(0, 0), "custom cursor (inactive)");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void updateCursor(int cursorType) {
switch (cursorType) {
case NORMAL -> frame.setCursor(cursor_normal);
case ACTIVE -> frame.setCursor(cursor_active);
case INACTIVE -> frame.setCursor(cursor_inactive);
}
}
}
MainMenu.java:
import Window;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MainMenu extends JPanel implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
// testing
new Window().updateCursor(Window.ACTIVE);
}
@Override
public void keyReleased(KeyEvent e) {
}
}
You can't do ...
and magically expect the other instance of
Window
to be updated, in fact, you don't need to do this at all.This is going to create another instance/copy of
Window
, which is not present on the screen and it will have no effect on the instance which is been displayed.You could call
setCursor
directly on the instanceMainMenu
.Now, if you want to "centralise" the functionality, I would start by creating a "manager" class, for example...
I would then create this instance of the manager during the initialisation phase of your code
And then pass this instance to every class that might need it...
And...
This is commonly known as "dependency injection" and is VERY powerful
Feedback
Just as a side note, if I was doing something like this, it would be very different, but I tried to keep it simple.
JFrame
, as stated,JFrame
is not a simple component and you're not actually adding any new functionality to the class and in the process, locking yourself into a single use, there by reducing re-usability. Better to start with aJPanel
as your base component and simply create an instance ofJFrame
or `JDialog or what ever top level container you want to use, when you need itKeyListener
is a poor choice for monitoring keyboard input (seriously, just do a search for "my key listener won't work". Instead, take a look at How to Use Key Bindings