如何在JPanel中仅在指定区域中重新录制鼠标?

时间:2021-07-31 21:18:19

I try to create a class that could added another JComponnent an create a clickable Settings-Icon in the Top-Right Corner.

我尝试创建一个可以添加另一个JComponnent的类,在右上角创建一个可点击的Settings-Icon。

I like to add some kind of ActionListener, that raises when the user click on the area of the g.drawImage(image, getWidth() - widgetSize, 0, widgetSize, widgetSize, imageObserver).

我想添加一些ActionListener,当用户点击g.drawImage(image,getWidth() - widgetSize,0,widgetSize,widgetSize,imageObserver)的区域时会引发它。

Is this the right way to solve this problem? Or are there better ways for that?

这是解决这个问题的正确方法吗?或者有更好的方法吗?

package de.display;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionListener;
import java.awt.image.ImageObserver;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class JWidget extends JPanel {

    private int widgetSize = 50;
    private boolean showWidgetIcon = true;

    Image image;
    ImageObserver imageObserver;

    public JWidget() {
        this(new ImageIcon("src/main/resources/Icon-Settings.png"));
    }

    public JWidget(String filename) {
        super();
        ImageIcon icon = new ImageIcon(filename);
        image = icon.getImage();
        imageObserver = icon.getImageObserver();
    }

    public JWidget(ImageIcon icon){
        super();
        image = icon.getImage();
        imageObserver = icon.getImageObserver();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        if(showWidgetIcon)
        {
            g.drawImage(image, getWidth() - widgetSize, 0, widgetSize, widgetSize, imageObserver);
        }
    }

    public int getWidgetSize() {
        return widgetSize;
    }

    public void setWidgetSize(int widgetSize) {
        this.widgetSize = widgetSize;
    }

    public void setImageIcon(ImageIcon icon) {
        image = icon.getImage();
        imageObserver = icon.getImageObserver();
    }

    public boolean isWidgetIconVisible() {
        return showWidgetIcon;
    }

    public void setShowWidgetVisibility(boolean showWidgetIcon) {
        this.showWidgetIcon = showWidgetIcon;
    }

    public void addPressSettingsActionListener(ActionListener actionListener)
    {
        listenerList.add(ActionListener.class, actionListener);
    }
}

1 个解决方案

#1


1  

Best way is to add a button with the given icon and no text (IMHO), which is placed at the given area of the panel. You can also set the border of the button to null (or EmptyBorder) if you only want to have the icon painted. For some L&F you also need to call the method AbstractButton.setContentAreaFilled(boolean) with parameter false. Method addActionListener can forward the call to the corresponded method of the enclosed button.

最好的方法是添加一个带有给定图标但没有文本(IMHO)的按钮,该按钮位于面板的给定区域。如果您只想绘制图标,也可以将按钮的边框设置为null(或EmptyBorder)。对于一些L&F,您还需要使用参数false调用AbstractButton.setContentAreaFilled(boolean)方法。方法addActionListener可以将调用转发到随附按钮的对应方法。

Here is my code

这是我的代码

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicButtonUI;

public class JWidget extends JPanel {

    private boolean showWidgetIcon = true;

    private BasicButton button = new BasicButton(null, 50);

    public JWidget() {
        this(new ImageIcon("src/main/resources/Icon-Settings.png"));
    }

    public JWidget(String filename) {
        super(new BorderLayout());

        ImageIcon icon = new ImageIcon(filename);
        button.setIcon(icon);
        initLayout();
    }

    public JWidget(ImageIcon icon) {
        super(new BorderLayout());
        button.setIcon(icon);
        initLayout();
    }

    private void initLayout() {
        removeAll();
        if (showWidgetIcon) {
            JPanel rightLayoutPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
            add(rightLayoutPanel, BorderLayout.NORTH);
            rightLayoutPanel.add(button);
        }
    }

    public int getWidgetSize() {
        return button.getButtonSize();
    }

    public void setWidgetSize(int widgetSize) {
        button.setButtonSize(widgetSize);
        revalidate();
        repaint();
    }

    public void setImageIcon(ImageIcon icon) {
        button.setIcon(icon);
    }

    public boolean isWidgetIconVisible() {
        return showWidgetIcon;
    }

    public void setShowWidgetVisibility(boolean showWidgetIcon) {
        this.showWidgetIcon = showWidgetIcon;
        initLayout();
    }

    public void addActionListener(ActionListener al) {
        button.addActionListener(al);
    }

    private static class BasicButton extends JButton {
        private int buttonSize;

        /**
         * 
         */
        public BasicButton(Icon anIcon, int aSize) {
            super(anIcon);
            buttonSize = aSize;
        }

        @Override
        public void updateUI() {
            setUI(new BasicButtonUI());
            setBorder(null);
            setContentAreaFilled(false);
        }

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

        public int getButtonSize() {
            return buttonSize;
        }

        public void setButtonSize(int size) {
            this.buttonSize = size;
        }
    }
}

#1


1  

Best way is to add a button with the given icon and no text (IMHO), which is placed at the given area of the panel. You can also set the border of the button to null (or EmptyBorder) if you only want to have the icon painted. For some L&F you also need to call the method AbstractButton.setContentAreaFilled(boolean) with parameter false. Method addActionListener can forward the call to the corresponded method of the enclosed button.

最好的方法是添加一个带有给定图标但没有文本(IMHO)的按钮,该按钮位于面板的给定区域。如果您只想绘制图标,也可以将按钮的边框设置为null(或EmptyBorder)。对于一些L&F,您还需要使用参数false调用AbstractButton.setContentAreaFilled(boolean)方法。方法addActionListener可以将调用转发到随附按钮的对应方法。

Here is my code

这是我的代码

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicButtonUI;

public class JWidget extends JPanel {

    private boolean showWidgetIcon = true;

    private BasicButton button = new BasicButton(null, 50);

    public JWidget() {
        this(new ImageIcon("src/main/resources/Icon-Settings.png"));
    }

    public JWidget(String filename) {
        super(new BorderLayout());

        ImageIcon icon = new ImageIcon(filename);
        button.setIcon(icon);
        initLayout();
    }

    public JWidget(ImageIcon icon) {
        super(new BorderLayout());
        button.setIcon(icon);
        initLayout();
    }

    private void initLayout() {
        removeAll();
        if (showWidgetIcon) {
            JPanel rightLayoutPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
            add(rightLayoutPanel, BorderLayout.NORTH);
            rightLayoutPanel.add(button);
        }
    }

    public int getWidgetSize() {
        return button.getButtonSize();
    }

    public void setWidgetSize(int widgetSize) {
        button.setButtonSize(widgetSize);
        revalidate();
        repaint();
    }

    public void setImageIcon(ImageIcon icon) {
        button.setIcon(icon);
    }

    public boolean isWidgetIconVisible() {
        return showWidgetIcon;
    }

    public void setShowWidgetVisibility(boolean showWidgetIcon) {
        this.showWidgetIcon = showWidgetIcon;
        initLayout();
    }

    public void addActionListener(ActionListener al) {
        button.addActionListener(al);
    }

    private static class BasicButton extends JButton {
        private int buttonSize;

        /**
         * 
         */
        public BasicButton(Icon anIcon, int aSize) {
            super(anIcon);
            buttonSize = aSize;
        }

        @Override
        public void updateUI() {
            setUI(new BasicButtonUI());
            setBorder(null);
            setContentAreaFilled(false);
        }

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

        public int getButtonSize() {
            return buttonSize;
        }

        public void setButtonSize(int size) {
            this.buttonSize = size;
        }
    }
}