Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Перетаскивать окно за любую точку


Автор: snaker 18.4.2007, 00:02
Собсно столкнулся с проблемой... Надо реализовать возможность перетаскивать окно за любую его часть.. а точнее за JLabel с картинкой, который стоит на бэкграунде...

Вроде бы, все несложно реализовать.... но не знаю, как получить координаты курсора относительно экрана, а не компонента... smile  

 smile

Добавлено через 7 минут и 8 секунд
Сейчас это сделано вот так
Код

class H1 implements MouseListener{

        
        public void mouseReleased(MouseEvent arg0) {
            b=0;
            
        }
      
     }
     class H2 implements MouseMotionListener{

        public void mouseDragged(MouseEvent e) {
            JChat win=(JChat)(getRootPane().getParent());
            if (b>0)
            {
                
                Point p=win.getLocation();
                win.setLocation(p.x+win.getMousePosition().x-PrevPos.x,
                        p.y+win.getMousePosition().y-PrevPos.y);
                PrevPos.setLocation(win.getMousePosition());
                
            }
            else
            {
                PrevPos.setLocation(win.getMousePosition());
                b=1;
            }
            
        }

     }



Но окно перерисовывается довольно медленно и если двигать с нормальной скоростью, то курсор выходит за пределы окна.... В общем, не фиксируется на одной точке, при перетаскивании окна... 

Автор: nornad 18.4.2007, 00:54
Используй для определения сдвига предыдущую и текущую позицию курсора мышки: MouseEvent.getLocationOnScreen().
Если предыдущей нет, то просто запоминаешь текущую, как предыдущую и выходишь. Если есть - рисуешь окно и заменяешь предыдущую позицию текущей.

Автор: snaker 18.4.2007, 01:11
Не наблюдаю такого метода у MouseEvent-a smile 
Есть у компонента... возвращает его положение относительно экрана... 
Код

public Point getLocationOnScreen()
Gets the location of this component in the form of a point specifying the component's top-left corner in the screen's coordinate space. 

Returns:
an instance of Point representing the top-left corner of the component's bounds in the coordinate space of the screen 
Throws: 
IllegalComponentStateException - if the component is not showing on the screen
See Also:
setLocation(int, int), getLocation()


Автор: nornad 18.4.2007, 03:22
Я писал для JDK6. В предыдущих наличие метода не проверял. В принципе, разницы особой нет и вполне можно использовать метод получения координат относительно компонента - относительное перемещение в любом случае будет присутствовать.

Автор: snaker 18.4.2007, 09:19
Цитата(snaker @ 18.4.2007,  00:02)
Но окно перерисовывается довольно медленно и если двигать с нормальной скоростью, то курсор выходит за пределы окна.... В общем, не фиксируется на одной точке, при перетаскивании окна...

Вот из-за этого нужны абсолютные координаты...

Автор: snaker 19.4.2007, 10:00
Ну неужели нельзя получить коордынаты курсора на экране??? smile  неужели гуру этого не знают? smile 
Очень нужен ваш хэлп  smile 

Автор: powerOn 19.4.2007, 11:01
В JDK 6 абсолютную позицию курсора можно получить из обработчика "мышиного" события. Например:

Код

....
addMouseMotionListener(new java.awt.event.MouseMotionAdapter()
        {
            public void mouseDragged(java.awt.event.MouseEvent evt)
            {
                 int x = evt.getXOnScreen();
                 int y = evt.getYOnScreen();
            }
        });
....



Автор: snaker 19.4.2007, 12:33
Спасибо... Похоже придется-таки ставить 6-й JDK


З.Ы. Но это ведь не будет работать если jdk 1.5 стоИт? а надо бы :(

Автор: fixxer 19.4.2007, 12:57
Цитата

SwingUtilities.convertPointToScreen(Point p, Component c)
Convert a point from a component's coordinate system to screen coordinates.


Не спасет отца русской демократии?

Автор: snaker 19.4.2007, 13:26
не-а :(
потому как опять же определяется относительно компонента, который не перерисовался еще ))) вот такая хитрая хренька smile

Надо именно на манеторе! smile 

Хотя.. в принципе.. попробовать можно.. но резальтат, думаю, будет тот же smile

Всем спасибо за участие smile) Жду еще варианты smile

Автор: fixxer 24.4.2007, 14:03
Вот. Намыл в Swing Hacks

Цитата

Drag a window by clicking on its background using a special event listener.

