Компонент Paint, по-видимому, приводит к тому, что курсор и Mouse Listener of Label не работают - PullRequest
0 голосов
/ 13 февраля 2019

Использование LayerUI для добавления меток в верхний угол панели с вкладками.Хотелось бы, чтобы эти метки отображались как гиперссылки, поэтому я установил синий цвет, курсор на руку и добавил mouselistener.

Однако, когда я рисую компонент, настройки курсора и прослушиватель мыши не работают.

пример изображения

enter image description here

Пример приложения:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JLayer;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.LayerUI;

public class TopRightCornerLabelLayerUITest {
    public static JPanel makeUI() {
        JPanel resultPanel = new JPanel();
        resultPanel.setLayout( new BorderLayout());
        resultPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.add("Tab 1", new JPanel());  
        tabbedPane.add("Tab 2", new JPanel());  

        resultPanel.add(new JLayer<JComponent>(tabbedPane, new TopRightCornerLabelLayerUI()), BorderLayout.CENTER);

        return resultPanel;
    }

    private static void initandShow()
    {
        JDialog dialog = new JDialog();
        dialog.getContentPane().add(makeUI());
        dialog.setSize(520, 240);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                initandShow();
            }
        });

    }
}

class TopRightCornerLabelLayerUI extends LayerUI<JComponent> {
    private JPanel rubberStamp = new JPanel();

    @Override public void paint(Graphics g, JComponent c) {
        super.paint(g, c);

        JLabel layoutHyperlink = new JLabel("<html><a href=''>File Layout and Descriptions</a></html>");
        JLabel templateHyperlink = new JLabel("<html><a href=''>Download Template</a></html>");

        layoutHyperlink.setForeground(Color.BLUE.darker());
        layoutHyperlink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        layoutHyperlink.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // the user clicks on the label
                System.err.println("clicked");
            }
       });

        templateHyperlink.setForeground(Color.BLUE.darker());
        templateHyperlink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        templateHyperlink.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // the user clicks on the label
                System.err.println("clicked");

            }
       });

        // Add components
        Dimension templateDimension = templateHyperlink.getPreferredSize();
        int x = c.getWidth() - templateDimension.width - 5;
        SwingUtilities.paintComponent(g, templateHyperlink, rubberStamp, x, 2, templateDimension.width , templateDimension.height);

        Dimension layoutDimension = layoutHyperlink.getPreferredSize();
        x = c.getWidth() - layoutDimension.width - 15 - templateDimension.width;
        SwingUtilities.paintComponent(g, layoutHyperlink, rubberStamp, x, 2, layoutDimension.width, templateDimension.height);

    }
}

1 Ответ

0 голосов
/ 13 февраля 2019

Я фактически не знал о классе JLayer, пока не прочитал твой вопрос.У меня нет полного ответа, но я думаю, что этого достаточно, чтобы подтолкнуть вас в правильном направлении.Мне помог урок из урока Oracle по Java: Как декорировать компоненты с помощью класса JLayer .На этом уроке есть раздел под названием Ответ на событие , который помог мне выяснить, как частично решить вашу проблему.По сути, вы просто рисуете метки, а не добавляете их как компоненты, и поэтому они не будут реагировать на события мыши.Поскольку метки можно считать частью JLayer компонента, который добавляется как компонент, вы можете настроить JLayer для реагирования на события мыши.Как указано в уроке, вам необходимо переопределить некоторые другие методы в вашем классе TopRightCornerLabelLayerUI.Код ниже содержит два из этих методов.Добавьте их в свой код и посмотрите, дают ли они ожидаемый результат.

public void installUI(JComponent c) {
    super.installUI(c);
    ((JLayer<?>) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
}

protected void processMouseEvent(MouseEvent e, JLayer l) {
    if (e.getID() == MouseEvent.MOUSE_CLICKED) {
        Point pt = e.getPoint();
        if (pt.x >= xTemplateHyperlink  &&  pt.x <= (xTemplateHyperlink + widthTemplateHyperlink)) {
            System.out.println("clicked");
        }
    }
}

РЕДАКТИРОВАТЬ: Забыл упомянуть, что я добавил следующих членов в ваш TopRightCornerLabelLayerUI класс ...

private int xTemplateHyperlink;
private int yTemplateHyperlink;
private int widthTemplateHyperlink;
private int heightTemplateHyperlink;

И установить их значения в методе paint() примерно так ...

Dimension templateDimension = templateHyperlink.getPreferredSize();
xTemplateHyperlink = c.getWidth() - templateDimension.width - 5;
yTemplateHyperlink = 2;
widthTemplateHyperlink = templateDimension.width;
heightTemplateHyperlink = templateDimension.height;

, что объясняет код в методе processMouseEvent().

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