Java 在JPanel中检测鼠标点击并防止在JPanel中绘制圆圈时出现问题

Java 在JPanel中检测鼠标点击并防止在JPanel中绘制圆圈时出现问题,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我当前的程序允许用户在JFrame周围移动一个圆圈,并通过按JFrame底部JPanel中显示的颜色之一来更改其颜色 我的代码: import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; import javax.swing.border.Border; import javax.swing.BorderFactory; import java.awt.event.MouseEvent;

我当前的程序允许用户在JFrame周围移动一个圆圈,并通过按JFrame底部JPanel中显示的颜色之一来更改其颜色

我的代码:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.border.Border;
import javax.swing.BorderFactory;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.FlowLayout;
import java.awt.BorderLayout;
import java.awt.GridLayout;

public class SixthProgram
{
    public static void main(String[] args)
    {
        GUI prog=new GUI("SixthProgram");
        prog.setBounds(350,250,500,250);
        prog.setVisible(true);
    }
}

class GUI extends JFrame implements MouseListener, MouseMotionListener
{
    JButton button;
    JPanel colorPan, color1, color2, color3 ,color4 ,color5;
    Color color=Color.BLACK;

    int x=3,y=30;

    public GUI(String header)
    {
        super(header);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        maker();

        addMouseListener(this);
        addMouseMotionListener(this);

        add(colorPan, BorderLayout.SOUTH);
    }

    public void maker()
    {
        colorPan = new JPanel();

        Border raisedbevel = BorderFactory.createRaisedBevelBorder();
        Border loweredbevel = BorderFactory.createLoweredBevelBorder();
        Border compound = BorderFactory.createCompoundBorder(raisedbevel, loweredbevel);
        colorPan.setBorder(compound);

        colorPan.setLayout(new GridLayout(1, 0));

        color1 = new JPanel();
        color2 = new JPanel();
        color3 = new JPanel();
        color4 = new JPanel();
        color5 = new JPanel();

        color1.setBackground(Color.WHITE);
        color2.setBackground(Color.GREEN);
        color3.setBackground(Color.RED);
        color4.setBackground(Color.BLUE);
        color5.setBackground(Color.BLACK);

        colorPan.add(color1);
        colorPan.add(color2);
        colorPan.add(color3);
        colorPan.add(color4);
        colorPan.add(color5);

    }

    @Override
    public void paint(Graphics g)
    {
        //g.setColor(Color.WHITE);
        //g.fillRect(0,0,getWidth(),getHeight());
        super.paint(g); //Do the same thing as above(Clear jframe)

        g.setColor(color);
        g.fillOval(x,y,50,50);
    }

    public void mouseExited(MouseEvent e) //MouseListener overrided methods
    {}

    public void mouseEntered(MouseEvent e)
    {}

    public void mouseReleased(MouseEvent e)
    {}

    public void mousePressed(MouseEvent e)
    {
        System.out.println("Press");    
        if(e.getX()+50 < getWidth() && e.getY()+50 < getHeight()) // Preventing out of bounds
        {
            x=e.getX();
            y=e.getY();
            repaint();
        }
    }

    public void mouseClicked(MouseEvent e) //Press+Release=Click
    {
        System.out.println("Click");
        if((e.getX()>=8 && e.getX()<=105) && (e.getY()>=232 && e.getY()<=243))
            color=Color.WHITE;
        else if((e.getX()>=106 && e.getX()<=203) && (e.getY()>=232 && e.getY()<=243))
            color=Color.GREEN;
        else if((e.getX()>=204 && e.getX()<=301) && (e.getY()>=232 && e.getY()<=243))
            color=Color.RED;
        else if((e.getX()>=302 && e.getX()<=399) && (e.getY()>=232 && e.getY()<=243))
            color=Color.BLUE;
        else if((e.getX()>=400 && e.getX()<=489) && (e.getY()>=232 && e.getY()<=243))
            color=Color.BLACK;
        repaint();
    }

    public void mouseDragged(MouseEvent e) //MouseMotionListener overrided methods
    {
        System.out.println("Dragged to ("+ e.getX() +","+ e.getY() +")");
        if((e.getX()>=3 && e.getY()>=30) && (e.getX()+50<getWidth() && e.getY()+50<getHeight())) //If circle is dragged in the JFrame
        {
            x=e.getX();
            y=e.getY();
            repaint();
        }
    }

