JPanel не получает события мыши на Mac - PullRequest
0 голосов
/ 10 июля 2019

У меня есть JPanel в JFrame. Я хочу, чтобы панель получала события мыши, но вместо этого они отправляются в JFrame при запуске в macOS. Я пытался запросить фокус, и это не помогло

SSCCE:

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

public class PanelInFrame extends JPanel {

    public PanelInFrame() {
        this.setPreferredSize(new Dimension(100, 100));
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("panel click!");
            }
        });
        this.setFocusable(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            PanelInFrame panel = new PanelInFrame();
            frame.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseReleased(MouseEvent e) {
                    System.out.println("frame click!");
                }
            });
            frame.setContentPane(panel);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
            frame.pack();
            frame.setVisible(true);
            panel.requestFocusInWindow();
        });
    }
}

Я хочу сообщить о «щелчке панели!». Когда я запускаю это на Mac (macOs 10.14.5, Java 11.0.2), я получаю только «щелчок по рамке», но в Linux я получаю «щелчок по панели»

В macOS:

mac $ javac PanelInFrame.java 
mac $ java PanelInFrame
frame click!
frame click!
frame click!
mac $ java --version
java 11.0.2 2019-01-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)
mac $ uname -a
Darwin gavin-mpb.lan 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64 i386 MacBookPro12,1 Darwin

В Linux:

linux $ javac PanelInFrame.java 
linux $ java PanelInFrame 
panel click!
panel click!
panel click!
linux $ java -version
java version "11.0.2" 2019-01-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)
linux $ uname -a
Linux hostname 4.15.0-50-generic #54-Ubuntu SMP Mon May 6 18:46:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

1 Ответ

1 голос
/ 10 июля 2019

но я не могу заставить его сфокусироваться, поэтому события мыши идут в кадр.

Фокус актуален только для KeyEvents.

То есть только компоненты с фокусом могут получать KeyEvents.

Фокус не имеет значения для MouseEvents. Когда вы нажимаете на компонент, Swing будет искать первый компонент в родительской / дочерней иерархии, чтобы найти компонент с помощью MouseListener.

Когда я запускаю ваш код, я вижу «щелчок панели», указывающий, что MouseEvent действительно идет на панель, а не на фрейм.

    this.setRequestFocusEnabled(true);
    this.requestFocusInWindow();
    this.requestFocus();
    this.grabFocus();

Также обратите внимание, что вы можете запросить фокус только на видимом реализованном компоненте, что в основном означает, что вы запрашиваете фокус ПОСЛЕ того, как упакуете () или используете setVisible (true) для фрейма.

Правильный метод для использования - это метод requestFocusInWindow().

Я не верю, что setRequestFocusEnabled(true) требуется для фокусировки на панели, только setFocusable(true).

Также обратите внимание, что все компоненты Swing должны быть созданы на Event Dispatch Thread (EDT). См. Frame Demo пример из учебного пособия по Swing по Как создать фреймы , чтобы улучшить структуру вашего класса и убедиться, что код выполняется на EDT.

Кроме того, pack() должно быть сделано просто как setVisible(...), чтобы методы вроде setRisizable (...) работали правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...