public class cPan extends JPanel implements ActionListener{
#Override
public void actionPerformed(ActionEvent arg0) {
}
}
I have the above code which catches actions from within my JPanel.
Im confused about how i would get an x,y cordinate from within my JPanel e.g. where i click
So if i click on 100,200 (x,y) i would like to be able to see this.
I've look the function givens from arg0 but cant find anything useful.
Where am i going wrong?
Use a MouseListener instead. This way, you'll get a MouseEvent, from which you can get the clicked point by calling MouseEvent#getPoint().
public class cPan extends JPanel implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
// or
int x = e.getX();
int y = e.getY();
}
}
public class cPan extends JPanel implements ActionListener{
should be
public class cPan extends JPanel implements MouseListener{
more in Oracle turorial How to Write a Mouse Listener and with compare with wrong listener How to Write an Action Listener for MouseEvents
You need to add mouse listener:
JPanel panel = new JPanel ();
panel.setPreferredSize (new Dimension (640, 480));
panel.addMouseListener (new MouseAdapter() {
#Override
public void mouseClicked (MouseEvent e) {
JOptionPane.showMessageDialog(
e.getComponent (), "X: " + e.getX () + ", Y: " + e.getY ());
}
});
JFrame frame = new JFrame ("Click");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane ().setLayout (new BorderLayout ());
frame.getContentPane ().add (panel, BorderLayout.CENTER);
frame.pack ();
frame.setVisible (true);
ActionListener is used to notify you when, well, some kind of nondescript action has occurred.
There is no way to extract information about what caused the action (like mouse click or key action)
To get information about mouse events, you need to use a MouseListener attached to the component(s) you are interested in monitoring.
Check out How to use Mouse Listeners for more information
Related
I'm new to java and working on a GUI assignment and I'm running into some issues. The premise is a simple GUI window that has a few mouse events and a few keyboard events.
I put together a window with some mouse events and once that was working started to add a couple JTextFields to the window but they're not showing up on the window and I'm not exactly sure why.
Here is the problem now. I created a new panel (panel2) to add the JTextFields to the window and I now see the JTextFields but it overtakes the entire window and the Mouse Events do not work with it. If I add the JTF to the panel above the Mouse Events then the JTF do not show up and the Mouse Events work.......
code
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class EventDemo extends JFrame {
private JPanel mousePanel;
private JPanel panel1;
private JPanel panel2;
private JPanel panel3;
private JLabel statusBar;
private JLabel directions1;
private JLabel directions2;
private JLabel directions3;
private JTextField textField1;
private JTextField textField2;
public EventDemo() {
super("EVENT DEMO PROGRAM");
panel1 = new JPanel();
panel2 = new JPanel();
//Add directions for the events to top of the window.
directions1 = new JLabel("Enter & Leave window." +
" Press & hold, release, drag, move cursor to display a message in statusbar." +
" Clicking in one spot will display coordinates.");
panel1.add(directions1);
add(panel1, BorderLayout.PAGE_START);
//Add mouse and statusBar to panel.
mousePanel = new JPanel();
mousePanel.setBackground(Color.WHITE);
add(mousePanel, BorderLayout.CENTER);
statusBar = new JLabel("Default");
add(statusBar, BorderLayout.SOUTH);
//Create handler object for Mouse events
TheHandler handler = new TheHandler();
mousePanel.addMouseListener(handler);
mousePanel.addMouseMotionListener(handler);
textField1 = new JTextField(10);
panel2.add(textField1, BorderLayout.SOUTH);
textField2 = new JTextField("Enter Text Here");
panel2.add(textField2, BorderLayout.SOUTH);
add(panel2);
TheHandler handlerJTF = new TheHandler();
textField1.addActionListener(handlerJTF);
textField2.addActionListener(handlerJTF);
}
private class TheHandler implements MouseListener, MouseMotionListener {
public void mouseClicked(MouseEvent event) {
statusBar.setText(String.format("YOU CLICKED THE MOUSE AT %d, %d", event.getX(), event.getY()));
}
public void mousePressed(MouseEvent event) {
statusBar.setText("YOU HAVE PRESSED THE MOUSE BUTTON.");
}
public void mouseReleased(MouseEvent event) {
statusBar.setText("YOU HAVE RELEASED THE MOUSE BUTTON.");
}
public void mouseEntered(MouseEvent event) {
statusBar.setText("YOU HAVE ENTERED THE WINDOW THE BACKGROUND CHANGES TO RED.");
mousePanel.setBackground(Color.RED);
}
public void mouseExited(MouseEvent event) {
statusBar.setText("EXITING THE WINDOW, BACKGROUND CHANGES BACK TO WHITE.");
mousePanel.setBackground(Color.WHITE);
}
//Mouse Motion events.
public void mouseDragged(MouseEvent event) {
statusBar.setText("YOU ARE DRAGGING THE MOUSE.");
}
public void mouseMoved(MouseEvent event) {
statusBar.setText("YOU ARE MOVING THE MOUSE AROUND.");
}
}
public void actionPerformed(ActionEvent event) {
textField1.getText();
textField2.getText();
}
public static void main(String[] args) {
EventDemo go = new EventDemo();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(960, 300);
go.setVisible(true);
new EventDemo();
}
}
TheHandler does not implement ActionListener which is the required type of JTextField#addActionListener. See How to Write an Action Listeners and How to Use Text Fields for more details
Your actionPerformed method isn't actually defined in TheHandler class, but is a method of the EventDemo class
You should use the #Override annotation when you think you're overriding methods (or implementing methods from an interface) as this will cause a compiler error when you're wrong (for some reason)
Your fields aren't appearing for two reasons, first, textField is added to panel2 which is never added to anything and textField2 is been added to the frame (at the default position of BorderLayout.CENTER), but is been overriden/circumvented by add(mousePanel, BorderLayout.CENTER);, so it's actually never laid out by the frames BorderLayout. Have a look at How to Use Borders for more details
I have Java Swing application ToolTipMouseTest
The critical line is label.setToolTipText("label" + i);. Once it is commented out very click on a label produces 2 mousePressed in console. With this line enabled click on labels would produce nothing.
Is this expected behaviour or a bug? My goal is to show tooltips without disabling MouseListener from working.
Almost SSCCE, but without imports:
public class ToolTipMouseTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ToolTipMouseTest();
}
});
}
public ToolTipMouseTest() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
JLayeredPane lpane = new JLayeredPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(600,400);
}
};
MouseAdapter1 mouseAdapter1 = new MouseAdapter1();
lpane.addMouseListener(mouseAdapter1);
frame.add(lpane);
JPanel panel1 = new JPanel();
panel1.setSize(new Dimension(600, 400));
panel1.setOpaque(false);
lpane.add(panel1, JLayeredPane.PALETTE_LAYER);
JPanel panel2 = new JPanel();
for (int i = 0; i < 5; i++) {
JLabel label = new JLabel("Label " + i);
panel2.add(label);
label.setToolTipText("label" + i); //HERE!!
}
JScrollPane spane = new JScrollPane(panel2) {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
};
MouseAdapter2 mouseAdapter2 = new MouseAdapter2();
spane.addMouseListener(mouseAdapter2);
panel1.add(spane);
frame.pack();
frame.setVisible(true);
}
private class MouseAdapter1 extends MouseAdapter {
#Override
public void mousePressed (MouseEvent me) {
System.out.println("1 mousePressed");
}
}
private class MouseAdapter2 extends MouseAdapter {
#Override
public void mousePressed (MouseEvent me) {
System.out.println("2 mousePressed");
}
}
}
It is working as intended. Let me explain why.
When a component has no listener, the mouse events will be propagated.
When any component has at least one MouseListener set on it - it will consume any mouse enter/exit/click/press/release events from going down in the components hierarchy.
It's the same for any listener such as MouseMotionListener with
mouse dragged/moved.
When you are adding a tooltip to a component (JLabel in your case), the component automatically receive a new MouseListener and a MouseMotionListener from ToolTipManager. The registerComponent method from ToolTipManager class do this (it's invoked by setToolTipText) :
public void registerComponent(JComponent component) {
component.removeMouseListener(this);
component.addMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener);
component.addMouseMotionListener(moveBeforeEnterListener);
component.removeKeyListener(accessibilityKeyListener);
component.addKeyListener(accessibilityKeyListener);
}
In your case - JLabels are consuming mouse events and mouse motion events, and as such prevents from propagating the events to the JLayeredPane because ToolTipManager listener added itself when the tooltip is set (setToolTipText) on the component.
In order to work around this, register a listener that will pass events down. You can add that listener to every component with a tooltip that should pass mouse events down (e.g to a JLayeredPane, a JScrollPane, etc).
Here is a small example of how that could be done:
var destinationComponent = // the JLayeredPane, JScrollPane, etc with mouse listeners
componentWithToolTip.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
destinationComponent.dispatchEvent(
SwingUtilities.convertMouseEvent(
event.getComponent(), // the component with the tooltip
event,
destinationComponent
)
);
}
// implements other mouse* handlers as required.
});
In that setup componentWithToolTip will have 2 listeners, the one from the ToolTipManager and the propagating one. When componentWithToolTip all its listeners will be triggered, and the propagating listener will dispatch to the declared destination component destinationComponent. So that destinationComponent listeners receive the mouse events as well.
I am designing the graphics for a game i am programming, i wanted to know if there is an easy way of opening a frame when a JLabel is cliked?
Is there easy code for this?
Implement MouseListener interface and use it mouseClicked method to handle the clicks on the JLabel.
label.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
// you can open a new frame here as
// i have assumed you have declared "frame" as instance variable
frame = new JFrame("new frame");
frame.setVisible(true);
}
});
create a label and add click event in it .
Something like this :
JLabel click=new JLabel("Click me");
click.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
JFrame jf=new JFrame("new one");
jf.setBackground(Color.BLACK);
jf.setSize(new Dimension(200,70));
jf.setVisible(true);
jf.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
});
don't to create a new JFrame, never bunch of JFrames, have to calculating with OutOfMemoryException, because this Object never will be GC'ed,
for multiple of views to use CardLayout
see answer The Use of Multiple JFrames, Good/Bad Practice? by #Andrew Thompson
You could do that like this:
label.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e)
{
JPanel j = new JPanel();
frame.setContentPane(j);
}
});
1:- Implement your class containing the JLabel with MouseListener interface
2:- add MouseListener to your JLabel
3:-Override mouseClicked Event in your class
4:- In mouseClicked Even't body add your code to open a new JFrame/Frame .
I'm supposed to program a GUI. Every component in this GUI has to have the possibility to be resized dynamically.
So far I worked with GlassPane and ContentPane, added a JPanel and on it a button. When clicking the GlassPane gets the event, analyses the underlying component, creates a new handle for this special component and handles it over to the said component.
I added a button that should change its size automatically. Works like I wanted it to work.
BUT: When I change the size of the frame and click on the button now, nothing happens. The GlassPane is able to identify the button, but something seems to be wrong...
Here's the code for the interception of GlassPane and giving the event to the component:
private void resendEvent(MouseEvent e) {
//Point p = SwingUtilities.convertPoint(content.getGlassPane(), e.getPoint(), content.getContentPane());
Point p = e.getPoint();
Component component = SwingUtilities.getDeepestComponentAt(content.getContentPane(), p.x, p.y);
System.out.println(component.toString());
Point p2 = component.getLocation();
MouseEvent event = new MouseEvent(component, e.getID(), e.getWhen(), e.getModifiers(), p2.x, p2.y, e.getClickCount(), e.isPopupTrigger());
//following lines have the same effects
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
//component.dispatchEvent(event);
}
Thanks for your help/suggestions
Okay, here's some more Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import resize.ResizablePanel;
public class ExampleProblem extends JFrame {
public ExampleProblem () {
JPanel glassPane = new JPanel();
glassPane.setOpaque(false);
glassPane.addMouseListener(new MouseAdapter(){
#Override
public void mousePressed(MouseEvent e) {
resendEvent(e);
}
#Override
public void mouseReleased(MouseEvent e) {
resendEvent(e);
}
});
this.setGlassPane(glassPane);
glassPane.setVisible(true);
JButton b = new JButton("Test");
b.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Button clicked");
}});
JPanel p = new JPanel();
p.add(b);
setContentPane(p);
pack();
setVisible(true);
}
private void resendEvent(MouseEvent e) {//Point p = SwingUtilities.convertPoint(content.getGlassPane(), e.getPoint(), content.getContentPane());
Point p = e.getPoint();
Component component = SwingUtilities.getDeepestComponentAt(this.getContentPane(), p.x, p.y);
System.out.println(component.toString());
Point p2 = component.getLocation();
MouseEvent event = new MouseEvent(component, e.getID(), e.getWhen(), e.getModifiers(), p2.x, p2.y, e.getClickCount(), e.isPopupTrigger());
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);
}
public static void main(String[] args) {
new ExampleProblem();
}
}
Hope, the problem is a bit clearer now.
Is it possible, that I shouldn't have used setContentPane()? But we had to overwrite the JContentPane for resizing the components on it...
You have to determine the component point from your coordinate. Use this instead of p2 to to create the event:
Point p2 = SwingUtilities.convertPoint(this.getGlassPane(), p, component);
You might be able to use the Component Resizer. It would need to be added to all components in advance.
Or maybe you could add the listener when you select the component and then remove the listener when you deselect the component.
The code you posted is of little help when guessing what your actual program is doing. When you have problems with your code you need to post a SSCCE.
I'd like to ask another question how to handle Windows' events in Java. To be specific, I'd like to know how to handle events such as mouse moved or mouse clicked in Windows XP and Vista. I want to wire my own custom behavior in my application to these events, even when my application is inactive or otherwise hidden.
All help is appreciated!
you can add e.g. a MouseListener to any JComponent by calling
addMouseListener()
There are different EventListeners which you can use instead of MouseListeners
KeyListener
WindowListener
ComponentListener
ContainerListener
FocusListener
...and many more
Check here for an detailed explanation
you can implement the MouseListener Interface completely or just use the convienience class MouseAdapter, which has method stubs, so you dont have to implement every single method.
check this sample:
public class MyFrame extends JFrame {
private MouseListener myMouseListener;
public MyFrame() {
this.setSize(300, 200);
this.setLocationRelativeTo(null);
// create the MouseListener...
myMouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("clicked button " + e.getButton() + " on " + e.getX() + "x" + e.getY()); // this gets called when the mouse is clicked.
}
};
// register the MouseListener with this JFrame
this.addMouseListener(myMouseListener);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyFrame frame=new MyFrame();
frame.setVisible(true);
}
});
}
}