    public void mouseMoved(MouseEvent e)
    {}

}
  • 第二个问题是圆可以拖到颜色选择器上。我不知道我该怎么做才能防止这种情况。我可以像对问题1那样硬编码这些值,但这将产生与问题1相同的问题
  • 我不希望使用
    setresizeable(false)
    ,而且JFrame是可调整大小的


    如何解决上述问题?

    不应重写JFrame的paint()方法。自定义绘制是通过重写JPanel(或JComponent)的paintComponent()方法完成的,然后将面板添加到框架中。您可以使用
    BorderLayout.CENTER
    将此面板添加到框架中

    对于您的颜色,您应该创建一个单独的面板,并在面板中添加按钮以表示每种颜色。您可以将每个按钮的背景设置为特定的颜色。您可以使用网格布局。然后,将此面板添加到框架的
    边框布局.PAGE\u END

    然后,您可以向每个按钮添加一个
    ActionListener
    ,而不是使用鼠标侦听器。基本准则是:

    public void actionPerformed(ActionEvent e)
    {
        JButton button = (JButton)e.getSource();
        color = button.getBackground();
        repaint();
    }
    

    不应重写JFrame的paint()方法。自定义绘制是通过重写JPanel(或JComponent)的paintComponent()方法完成的,然后将面板添加到框架中。您可以使用
    BorderLayout.CENTER
    将此面板添加到框架中

    对于您的颜色,您应该创建一个单独的面板,并在面板中添加按钮以表示每种颜色。您可以将每个按钮的背景设置为特定的颜色。您可以使用网格布局。然后,将此面板添加到框架的
    边框布局.PAGE\u END

    然后,您可以向每个按钮添加一个
    ActionListener
    ,而不是使用鼠标侦听器。基本准则是:

    public void actionPerformed(ActionEvent e)
    {
        JButton button = (JButton)e.getSource();
        color = button.getBackground();
        repaint();
    }
    

    我刚刚以更好的方式重新解决了你的问题。现在看起来是这样的:问题已经解决了

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class CirclePainter implements MouseMotionListener, ActionListener {
        private JFrame mainFrame;
        private JPanel colorPanel, circlePanel;
        private JButton whiteColorButton, redColorButton, greenColorButton,
                blueColorButton;
    
        private int circleWidth = 3, circleHeight = 15;
        private Color circleColor = Color.black;
    
        public CirclePainter() {
            initGui();
        }
    
        public void initGui() {
            mainFrame = new JFrame("Circle");
            mainFrame.setLayout(new BorderLayout());
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainFrame.setSize(500, 400);
    
            colorPanel = new JPanel(new FlowLayout());
    
            whiteColorButton = new JButton();
            whiteColorButton.setBackground(Color.white);
            whiteColorButton.setActionCommand("white");
            whiteColorButton.addActionListener(this);
            redColorButton = new JButton();
            redColorButton.setBackground(Color.red);
            redColorButton.setActionCommand("red");
            redColorButton.addActionListener(this);
            greenColorButton = new JButton();
            greenColorButton.setBackground(Color.green);
            greenColorButton.setActionCommand("green");
            greenColorButton.addActionListener(this);
            blueColorButton = new JButton();
            blueColorButton.setBackground(Color.blue);
            blueColorButton.setActionCommand("blue");
            blueColorButton.addActionListener(this);
    
            colorPanel.add(whiteColorButton);
            colorPanel.add(redColorButton);
            colorPanel.add(greenColorButton);
            colorPanel.add(blueColorButton);
    
            circlePanel = new JPanel() {
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(circleColor);
                    g.fillOval(circleWidth, circleHeight, 50, 50);
                }
            };
            circlePanel.addMouseMotionListener(this);
            circlePanel.setBackground(Color.yellow);
            mainFrame.add(circlePanel, BorderLayout.CENTER);
    
            mainFrame.add(colorPanel, BorderLayout.PAGE_END);
            mainFrame.setVisible(true);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            switch (e.getActionCommand()) {
            case "white":
                circleColor = Color.white;
                circlePanel.repaint();
                break;
            case "red":
                circleColor = Color.red;
                circlePanel.repaint();
                break;
            case "green":
                circleColor = Color.green;
                circlePanel.repaint();
                break;
            case "blue":
                circleColor = Color.blue;
                circlePanel.repaint();
                break;
            default:
                break;
            }
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new CirclePainter();
                }
            });
    
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
            if ((e.getX() >= 0 && e.getY() >= 0)
                    && (e.getX() <= mainFrame.getWidth() - 60)
                    && (e.getY() <= mainFrame.getHeight() - 110)) {
                circleWidth = e.getX();
                circleHeight = e.getY();
                circlePanel.repaint();
            }
    
        }
    
        @Override
        public void mouseMoved(MouseEvent arg0) {
    
        }
    
    }
    
    导入java.awt.BorderLayout;
    导入java.awt.Color;
    导入java.awt.FlowLayout;
    导入java.awt.Graphics;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.event.MouseEvent;
    导入java.awt.event.MouseMotionListener;
    导入javax.swing.JButton;
    导入javax.swing.JFrame;
    导入javax.swing.JPanel;
    导入javax.swing.SwingUtilities;
    公共类CirclePaint实现MouseMotionListener、ActionListener{
    专用JFrame主机;
    私人JPanel彩色面板,circlePanel;
    私人JButton白色按钮,红色按钮,绿色按钮,
    蓝色按钮;
    私有整数圆宽=3,圆宽=15;
    专用颜色circleColor=Color.black;
    公共电路油漆工(){
    initGui();
    }
    public void initGui(){
    大型机=新JFrame(“圆”);
    mainFrame.setLayout(新的BorderLayout());
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    大型机。设置大小(500400);
    colorPanel=newjpanel(newflowlayout());
    whiteColorButton=新JButton();
    白色按钮。背景(颜色。白色);
    setActionCommand(“白色”);
    whiteColorButton.addActionListener(此);
    redColorButton=新JButton();
    红色按钮。背景(颜色。红色);
    setActionCommand(“红色”);
    redColorButton.addActionListener(此);
    greenColorButton=新JButton();
    绿色按钮。背景(颜色。绿色);
    greenColorButton.setActionCommand(“绿色”);
    greenColorButton.addActionListener(此);
    blueColorButton=新JButton();
    蓝色按钮。背景(颜色。蓝色);
    blueColorButton.setActionCommand(“蓝色”);
    blueColorButton.addActionListener(此);
    添加(白色按钮);
    颜色面板。添加(红色颜色按钮);
    颜色面板。添加(绿色颜色按钮);
    添加(蓝色按钮);
    circlePanel=新的JPanel(){
    @凌驾
    公共组件(图形g){
    超级组件(g);
    g、 setColor(圆环色);
    g、 圆形(圆形宽度,圆形宽度,50,50);
    }
    };
    circlePanel.addMouseMotionListener(此);
    圆形板。挫折地面(颜色。黄色);
    mainFrame.add(圆环面板,BorderLayout.CENTER);
    mainFrame.add(彩色面板,边框布局,第_页结束);
    mainFrame.setVisible(true);
    }
    @凌驾
    已执行的公共无效操作(操作事件e){
    开关(如getActionCommand()){
    “白色”案例:
    圆环色=颜色。白色;
    circlePanel.repaint();
    打破
    案例“红色”:
    circleColor=颜色为红色;
    circlePanel.repaint();
    打破
    案例“绿色”:
    圆环色=Color.green;
    circlePanel.repaint();
    打破
    案例“蓝色”:
    circleColor=Color.blue;
    circlePanel.repaint();
    打破
    违约:
    打破
    }
    }
    公共静态void main(字符串参数[]){
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    新的电路油漆工();
    }
    });
    }
    @凌驾
    公共无效鼠标标记(鼠标事件e){
    如果((e.getX()>=0&&e.getY()>=0)
    
    &&(e.getX()我刚刚以一种更好的方式重新实现了您的问题

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class CirclePainter implements MouseMotionListener, ActionListener {
        private JFrame mainFrame;
        private JPanel colorPanel, circlePanel;
        private JButton whiteColorButton, redColorButton, greenColorButton,
                blueColorButton;
    
        private int circleWidth = 3, circleHeight = 15;
        private Color circleColor = Color.black;
    
        public CirclePainter() {
            initGui();
        }
    
        public void initGui() {
            mainFrame = new JFrame("Circle");
            mainFrame.setLayout(new BorderLayout());
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainFrame.setSize(500, 400);
    
            colorPanel = new JPanel(new FlowLayout());
    
            whiteColorButton = new JButton();
            whiteColorButton.setBackground(Color.white);
            whiteColorButton.setActionCommand("white");
            whiteColorButton.addActionListener(this);
            redColorButton = new JButton();
            redColorButton.setBackground(Color.red);
            redColorButton.setActionCommand("red");
            redColorButton.addActionListener(this);
            greenColorButton = new JButton();
            greenColorButton.setBackground(Color.green);
            greenColorButton.setActionCommand("green");
            greenColorButton.addActionListener(this);
            blueColorButton = new JButton();
            blueColorButton.setBackground(Color.blue);
            blueColorButton.setActionCommand("blue");
            blueColorButton.addActionListener(this);
    
            colorPanel.add(whiteColorButton);
            colorPanel.add(redColorButton);
            colorPanel.add(greenColorButton);
            colorPanel.add(blueColorButton);
    
            circlePanel = new JPanel() {
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(circleColor);
                    g.fillOval(circleWidth, circleHeight, 50, 50);
                }
            };
            circlePanel.addMouseMotionListener(this);
            circlePanel.setBackground(Color.yellow);
            mainFrame.add(circlePanel, BorderLayout.CENTER);
    
            mainFrame.add(colorPanel, BorderLayout.PAGE_END);
            mainFrame.setVisible(true);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            switch (e.getActionCommand()) {
            case "white":
                circleColor = Color.white;
                circlePanel.repaint();
                break;
            case "red":
                circleColor = Color.red;
                circlePanel.repaint();
                break;
            case "green":
                circleColor = Color.green;
                circlePanel.repaint();
                break;
            case "blue":
                circleColor = Color.blue;
                circlePanel.repaint();
                break;
            default:
                break;
            }
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new CirclePainter();
                }
            });
    
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
            if ((e.getX() >= 0 && e.getY() >= 0)
                    && (e.getX() <= mainFrame.getWidth() - 60)
                    && (e.getY() <= mainFrame.getHeight() - 110)) {
                circleWidth = e.getX();
                circleHeight = e.getY();
                circlePanel.repaint();
            }
    
        }
    
        @Override
        public void mouseMoved(MouseEvent arg0) {
    
        }
    
    }
    
    导入java.awt.BorderLayout;
    导入java.awt.Color;
    导入java.awt.FlowLayout;
    导入java.awt.Graphics;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    进口jav