5 Replies Latest reply: Oct 1, 2010 5:38 AM by 800268 RSS

    Drag and Drop disables Event Listeners?

    801952
      When a exportAsDrag() is called, all event listeners stop working until the drag is completed. Is there a way to get at least keylistener to work or catch the keyboard input somewhere?
      Here is a simple compilable program that creates a jframe with a jlabel inside. The label has a mouselistener, focuslistener, and keylistener.
      The mouselistener calls exportAsDrag from the mousedragged event, the focus listener changes the text color (focus = green, not focused = red). The keylistener changes the label text to the key pressed.
      Dnd works correctly: you can drag the label text to any program native, java ,ect... but i really want the keylistener to work WHILE dragging. If this is not possible why does dragging disable the event listeners or cause them not to function?
      import java.awt.Color;
      import java.awt.FlowLayout;
      import java.awt.event.FocusEvent;
      import java.awt.event.FocusListener;
      import java.awt.event.KeyAdapter;
      import java.awt.event.KeyEvent;
      import java.awt.event.MouseAdapter;
      import java.awt.event.MouseEvent;
      import javax.swing.JComponent;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.TransferHandler;
      
      public class Dnd extends JFrame {
          
          public static void main(String[] args) {
              new Dnd().setVisible(true);
          }
          JLabel dragLabel;
         public Dnd() {
             this.setTitle("Drag and drop");
              this.setSize(300,100);
              this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              this.setLayout(new FlowLayout());
              dragLabel = new JLabel("text to drag");
              dragLabel.setTransferHandler(new TransferHandler("text"));
              MouseAdapter ma = new MouseAdapter() {
                  @Override
                  public void mouseDragged(MouseEvent e) {
                      JComponent comp = (JComponent)e.getSource();
                      TransferHandler th = comp.getTransferHandler();
                      th.exportAsDrag(comp, e, TransferHandler.COPY);
                      super.mouseDragged(e);
                  }
              };
              dragLabel.addMouseMotionListener(ma);
              dragLabel.addKeyListener(new KeyAdapter() {
      
                  @Override
                  public void keyPressed(KeyEvent e) {
                      dragLabel.setText("Key pressed: "+e.getKeyText(e.getKeyCode()));
                  }
      
              });
              dragLabel.setFocusable(true);
              dragLabel.addFocusListener(new FocusListener() {
      
                  public void focusGained(FocusEvent e) {
                      dragLabel.setForeground(Color.GREEN);
                  }
      
                  public void focusLost(FocusEvent e) {
                      dragLabel.setForeground(Color.RED);
                  }
              });
              this.add(dragLabel);
          }
      }
      Edited by: 798949 on Sep 30, 2010 1:47 AM
        • 1. Re: Drag and Drop disables Event Listeners?
          DarrylBurke
          Moderator advice: Announcements at the top of the forum listing are there for a purpose. Please read the announcement and edit your post accordingly.

          db
          • 2. Re: Drag and Drop disables Event Listeners?
            800268
            Doesn't seem possible (at least not without creating a custom (platform dependent) Toolkit) as the no events are fired at all except for the drag related ones during a drag.

            What do you actually want to do? I tried Windows Explorer and only the F1 key seems to do anything during a drag.
            • 3. Re: Drag and Drop disables Event Listeners?
              801952
              The program I want to this to work with will have a graphical display in a window and a user should be able to drag components around the display as well as to other windows/displays/dialogs ect... The problem is that the graphical display is larger than the window so it is scrollable by using the arrow keys. I want the user to click&hold(drag) on a component and be able to scroll using the arrow keys and drop to a component that was offscreen when the drag initialed.
              I think a possible solution is to use a mouselistener to do the drag operations manually within the window, and on mouseexited call exportasdrag. However this might cause conflicting behavior if you drag a component off and back into the window so I would prefer only one implementation of dnd. I also noticed this behavior occurs is practically all applications: during a drag operations, key input is ignored...

              Edited by: 798949 on Sep 30, 2010 4:29 PM
              • 4. Re: Drag and Drop disables Event Listeners?
                DarrylBurke
                Cross posted an hour and a half ago
                http://www.java-forums.org/awt-swing/33031-drag-drop-disables-event-listeners.html#post146528

                db
                • 5. Re: Drag and Drop disables Event Listeners?
                  800268
                  Then you want to implement Scrollable for your component. A quick demo:
                  import java.awt.*;
                  import java.awt.datatransfer.DataFlavor;
                  import java.awt.event.MouseEvent;
                  
                  import javax.swing.*;
                  import javax.swing.event.MouseInputAdapter;
                  
                  public class TestDragScroll extends JPanel implements Scrollable {
                  
                      private final String text = "Drag me";
                      private Point location = new Point(100, 100);
                      protected boolean dragging;
                  
                      public TestDragScroll() {
                          setPreferredSize(new Dimension(1000, 1000));
                          setTransferHandler(new TransferHandler("text") {
                  
                              @Override
                              public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
                                  return true;
                              }
                  
                              @Override
                              public boolean importData(TransferSupport support) {
                                  if (support.isDrop()) {
                                      location = support.getDropLocation().getDropPoint();
                                      repaint();
                                      return true;
                                  }
                                  else {
                                      return false;
                                  }
                              }
                          });
                  
                          MouseInputAdapter listener = new MouseInputAdapter() {
                  
                              @Override
                              public void mouseDragged(MouseEvent e) {
                                  if (!dragging) {
                                      dragging = true;
                                      getTransferHandler().exportAsDrag(TestDragScroll.this, e, TransferHandler.COPY);
                                  }
                              }
                  
                              @Override
                              public void mouseReleased(MouseEvent e) {
                                  dragging = false;
                              }
                          };
                          addMouseListener(listener);
                          addMouseMotionListener(listener);
                      }
                  
                      public String getText() {
                          return text;
                      }
                  
                      @Override
                      protected void paintComponent(Graphics g) {
                          super.paintComponent(g);
                  
                          g.drawString(text, location.x, location.y);
                      }
                  
                      public Dimension getPreferredScrollableViewportSize() {
                          return new Dimension(250, 250);
                      }
                  
                      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
                          return 10;
                      }
                  
                      public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
                          return 100;
                      }
                  
                      public boolean getScrollableTracksViewportWidth() {
                          return false;
                      }
                  
                      public boolean getScrollableTracksViewportHeight() {
                          return false;
                      }
                  
                      public static void main(String[] args) {
                  
                          EventQueue.invokeLater(new Runnable() {
                  
                              public void run() {
                                  JFrame frame = new JFrame("Test");
                                  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                                  frame.getContentPane().add(new JScrollPane(new TestDragScroll()));
                                  frame.pack();
                                  frame.setLocationRelativeTo(null);
                                  frame.setVisible(true);
                              }
                          });
                      }
                  }