Ryan
Ryan

Reputation: 747

JPanel losing focus and listeners aren't firing

So in my window, I set the JFrame to undecorated(true) and have my own custom header at the top (with closing and minimizing buttons). The only problem I'm having is making the window move when you drag this 'custom header'. The entire header is in a JPanel which is then added to the JFrame on the North side (BorderLayout.NORTH). I have a MouseListener and MouseMotionListener added to this JPanel, but it does not recognize any events. The only thing I can assume is how I have the layout figured out. Below is the code for the header, along with a visual to go along with it.

CODE:

private void addHeader()
{
    headPane = new JPanel();
    headPane.setLayout(new BoxLayout(headPane, BoxLayout.LINE_AXIS));
    buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 2));
    buttonPane.setBackground(mouseLineColor);
    headPane.setBackground(Color.GREEN);

    Font buttonFont = new Font("", Font.PLAIN, 18);
    minimize.setFocusable(false);
    minimize.setPreferredSize(new Dimension(30, 20));
    minimize.setMargin(new Insets(0, 0, 0, 0));
    minimize.setOpaque(false);
    minimize.setBorder(null);
    minimize.setForeground(Color.WHITE);
    minimize.setOpaque(true);
    minimize.setFont(buttonFont);
    minimize.setBackground(buttonColor);

    quit.setFocusable(false);
    quit.setPreferredSize(new Dimension(30, 20));
    quit.setMargin(new Insets(0, 0, 0, 0));
    quit.setOpaque(false);
    quit.setBorder(null);
    quit.setForeground(Color.WHITE);
    quit.setOpaque(true);
    quit.setFont(buttonFont);
    quit.setBackground(buttonColor);

    back.setFocusable(false);
    back.setPreferredSize(new Dimension(30, 20));
    back.setMargin(new Insets(0, 0, 0, 0));
    back.setOpaque(false);
    back.setBorder(null);
    back.setForeground(Color.WHITE);
    back.setOpaque(true);
    back.setFont(buttonFont);
    back.setBackground(buttonColor);

    if(screen != GAME_MENU)
        buttonPane.add(back);
    else
        buttonPane.remove(back);

    buttonPane.add(minimize);
    buttonPane.add(quit);

    headTitle = new JLabel("Bouncy Ball Version " + VERSION);
    headTitle.setBorder(new EmptyBorder(0, 5, 0, 0));
    headTitle.setFont(new Font("", Font.BOLD, 14));
    headTitle.setForeground(Color.BLACK);
    headTitle.setBackground(Color.YELLOW);
    headTitle.setOpaque(true);
    headTitle.setFocusable(false);
    headPane.setFocusable(false);
    buttonPane.setFocusable(false);

    buttonPane.setBackground(Color.RED);

    headPane.add(headTitle);
    headPane.add(Box.createHorizontalGlue());
    headPane.add(buttonPane);

    if(callOnce)
    {
        minimize.addActionListener(this);
        quit.addActionListener(this);
        back.addActionListener(this);

        minimize.addMouseListener(this);
        quit.addMouseListener(this);
        back.addMouseListener(this);

        headPane.addMouseListener(this);
        headPane.addMouseMotionListener(this);

        callOnce = false;
    }

    headPane.setPreferredSize(new Dimension(headPane.getPreferredSize().width, 24));
    frame.add(headPane, BorderLayout.NORTH);
}

LISTENERS:

MousePressed:

Object source = e.getSource();
if(source == headPane)
{
    mouseX = e.getX();
    mouseY = e.getY();
    movingWindow = true;
}

MouseDragged:

Object source = e.getSource();
if(source == headPane)
{
    if(movingWindow)
    {
        int x = e.getXOnScreen();
        int y = e.getYOnScreen();
        frame.setLocation(x - mouseX, y - mouseY);
    }
}

enter image description here

I'll also add that when I click on the headPane, the JButtons will cease to work as well. I don't know why it's doing this, or if the answer is really simple and I'm just being stupid, but nothing I have tried has worked.

I'm fairly new to Java so thanks in advance for any help.

Upvotes: 0

Views: 71

Answers (1)

camickr
camickr

Reputation: 324207

I see no need for the "callOnce" variable. The frame and the components added to the frame should only be created once when the class is created. If you are calling the "addHeader()" method more than once, then I suggest you have a design problem.

Also you should not be adding the ActionListeners to your buttons twice.

The only problem I'm having is making the window move when you drag this 'custom header'.

Check out Moving Windows for a general purpose class that allows you to drag any component. Typically you would drag a component within a panel.

However, the class also has a feature that allows you to drag a window on the desktop by dragging a component added to the window.

Upvotes: 2

Related Questions