0

I am making a custom JFrame. I already have this layout, and it works completely fine:

enter image description here

The frame is undecorated, but I want to be able to move it around. I want my custom panel to be the moving grip for this, so what I did was add a MouseMotionListener to it. The mouseDragged function looks like this:

@Override
public void mouseDragged(MouseEvent e) {
    parent.setBounds(e.getX(), e.getY(), parent.getWidth(), parent.getHeight());

}

The parent field is set in the constructor and is final.

When I try to drag the frame with the panel, it works, but not quite right. The frame constantly flickers between two positions on the screen. I am able to move the frame, but it looks horrible. When I don't drag the frame, it doesn't flicker. The two positions are relative to each other, so if you move the frame, the other one moves along (but doesn't stay at the same distance from the other). Another problem is that the frame doesn't move well with the mouse. So, if you move the frame like 100 pixels in the x direction, the frame moves less pixels in the same direction.

How can you make a moving grip for a JFrame without this happening (and what is actually causing it to do this)?

If more code is required, just tell me.

cvbattum
  • 811
  • 2
  • 15
  • 32
  • Is your problem that you're trying to move the entire JFrame and it flickers? Or you're trying to move a component within the JFrame? Just making sure I understand this correctly. – Mdev Apr 12 '14 at 20:18
  • I am trying to move the whole frame. Sorry if this was unclear. – cvbattum Apr 12 '14 at 20:24
  • [For example](http://stackoverflow.com/questions/16869877/how-to-remove-window-box-from-any-java-gui/16869893#16869893) – MadProgrammer Apr 12 '14 at 20:57

2 Answers2

2

You need to provide a mousePressed also to get the initial point of the click. Then use that point to do some calculations.

Try something like this, where pX and pY are class fields (and assuming listeners are added in the panel constructor

addMouseListener(new MouseAdapter() {
    public void mousePressed(MouseEvent me) {
        // Get x,y and store them
        pX = me.getX();
        pY = me.getY();
    }
});
addMouseMotionListener(new MouseMotionAdapter() {
    public void mouseDragged(MouseEvent me) {
        parent.setLocation(parent.getLocation().x + me.getX() - pX, 
                parent.getLocation().y + me.getY() - pY);
    }
});

Here's a full example

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class UndecoratedExample {

    private JFrame frame = new JFrame();

    class MainPanel extends JPanel {

        public MainPanel() {
            setBackground(Color.gray);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }

    class BorderPanel extends JPanel {

        private JLabel label;
        int pX, pY;

        public BorderPanel() {
            label = new JLabel(" X ");
            label.setOpaque(true);
            label.setBackground(Color.RED);
            label.setForeground(Color.WHITE);

            setBackground(Color.black);
            setLayout(new FlowLayout(FlowLayout.RIGHT));

            add(label);

            label.addMouseListener(new MouseAdapter() {
                public void mouseReleased(MouseEvent e) {
                    System.exit(0);
                }
            });
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent me) {
                    // Get x,y and store them
                    pX = me.getX();
                    pY = me.getY();
                }
            });
            addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent me) {
                    frame.setLocation(frame.getLocation().x + me.getX() - pX,
                            frame.getLocation().y + me.getY() - pY);
                }
            });
        }
    }

    class OutsidePanel extends JPanel {

        public OutsidePanel() {
            setLayout(new BorderLayout());
            add(new MainPanel(), BorderLayout.CENTER);
            add(new BorderPanel(), BorderLayout.PAGE_START);
            setBorder(new LineBorder(Color.BLACK, 5));
        }
    }

    private void createAnsShowGui() {
        frame.setUndecorated(true);
        frame.add(new OutsidePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new UndecoratedExample().createAnsShowGui();
            }
        });
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I have a problem with the code. When I compiled and ran the code above, it works fine, but when I run my own code, which is pretty much copied from this, it first moves the window so that the cursor is in position (0,0) relative to the frame. Then I can move the frame without problem, but this is very annoying.. **EDIT:** Actually it looks more that the frame is moved so the cursor is in position (1,1) – cvbattum Apr 13 '14 at 13:36
  • You wanna post what you have? I'll check it out. I'm not sure what you mean. – Paul Samsotha Apr 13 '14 at 13:51
  • I have exactly what is in your code, except for the fact I'm using `Listeners` instead of `Adapters` – cvbattum Apr 13 '14 at 13:55
  • That doesn't help. Your just posting my code. If my code works, how am I supposed to know what it is about _your_ code that doesnt? – Paul Samsotha Apr 13 '14 at 13:55
  • In the mouseDragged method I have: parent.setLocation(parent.getLocation().x + e.getX() - px, parent.getLocation().y + e.getY() - py); – cvbattum Apr 13 '14 at 13:56
  • The possible explanation could be that the mousePressed method returns 0 for the coordinates – cvbattum Apr 13 '14 at 13:57
  • Did you use a `MouseListener` _and_ a `MouseMotionListener`? – Paul Samsotha Apr 13 '14 at 13:58
  • I tested it with debug and it came to me the mousePressed is never called. The `MouseListener` wasn't added as a listener... Thanks for the help. – cvbattum Apr 13 '14 at 13:58
  • putting the `mousePressed` in the `MouseMotionListener` won't override any functionality, that may be why it's never called, if that's what you did. You need a separate `MouseListener`. I used the `MouseAdapter` so you don't have to override all the methods. – Paul Samsotha Apr 13 '14 at 14:00
  • 1
    I didn't add it to the `JPanel` as a listener. – cvbattum Apr 13 '14 at 14:01
1

I want my custom panel to be the moving grip for this,

Check out Moving Windows which contains a class that will allow you to drag a window around the screen or any component around its parent container.

camickr
  • 321,443
  • 19
  • 166
  • 288