Most windows let you move them by dragging the titlebar. Some program windows, however, don't have titlebars. In the age of eye-candy interfaces (see iTunes and WinAmp for prime examples) it is very common to have a windowpossibly non-rectangularwithout any titlebar or window controls at all. This makes for a pretty window, but how do you move it? Simply by dragging any available space on the window. Though not terribly intuitive, such programs are commonplace, and this book wouldn't be called Swing Hacks without providing a Java implementation of draggable windows, even when no titlebar is used.

The simplest approach to this problem is to create a listener that simply catches all drags and moves the window:
Код

            public class MoveMouseListener implements MouseListener, MouseMotionListener
            {
                JComponent target;
                JFrame frame;
                public MoveMouseListener(JComponent target, JFrame frame) {
                    this.target = target;
                    this.frame = frame;
                }
               
                public void mouseClicked(MouseEvent e) {}
                public void mouseEntered(MouseEvent e) {}
                public void mouseExited(MouseEvent e) {}
                public void mousePressed(MouseEvent e) {}
                public void mouseReleased(MouseEvent e) {}
                public void mouseMoved(MouseEvent e) {}
                public void mouseDragged(MouseEvent e) {
                    frame.setLocation(new Point(e.getX( ),e.getY( ));
                }
            }



This class implements MouseListener and MouseMotionListener with no-ops for all methods except mouseDragged( ), which moves the frame to the current mouse location. However, this approach has two problems. First, the mouse coordinates are going to be relative to the component, rather than the screen. Thus, a click on a 50 x 50 button in the bottom right of the screen might return (25, 25) when it should really be more like (1000, 700). The other problem is that the code moves the origin of the frame to the mouse cursor. This would look strange because the window would immediately jump so that its upper-left corner is right under the cursor. The proper behavior is for the window to stay in the same position relative to the cursor as the cursor moves around.

The solution to the first problem (getting screen coordinates rather than component coordinates) is to convert mouse coordinates to absolute screen coordinates. The following method does just that (we'll use this shortly in mouseDragged( )):
Код

         Point getScreenLocation(MouseEvent e) {
             Point cursor = e.getPoint( );
             Point target_location = this.target.getLocationOnScreen( );
             return new Point(

                 (int)(target_location.getX( )+cursor.getX( )),
                 (int)(target_location.getY( )+cursor.getY( )));
         }



Solving the second issue (keeping the window static relative to the mouse) requires saving an initial offset between window and cursor, and then maintaining that offset throughout the drag. You should add a new mousePressed( ) implementation that saves the current screen location of the mouse cursor (start_drag) and the current location of the window (start_loc). The distance between the two points can be used to form an offset:
Код

       Point start_drag;
       Point start_loc;
       public void mousePressed(MouseEvent e) {
           this.start_drag = this.getScreenLocation(e);
           this.start_loc = this.getFrame(this.target).getLocation( );
       }



Next, the listener should maintain the offset difference throughout the drag operation by calculating a new offset each time the mouse moves. Here is the new mouseDragged( ) method:
Код

          public void mouseDragged(MouseEvent e) {
              Point current = this.getScreenLocation(e);
              Point offset = new Point(
                  (int)current.getX( )-(int)start_drag.getX( ),
                  (int)current.getY( )-(int)start_drag.getY( ));
              JFrame frame = this.getFrame(target);
    Point new_location = new Point(
                  (int)(this.start_loc.getX( )+offset.getX( )),
                  (int)(this.start_loc.getY( )+offset.getY( )));
              frame.setLocation(new_location);
          }



Using the utility method, it gets the current mouse position in screen coordinates, and then calculates the distance between that position and where the mouse started. Finally, it adds this offset to the starting location for the window to set the window's final location.

Every now and then, the event queue will drop a mouse event. If the code was adding the deltas (change in position) from each drag event, then eventually the user would start to see errors as a result of these dropped events. Because this code always recalculates the window position relative to the start of the drag, these errors don't have an effect. Plus, since Swing sends all mouse events to a dragged componenteven if the cursor moves outside the bounds of the componentyou don't have to worry about the user dragging off the edge of the window and shutting down the whole process.

This method of window dragging has two strengths. First, since the work is done in a listener, you can add this listener to any existing Swing component without subclassing. Any old program can become draggable! Second, only drags on the attached component affect the windowyou can make the background of the window draggable without affecting any of the foreground components (like the Play button on an MP3 player).


Автор: snaker 24.4.2007, 19:56
Great thnx!!! работает гууут! smile  smile  smile 
Поставил бы плюсик, но постов не хватает! smile 

Автор: batigoal 24.4.2007, 20:56
Цитата(snaker @  24.4.2007,  20:56 Найти цитируемый пост)
Поставил бы плюсик, но постов не хватает! smile  

Поставим от твоего имени  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)