java - 在 JPanel 中检测 mouseClick 并防止在 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;
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)
    {}

}

以上代码按预期工作并产生输出:

OUTPUT

当我也单击底部 JPanel 中的颜色时,程序会按预期工作并更改圆圈的颜色。

出现的两个问题是:

  1. 当我调整 JFrame 大小时,颜色选择器无法按预期工作。这是由于我在 mouseClicked 方法中硬编码的愚蠢方式:

    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();
    }
    
  2. 第二个问题是可以将圆拖到颜色选择器上。我不知道我应该怎么做才能防止这种情况发生。我可以像解决问题 #1 那样对值进行硬编码,但这会产生与问题 #1 相同的问题。

我宁愿不使用 setResizable(false) 并且 JFrame 可以调整大小。

如何解决上述问题?

最佳答案

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

对于您的颜色,您应该创建一个单独的面板并向面板添加按钮以代表每种颜色。您可以将每个按钮的背景设置为特定颜色。您可以使用 GridLayout。然后将此面板添加到框架的 BorderLayout.PAGE_END

然后,您可以向每个按钮添加一个 ActionListener,而不是使用 MouseListener。基本代码是:

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

关于java - 在 JPanel 中检测 mouseClick 并防止在 JPanel 中绘制圆圈的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29947016/

相关文章:

java - 我的 JFrame 总是变得太大了几个像素。

java - 按钮监听器中的随机面板颜色仅有效一次

java jframe和ImagePanel之间的差距

java - Eclipse 将多个 classpathentry 分层组合到相同的输出中

java - 使用 Jena 读取限制值

java - 保存的(位图)图像需要一段时间才能出现在图库中

java - 使用数据库创建 jcomponents

Java Swing 图形用户界面 : Code isnt producing the right output

java - 使用 Spring Integration 的带有 Dataflow 的 Google PubSub

java - 编译和运行一个java程序需要多少资源?