Yet abother silly newbie question...
I could simplify my project considerably if I could, under certain
conditions, pass mouse events from the child window that gets them
through to the parent window that contains the child window. The parent
is just better suited to handle the mouse events at certain times. I'm
sure this is possible, but I can't figure out how to do it.
(Example: for GUI customization a user might click a menu item that
disables all buttons. When disabled the buttons can be dragged and
dropped to different locations in the parent window. The parent, not
the button, needs to oversee the dragging and dropping, and so clicking
on the button doesn't activate the button, but passes the mouse message
to the parent which grabs it so it can be dragged around.)
Thanks
--gary
> Yet abother silly newbie question...
>
[quoted text clipped - 14 lines]
>
> --gary
If you're talking about what I think you're talking about, then you should
be able to register the mouseListener to the parent and then move around
via the MouseEvent.getSource()
I'd give you the code to do that, except that I'm still unsure whether or
not this would be easier with the AWT Drag 'n Drop...
fiziwig - 04 Aug 2006 04:34 GMT
> > Yet abother silly newbie question...
> >
[quoted text clipped - 3 lines]
> > is just better suited to handle the mouse events at certain times. I'm
> > sure this is possible, but I can't figure out how to do it.
<snip>
> If you're talking about what I think you're talking about, then you should
> be able to register the mouseListener to the parent and then move around
> via the MouseEvent.getSource()
>
> I'd give you the code to do that, except that I'm still unsure whether or
> not this would be easier with the AWT Drag 'n Drop...
I tried that first. The parent window never sees a mouse event if the
child window gets it first. The button swallows the mouse event. I can
drag and drop a JLabel that way, but not a child that is expecting
mouse events, like a JButton. The mouse events never reach the parent
in that case. I need to override the the mouse event listener in the
JButton and have it explicitly pass the mouse event to the parent.
That's a standard technique in C++/Windows, but I can't find how to do
it in Java. It's got to be possible though.
--gary
Sample compilable code:
I can drag the JLabel, but I can't drag the JButton, even when it is
disabled.
How do I get the mouse events to not be gobbled by the disabled
JButton?
OR How do I get the JButton to pass those mouse events to the parent
container?
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class DragSample extends JPanel
implements MouseListener, MouseMotionListener {
private JButton dragButton;
private JLabel label;
private JPanel parent;
private JComponent dragging = null;
private int mOffsetX, mOffsetY;
private boolean disabled = false;
public DragSample() {
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
JToolBar toolBar = buildToolbar();
add(toolBar);
parent = new JPanel();
add(parent);
parent.setBackground( Color.white);
parent.setPreferredSize(new Dimension(640, 480));
parent.addMouseMotionListener(this);
parent.addMouseListener(this);
// Create a button.
dragButton = new JButton("Drag Me");
parent.add(dragButton);
// Create JLabel
Border myBorder = BorderFactory.createLineBorder( Color.red );
label = new JLabel("Drag me");
label.setBounds(0, 100, 50, 50);
label.setBorder(myBorder);
parent.add(label);
}
private JToolBar buildToolbar() {
JToolBar toolBar = new JToolBar();
toolBar.setRollover( true );
toolBar.setFloatable( false );
JButton disableButton = new JButton("Disable");
disableButton.setToolTipText( "Disable 'Drag Me' Button" );
disableButton.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
disabled = true;
dragButton.setEnabled(false);
}
});
toolBar.add( disableButton );
return toolBar;
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the window.
JFrame frame = new JFrame("DragSample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new DragSample();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
//
============================================================================
// Mouse and Mouse motion event handlers
public void mouseDragged(MouseEvent e) {
if ( dragging!=null ) {
int newY = e.getY() - mOffsetY;
int newX = e.getX() - mOffsetX;
dragging.setLocation(newX, newY);
}
}
public void mouseMoved(MouseEvent e) {} //do nothing
public void mouseExited(MouseEvent e) {} // do nothing
public void mouseEntered(MouseEvent e) {} // do nothing
public void mouseClicked(MouseEvent e) {} // do nothing
public void mousePressed(MouseEvent e) {
int cx = e.getX();
int cy = e.getY();
System.out.println("MousePressed event");
// Find which component, if any, the mouse is over
int lx, ty, rx, by;
lx = label.getX();
rx = lx + label.getWidth();
if ((cx>=lx) && (cx<=rx)) {
ty = label.getY();
by = ty + label.getHeight();
if ((cy>=ty) && (cy<=by)) {
dragging = label;
}
}
lx = dragButton.getX();
rx = lx + dragButton.getWidth();
if ((cx>=lx) && (cx<=rx)) {
ty = dragButton.getY();
by = ty + dragButton.getHeight();
if ((cy>=ty) && (cy<=by)) {
dragging = dragButton;
}
}
if ( dragging != null ) {
lx = dragging.getX();
ty = dragging.getY();
rx = lx + dragging.getWidth();
by = ty + dragging.getHeight();
if ((cx>=lx) && (cx<=rx) && (cy>=ty) && (cy<=by)) {
mOffsetX = cx - lx; // offset from mouse pointer to loc
mOffsetY = cy - ty; // of region
}
}
}
public void mouseReleased(MouseEvent e) {
dragging = null;
}
}
fiziwig - 04 Aug 2006 22:08 GMT
If anyone is curious, here's how I finally figured out to make it work.
This change allows you to drag and drop a button (or any other
Component) anywhere in the parent window with the mouse. Notice that
when the mouse event is passed to the parent the x,y coordinates need
to be transformed from relative to the button to relative to the
parent.
In the code above replace the three lines:
--------------
// Create a button.
dragButton = new JButton("Drag Me");
parent.add(dragButton);
-------------
With:
-------------
// Create a button.
dragButton = new JButton("Drag Me");
dragButton.addMouseListener( new MouseListener() {
public void mousePressed(MouseEvent e) {
if ( disabled ) {
int newX = e.getX() + dragButton.getX();
int newY = e.getY() + dragButton.getY();
MouseEvent transformed =
new MouseEvent(dragButton,
MouseEvent.MOUSE_PRESSED, e.getWhen(),
0, newX, newY, e.getClickCount(), false,
e.getButton());
parent.dispatchEvent( transformed );
}
}
public void mouseReleased(MouseEvent e) {
if ( disabled ) {
int newX = e.getX() + dragButton.getX();
int newY = e.getY() + dragButton.getY();
MouseEvent transformed =
new MouseEvent(dragButton,
MouseEvent.MOUSE_RELEASED, e.getWhen(),
0, newX, newY, e.getClickCount(), false,
e.getButton());
parent.dispatchEvent( transformed );
}
}
public void mouseExited(MouseEvent e) {} // do nothing
public void mouseEntered(MouseEvent e) {} // do nothing
public void mouseClicked(MouseEvent e) {} // do nothing
});
dragButton.addMouseMotionListener( new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
if ( disabled ) {
int newX = e.getX() + dragButton.getX();
int newY = e.getY() + dragButton.getY();
MouseEvent transformed =
new MouseEvent(dragButton,
MouseEvent.MOUSE_DRAGGED, e.getWhen(),
0, newX, newY, e.getClickCount(), false,
e.getButton());
parent.dispatchEvent( transformed );
}
}
public void mouseMoved(MouseEvent e) {} //do nothing
});
parent.add(dragButton);
---------------
--gary