I am trying to create a mouse listener class, simply for detecting mouse clicks. My code
package game.input;
import java.awt.event.*;
import java.awt.*;
public class Mouse implements MouseAdapter{
public Mouse(Component c){
c.addMouseListener(this);
}
public boolean mouseClicked(MouseEvent e) {
return true;
}
}
is giving me two errors:
"Interface expected here", pointing to the MouseAdapter
"Method addMouseListener in class Component cannot be applied to given types", pointing to the c.addMouseListener(this)
How can I solve this two problems and accomplish the simple task of creating a detector for mouse clicks? This is the first time I write a MouseListener, so any other comments about mistakes I have done are welcome.
MouseAdapter is a class not a interface, you need to use extends instead of implements
public class Mouse extends MouseAdapter{
Take a look at
What Is a Class?
What Is an Interface?
How to Write a Mouse Listener
For more details
FYI...
public boolean mouseClicked(MouseEvent e) {
Will never be called, as it does not meet the requirements of the MouseListener interface contract, it should be...
#Override
public void mouseClicked(MouseEvent e) {
Related
How to Register MouseMotionListener without using Applet,JFrame,JPanel or anything.Because i want to capture mouse positions when mouse is just moved in a System?
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.*;
import java.awt.*;
class Mouseposition extends MouseAdapter
{
public void mouseMoved(MouseEvent e)
{
System.out.println("MOuse x : "+MouseInfo.getPointerInfo().getLocation().x+ "Mouse Y : "+MouseInfo.getPointerInfo().getLocation().y);
}
public static void main(String args[])
{
//--- register for Mouse events
----
while(true);
}
}
You can't, Java won't listen to global OS events in this way.
You could use a JNI/JNA hook into the OS, for example or example or use a Thread to constantly poll the MouseInfo class, for example and example, which probably isn't very efficient...
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import javax.swing.event.*;
import javax.swing.JPanel;
public class Triangle extends JFrame
{
public Triangle()
{
add(new PolygonsPanel());
}
public static void main(String [] args)
{
Triangle t = new Triangle();
t.setSize(500,500);
t.setTitle("Triangle");
t.setVisible(true);
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setLocationRelativeTo(null);
}
}
class PolygonsPanel extends JPanel implements MouseListener
{
private int x1,x2,x3,y1,y2,y3;
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Polygon p = new Polygon();
p.addPoint(x1,y1);
p.addPoint(x2,y2);
p.addPoint(x3,y3);
this.addMouseListener(this);
g.drawPolygon(p);
}
public void mouseExited(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
int i = 0;
if(i==0)
{
int x1= e.getX();
int y1= e.getY();
i++;
}
else if(i==1)
{
int x2= e.getX();
int y2= e.getY();
i++;
}
else if(i==2)
{
int x3= e.getX();
int y3= e.getY();
i++;
}
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
}
I want to make triangle using polygon and set the coordinate by click the mouse.
compiler did't show error, can anybody help ?
..........................................................................................................................................................................................................
In order to debug such applications, you can add println() lines in the right places. While this sounds a bit childish, this method of debugging, called printf-Debugging is even used by the most professional developers in some cases.
I suggest you add a System.err.println("1") resp. System.err.println("2") / System.err.println("3") in each of the if-branches of mouseClicked() to find out why it's not properly recording the points. Hint: You probably want variable i to have a different scope than now`.
Registering the MouseListener should not be done in paintComponent(). If you think a little bit about this, it should be obvious. Ask yourself: How often do I need to register the MouseListener? Only once. How often is paintComponent() called? Many times. So, the addMouseListener() is certainly in the wrong place.
Once you fixed these, you might notice that you have to hide/unhide, resize or (on some OS) move the window in order for your polygons to be redrawn. That's because once you've changed the appearance by recording a new coordinate for your polygon, you don't tell Java that the component needs to be redrawn.
The programming model usage by extension which you apply is still shown on many web pages and in many books as of today, but it's plainly wrong because it often violates the LSP - Liskov Substitution Principle. In your case, extending the JPanel for a PolygonsPanel is almost right, because that is a kind of Painting Canvas which in fact is a new component, so, creating a new class that is a component is perfect for that. Just JPanel might not be the best superclass for it, check out the class hierarchy of Swing class a bit and you will discover a better superclass. However, in Triangle, you do not really want to extend JFrame, you merely use JFrame without adding any new reusable features to it, so subclassing is not right in that case.
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class AppWindow extends Frame {
String keyMessage = "";
String MouseMsg = "";
int mouseX = 10;
int mouseY = 40;
int locX = 0;
int locY = 0;
public AppWindow() {
addMouseListener(new MyMouseAdaptor(this));
}
public void paint(Graphics g) {
g.drawString(keyMessage, mouseX, mouseY);
g.drawString(MouseMsg, locX, locY);
}
public static void main(String[] args) {
AppWindow appWindow = new AppWindow();
appWindow.setSize(400, 400);
appWindow.setVisible(true);
}
}
class MyMouseAdaptor extends MouseAdapter implements MouseListener {
AppWindow appWindow;
public MyMouseAdaptor(AppWindow appWindow) {
this.appWindow = appWindow;
}
public void mousePressed(MouseEvent e) {
this.appWindow.MouseMsg = "Mouse Pressed at : " + e.getX() + ", "
+ e.getY();
this.appWindow.locX = e.getX();
this.appWindow.locY = e.getY();
this.appWindow.repaint();
}
}
Dear All
I have a weird question. I know everything in the above code yet I am missing something. How Java knows when the mousePressed Event occurred? I need to find the answer for my own logic. Where is the code written that says
when the user press the mouse -- > trigger the method "public void mousePressed(MouseEvent e)" and do what is inside it
Thanks
This is the code that registers to look out for mouse events:
public AppWindow() {
addMouseListener(new MyMouseAdaptor(this));
}
This is your class that extends MouseAdaptor and listens for events:
class MyMouseAdaptor extends MouseAdapter implements MouseListener {
AppWindow appWindow;
public MyMouseAdaptor(AppWindow appWindow) {
this.appWindow = appWindow;
}
public void mousePressed(MouseEvent e) {
this.appWindow.MouseMsg = "Mouse Pressed at : " + e.getX() + ", "
+ e.getY();
this.appWindow.locX = e.getX();
this.appWindow.locY = e.getY();
this.appWindow.repaint();
}
}
MouseAdaptor:
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
Link
MouseListener:
The listener interface for receiving "interesting" mouse events (press, release, click, enter, and exit) on a component. (To track mouse moves and mouse drags, use the MouseMotionListener.)
The class that is interested in processing a mouse event either implements this interface (and all the methods it contains) or extends the abstract MouseAdapter class (overriding only the methods of interest).
The listener object created from that class is then registered with a component using the component's addMouseListener method. A mouse event is generated when the mouse is pressed, released clicked (pressed and released). A mouse event is also generated when the mouse cursor enters or leaves a component. When a mouse event occurs, the relevant method in the listener object is invoked, and the MouseEvent is passed to it.
Link
Now after you have read this, I think you will be able to make some changes to your program because when you implement MouseListener interface you have to define all of the methods in it..
There are actually two event classes associated with the mouse: MouseEvent and MouseMotionEvent. There are also two listener interfaces, MouseListener and MouseMotionListener. The MouseListener interface declares the methods
public void mousePressed(MouseEvent evt);
public void mouseReleased(MouseEvent evt);
public void mouseClicked(MouseEvent evt);
public void mouseEntered(MouseEvent evt);
public void mouseExited(MouseEvent evt);
and the MouseMotionListener declares
public void mouseMoved(MouseEvent evt);
public void mouseDragged(MouseEvent evt);
Any component can generate mouse events. An object that wants to respond to these events must implement one or both of the listener interfaces. It must also register itself with the component by calling the component's addMouseListener() and/or addMouseMotionListener() methods. Note that an object that implements MouseListener must provide definitions for all five of the methods in that interface, even if a definition consists just of an empty set of braces. Similarly, an object that implements MouseMotionListener must define both the mouseMoved() and the mouseDragged() methods.
A component calls mousePressed() whenever one of the buttons on the mouse is pressed while the mouse cursor is over that component. It will then call the mouseReleased() method when the button is released -- even if the cursor has moved outside of the component by that time. The mouseClicked() method is called if the button is pressed and released at the same point; it is called in addition to mousePressed() and mouseReleased(). If you simply want to respond to mouse clicks, you should probably do so in the mousePressed() routine, and leave the definitions of mouseReleased() and mouseClicked() empty.
Source
I would like to create a new Swing JComponent based on an existing one, but with a different API. In other words, I don't want to extend the existing component, because I don't want it's API to be accessible.
Here an example to clarify my needs:
A replacement of the JCheckBox which show two buttons ON/OFF. This could be based on a pre-configured JCommandButtonStrip (some info here) but exposing exactly the same API of JCheckBox. The configuration of the JCommandButtonStrip must not be altered.
What is the best approach for such a problem?
Clarifications:
As someone pointed out, what I wrote about API is not clear.
Of course JComponent have a number of public fields and methods which will be available for each sub-class. Then each sub-class of JComponent may add its own public fields and methods. For example, AbstractButton adds the isSelected() method, while JCommandButtonStrip adds the getButtonCount() method.
So, what I meant is: I want to create a new JComponent sub-class MyJComponent, which is based on an existing one ExistingJComponent. I don't want the public methods of ExistingJComponent, except those of JComponent, to be exposed by my class MyJComponent. Then I want to add some public methods to MyJComponent.
Please note that I'm not looking for an alternative to the JCommandButtonStrip/JCheckBox example. I'm interested in a general approach to such a problem.
You can create a new class which extends JComponent then inside the constructor insert a checkbox into itself.
public class MyCoolCheckbox extends JComponent{
private JCheckBox checkbox;
public MyCoolCheckbox(String label) {
checkbox= new JCheckBox(label);
this.setLayout(new BorderLayout());
this.add(checkbox, BorderLayout.CENTER);
}
}
This is obviously incomplete and you may need to delegate certain methods to the child. It might get messy. IDEs like IntelliJ IDEA will generate all this for you if you hit alt-ins (by default) then delegate, then select the checkbox member and pick the entries you want to delegate. For example:
public void setForeground(Color fg) {
checkbox.setForeground(fg);
}
public void setBackground(Color bg) {
checkbox.setBackground(bg);
}
public Color getForeground() {
return checkbox.getForeground();
}
public Color getBackground() {
return checkbox.getBackground();
}
Keep in mind that because the child is within the Swing component tree, other code will have access to the children even though they are marked private.
((JCheckBox)myCoolCheckbox.getComponents()[0]).setSelected(true);
As shown here, you can use two instances of JToggleButton in a ButtonGroup to "show two buttons ON / OFF." The ButtonGroup causes only one button in the group to be selected at a time. The following change is illustrated:
private final JLabel label = new JLabel(" \u2713 ");
Based on this picture of JCommandButtonStrip:
I think you are looking for JToggleButton as #trashgod suggested, but I'm not sure about buttons group given the current description of your "problem". If you need buttons group then use it.
Anyway my answer points to this line:
This could be based on a pre-configured JCommandButtonStrip (some info
here) but exposing exactly the same API of JCheckBox.
Once again it's not clear if you're trying to do a buttons bar such as JCommandButtonStrip or you want to do something else. However you can make your own component extending from JComponent and delegate only those methods that are needed from the outside. For example let's say you want to do a buttons bar such as JCommandButtonStrip. Then you can have:
One class extending from JComponent: your buttons bar.
Another one providing an API to add "commands" to the buttons bar.
Note: There's already a JToolBar component which can perfectly be used without reinvent the wheel. The example below is just to show you that you can control the API offered to the developers.
MyCommandBar.java
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.event.ChangeListener;
public class MyCommandBar extends JComponent {
private final JPanel content;
private final Map<String, CommandItem> map = new HashMap<>();
public MyCommandBar() {
super();
content = new JPanel(new GridLayout(1, 0));
content.setOpaque(false);
setLayout(new FlowLayout());
add(content);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics graphics = g.create();
graphics.setColor(getBackground());
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.dispose();
}
public void addCommandItem(String actionCommand, CommandItem commandItem) {
if(map.get(actionCommand) != null) {
removeCommandItem(actionCommand);
}
content.add(commandItem.getComponent());
map.put(actionCommand, commandItem);
}
public void removeCommandItem(String actionCommand) {
CommandItem commandItem = map.get(actionCommand);
if(commandItem != null) {
content.remove(commandItem.getComponent());
content.revalidate();
content.repaint();
map.remove(actionCommand);
}
}
public CommandItem getCommandItem(String actionCommand) {
return map.get(actionCommand);
}
public static class CommandItem {
public static final int TOGGLE_BUTTON_STYLE = 0;
public static final int CHECK_BOX_STYLE = 1;
public static final int DEFAULT_BUTTON_STYLE = 2;
private final AbstractButton component;
public CommandItem(String text, boolean state, Icon icon, int style) {
switch(style) {
case TOGGLE_BUTTON_STYLE : component = new JToggleButton(text, icon, state); break;
case CHECK_BOX_STYLE : component = new JCheckBox(text, icon, state); break;
default: component = new JButton(text, icon);
}
}
protected AbstractButton getComponent() {
return component;
}
public void addActionListener(ActionListener listener) {
component.addActionListener(listener);
}
public void addChangeListener(ChangeListener listener) {
component.addChangeListener(listener);
}
public void setAction(Action action) {
component.setAction(action);
}
}
}
Example of use
This code snippet shows how MyCommandBar class should be used:
MyCommandBar commandBar = new MyCommandBar();
commandBar.setBorder(BorderFactory.createLineBorder(Color.black, 1));
commandBar.addCommandItem("BOLD", new MyCommandBar.CommandItem("<html><b>Bold</b></html>", true, null, MyCommandBar.CommandItem.TOGGLE_BUTTON_STYLE));
commandBar.addCommandItem("ITALICS", new MyCommandBar.CommandItem("<html><i>Italics</i></html>", false, null, MyCommandBar.CommandItem.CHECK_BOX_STYLE));
commandBar.addCommandItem("UNDERLINE", new MyCommandBar.CommandItem("<html><u>Underline</u></html>", false, null, MyCommandBar.CommandItem.DEFAULT_BUTTON_STYLE));
And you'll see something like this:
You can create MyJComponent subclass of JComponent with a private field that references a forwarding class for ExistingComponent.
The interactions with ExistingComponent are done with the forwarding class through methods of MyJComponent, and you are free to add more methods to MyJComponent.
Please see Effective Java item 16, for the delegation pattern used with the forwarding class.
Simple question – why wouldn't an object move if it's the object of .move() inside onMouseMoved()? I'm trying to write Breakout as part of the Stanford 106A exercises on iTunes U and for some reason I can't get the paddle to track the mouse. I'm a java noob, so I'm sure it's something really simple. Could someone please take a look at this code?
/** Runs the Breakout program. */
public void run() {
setupBoard();
addMouseListeners();
}
/** Provides the initial GCanvas and blocks for the game */
private void setupBoard(){
this.setSize(APPLICATION_WIDTH,APPLICATION_HEIGHT);
addBricks();
paddle = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT);
add(paddle, WIDTH/2-PADDLE_WIDTH/2,HEIGHT-PADDLE_Y_OFFSET);
}
public void MouseMoved(MouseEvent e){
paddle.move(e.getX()-paddle.getX(), 0);
}
private GRect paddle;
}
I'm not sure if having paddle be an instance variable is appropriate in this case, since its "value" doesn't change (the paddle's always the paddle), but if I just define it as a new GRect within setupBoard I get an error in the MouseMoved() method.
Your class that has the mouseMoved() method needs to implement the interface MouseMotionListener, and add the motion listener. Moreover, the event handler is mouseMoved() not MouseMoved(). So, e.g.:
public class Game extends JPanel implements MouseMotionListener {
public void run() {
addMouseMotionListener(this);
//...
}
public void mouseMoved(MouseEvent e) {
paddle.move(e.getX()-paddle.getX(), 0);
}
//...
};