I currently have an abstract class which extends JComponent. In this class I have defined a method as follows:
public void makeMouseOverListener(){
System.out.println("Inside make mouseover...");
MouseMotionListener ret = new MouseMotionListener(){
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
System.out.println("Mouse Moved");
}
};
this.addMouseMotionListener(ret);
}
I extend this abstract class with a few other objects, and in the constructors of each of those objects I call this method. I always see the first println, but the "Mouse Moved" line never shows up in my console. I also tried directly creating this MouseMotionListener in each constructor, but with the same results. So ultimately my question is, How can I ensure that I get a working motion listener into my objects? Thank you in advance!
The code inside of the new MouseMotionListener( code ) it seems like this ..
**
MouseMotionListener ret = new MouseMotionListener(
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
System.out.println("Mouse Moved");
}
});
**
If you're invoking makeMouseOverListener in the constructor of your custom components, then its very likely that the mouse position is never positioned over the component itself. Ensure that the dimension of the component is great than 0 x 0. This can be achieved by using a layout manager. e.g. position the component at BorderLayout.CENTER location.
Related
I realize this is a repeat question, but my circumstances are a little bit different. I need to have a MouseListener in another class that can altar the background color of the object that calls it. Please help me.
public class LeftListPanel extends JPanel {
public LeftListPanel() {
setBackground(Settings.BACKGROUND_COLOR);
setLayout(null);
addPersonalStatsTab();
}
private void addPersonalStatsTab() {
JPanel personalStatsPanel = new JPanel();
personalStatsPanel.addMouseListener(new CustomMouseListener());
JLabel personalStatsText = new JLabel("Text");
personalStatsPanel.add(personalStatsText);
add(personalStatsPanel);
}
Then I have an inner-nested class for the MouseListener because this is the only place this MouseListener will be called.
class CustomMouseListener implements MouseListener {
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
setBackground(Settings.BACKGROUND_COLOR.brighter());
}
#Override
public void mouseExited(MouseEvent e) {
setBackground(Settings.BACKGROUND_COLOR);
}
}
The setBackground(COLOR) lines are those who don't work... this.setBack and super.setBack ARE NOT working in this case.. I'M DESPERATE FOR HELP!
The reason you don't see the background changes is that when you call setBackground, you are de-referring (implicitly) the this object, i.e. the instance of LeftListPanel. So, you are actually changing its background, but you don't see it because inside the LeftListPanel instance there is another JPanel (instantiated at the addPersonalStatsTab method) which occupies the whole visible space (or even it is not visible at all, because of that weird null layout; I don't know exactly).
Fist of all, I recommend to you not to set null as a layout. Chose a proper layout, or let it be defaulted - do not call setLayout(null).
Then, set personalStatsPanel as a private member of LeftListPanel. And when calling to setBackground, use it as the scope reference:
LeftListPanel.this.personalStatsPanel.setBackground(...);
This works, I instead just created a private method where I pass in the panel I want to apply it too.
private void CustomMouseListener(JPanel panel) {
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR.brighter());
}
#Override
public void mouseExited(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR);
}
});
}
Thank you all for your time and suggestions :)
You could...
Pass a reference of the component you want changed to the CustomMouseListener
class CustomMouseListener implements MouseListener {
private JPanel panel;
public CustomMouseListener(JPanel panel) {
this.panel = panel;
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR.brighter());
}
#Override
public void mouseExited(MouseEvent e) {
panel.setBackground(Settings.BACKGROUND_COLOR);
}
}
This is okay if you want to use the listener on a limited number of components, but if you want to use the same listener on a number of components...
You could...
Use the source property of the MouseEvent to get which component triggered the event
#Override
public void mouseEntered(MouseEvent e) {
if (!(e.getSource() instanceof JPanel)) {
return;
}
JPanel panel = (JPanel)e.getSource();
panel.setBackground(Settings.BACKGROUND_COLOR.brighter());
}
or, a better solution would be to do something more like...
#Override
public void mouseEntered(MouseEvent e) {
e.getComponent().setBackground(Settings.BACKGROUND_COLOR.brighter());
}
since the information is already provided to you (just not, this returns an instance of Component, so if you need to access the Swing specific properties, you'd still need to cast it).
Why is this approach better?
CustomMouseListener listener = new CustomMouseListener();
panel1.addMouseListener(listener);
panel2.addMouseListener(listener);
panel3.addMouseListener(listener);
panel4.addMouseListener(listener);
panel5.addMouseListener(listener);
panel6.addMouseListener(listener);
panel7.addMouseListener(listener);
because it's agnostic, meaning you can create a single instance of the listener and re-use on multiple components
Hi I'm trying to program a game using java. This is my first time using java, I am used to C#. In C# I would call Mouse.getLocation() and create a rect using the mouses location. Then by using if(Mouse.Left().toString() == "Pressed") I would then check if the mouse rect intersected with any other objects and act accordingly.
I've noticed in java you aren't provided with methods like these. So I was wondering, is the best way to approach mouse input simply to add listeners on all my clickable objects? I understand listeners and have a good idea how to use them but I was just wanting to check if there are more efficient ways to handle input or ways geared more towards what I'm most conformable with.
let your frame implement the MouseListener interface
implement all abstract methods, but in your case it is probably the mouseClicked event
identify if the button clicked is a left click, using the SwingUtilities class
if it is a left click, then set the x and y, which is the location of your click relative to the frame, not the screen.
public class MouseListeningObject extends JFrame implements MouseListener {
int x, y;
public MouseListeningObject () {
addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)){
x = e.getX();
y = e.getY();
}
}
#Override
public void mousePressed(MouseEvent e) {
// Some codes here
}
#Override
public void mouseReleased(MouseEvent e) {
// Some codes here
}
#Override
public void mouseEntered(MouseEvent e) {
// Some codes here
}
#Override
public void mouseExited(MouseEvent e) {
// Some codes here
}
}
You want your frame to implement MouseListener then add it in the constructor.
class MyFrame extends JFrame implements MouseListener {
MyFrame() {
addMouseListener(this);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
}
I'm trying to use the mouseClicked class in my program just to test and figure out. The only problem is that every time I use it I get an error telling me that "void" is the wrong type for mouseClicked. Every website and tutorial I've visited shows me that void is the type I should be using. Here's my code:
public static void door1(){
int x = c.getHeight() / 10;
int y = c.getHeight() * 20 / 100;
public void mouseClicked(MouseEvent e) {
c.drawLine("It worked!",y, x);
}
}
You cannot nest methods in Java. Your class must implement MouseListener inorder to use mouseClicked().
You will also need to implement:
void mousePressed(MouseEvent e) // Invoked when a mouse button has been pressed on a component.
void mouseReleased(MouseEvent e) // Invoked when a mouse button has been released on a component.
void mouseEntered(MouseEvent e) // Invoked when the mouse enters a component.
void mouseExited(MouseEvent e) // Invoked when the mouse exits a component.
I was wondering if you can use an adapter, say a MouseAdapter inside of a class that implements MouseListener.
I know I can use the Adapter as an anonymous Listener
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
panel.setBackground(Color.BLACK);
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
panel.setBackground(Color.WHITE);
repaint();
}
});
But I was wondering if I can define a separate Listener class without having to override all the other abstract methods, like Below
private class myListener implements MouseListener {
#Override
public void mousePressed(MouseEvent e) {
panel.setBackground(Color.BLACK);
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
panel.setBackground(Color.WHITE);
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Sure you can, because:
public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener
It does implement MouseListener.
from http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/awt/event/MouseAdapter.java :
An abstract adapter class for receiving mouse events. The methods in this class are empty. This class exists as convenience for creating listener objects.
Mouse events let you track when a mouse is pressed, released, clicked, moved, dragged, when it enters a component, when it exits and when a mouse wheel is moved.
Extend this class to create a MouseEvent (including drag and motion events) or/and MouseWheelEvent listener and override the methods for the events of interest. (If you implement the MouseListener, MouseMotionListener interface, you have to define all of the methods in it. This abstract class defines null methods for them all, so you can only have to define methods for events you care about.)
Create a listener object using the extended class and then register it with a component using the component's addMouseListener addMouseMotionListener, addMouseWheelListener methods. The relevant method in the listener object is invoked and the MouseEvent or MouseWheelEvent is passed to it in following cases:
when a mouse button is pressed, released, or clicked (pressed and
released)
when the mouse cursor enters or exits the component
when the mouse wheel rotated, or mouse moved or dragged
EDIT:
If your application only needs to know whether the mouse is pressed or released over a component, the other three methods will be empty and ignored. Those methods are unnecessary code. The adapter classes can help reduce the amount of code you must write when your application needs only a small subset of all interface methods. Each adapter class fully implements its associated interface (or interfaces). Then, if you want a listener for a subset of associated methods, you just have to provide that subset. No empty stubs required. Here is just such an adapter for the required MouseListener previously described.
MouseListener mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent mouseEvent) {
System.out.println("I'm pressed: " + mouseEvent);
}
public void mouseReleased(MouseEvent mouseEvent) {
System.out.println("I'm released: " + mouseEvent);
}
};
https://blogs.oracle.com/CoreJavaTechTips/entry/listeners_vs_adapters
In the game that I'm currently making I have three different mousePressed methods, one for single fire, one for automatic fire and one for melee attacks. Because the one for automatic fire uses a swing Timer I can override it in the other mousePressed methods by using timer.stop(); in them.
But the single fire mousePressed calls the fire() method directly so I can't override it in any way from the other mousePressed. The code below shows the method for the fireing (bullet is a ArrayList).
public void fire(){
if(!power.getChainsaw()){
bullet.add(new Bullet(x, y));
}
}
When the player gets a melee weapon I therefor need to remove the MouseListener for the single fireing. I have tried the code below but it didn't work.
removeMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
)};
I add the single fire and melee MouseListener in the exact same way as this. This is hwo the acctual mousePressed methods lok like.
public void mousePressed2(MouseEvent e){
if(SwingUtilities.isLeftMouseButton(e)){
timer.stop();
fire();
}
}
public void mousePressed3(MouseEvent e){
if(SwingUtilities.isLeftMouseButton(e)){
timer.stop();
}
}
mousePressed2 is the single fire method and mousePressed3 is the melee method
removeMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
)};
Look at what you are doing here. You are removing an instance of MouseAdapter created in place. This means that a new instance of mouse adapter will be created and then removed, but because the specific listener instance is not binded to any button, nothing will happen.
Pass the correct listener to the removeMouseListener method and it will work.
MouseAdapter myListener = new MouseAdapter() {
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
};
someButton.addMouseListener(myListener);
// then when you want to remove it, use the same referenece.
someButton.removeMouseListener(myListener);