在JPanel中检测mouseClick并防止在JPanel中画圆的问题 [英] Problems with detecting mouseClick in a JPanel and preventing circle from painting in JPanel
问题描述
我当前的程序允许用户在JFrame周围移动一个圆,并通过按JFrame底部JPanel中显示的颜色之一来更改其颜色.
My current program lets the user move a circle around the JFrame and also change its color by pressing one of the colors presented in the JPanel at the bottom of the JFrame.
我的代码:
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)
{}
}
上面的代码按预期工作并产生输出:
The above code works as expected and produces the output:
当我也单击底部JPanel中的颜色时,程序将按预期运行并更改圆圈的颜色.
When I click the colors in the JPanel in the bottom too, the program works as expected and changes the color of the circle.
出现的两个问题是:
-
当我调整JFrame的大小时,颜色选择器无法正常工作.这是由于我在
mouseClicked
方法中采用硬编码的愚蠢方式:
When I resize the JFrame, the color chooser doesn't work as expected. This is due to my stupid way of hardcoding in the
mouseClicked
method:
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();
}
我宁愿不使用setResizable(false)
并且JFrame可调整大小.
I would prefer not to use setResizable(false)
and that the JFrame to be resizeable.
如何解决上述问题?
推荐答案
我刚刚以更好的方式重新实现了您的问题.这是现在的样子:问题已解决.
I've just re implemented your problem in a better way. Here is how it looks like now: Problems are solved.
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) {
}
}
以下是输出:
这篇关于在JPanel中检测mouseClick并防止在JPanel中画圆的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!