[英]How to change the color of a panel when I pass over it with another one?
I'm creating a code where I need to change a Panel color with the one I'm still pressed on when I pass over it.我正在创建一个代码,我需要将面板颜色更改为当我通过它时仍然按下的颜色。 For instance if let's say I pressed on a green panel and drag it over another one, this one should get the green color.例如,假设我按下一个绿色面板并将其拖到另一个面板上,这个面板应该是绿色的。 However it doesn't work everytime, like sometimes it does change the color but sometimes it doesn't.但是,它并非每次都有效,例如有时它确实会改变颜色,但有时却不会。
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.util.Random;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.*;
import javax.swing.event.MouseInputListener;
public class Etabli extends JFrame {
JPanel paneprinci;
CarrePanel selected;
public Etabli() {
this.setVisible(true);
setTitle("Cadre");
setDefaultCloseOperation(EXIT_ON_CLOSE);
paneprinci=new JPanel(null);
setSize(600,600);
selected=new CarrePanel();
for (int i=0;i<10;i++) {
paneprinci.add(new CarrePanel(new Carre()));
}
this.getContentPane().add(paneprinci);
}
public static void main (String[]args) {
javax.swing.SwingUtilities.invokeLater(
new Runnable() {
public void run() {
Etabli e=new Etabli();
}
});
}
public class CarrePanel extends JPanel implements MouseInputListener{
private Carre carre;
private boolean etat;
private int xprev;
private int yprev;
public CarrePanel(Carre c) {
setBounds(new Random().nextInt(500),new Random().nextInt(500), 50, 50);
addMouseListener(this);
addMouseMotionListener(this);
this.setBackground(c.getColor());
this.carre=c;
}
public CarrePanel() {
setBounds(new Random().nextInt(500),new Random().nextInt(500), 50, 50);
addMouseListener(this);
addMouseMotionListener(this);
}
public void setCarre(Carre c) {
carre=c;
}
public Carre getCarre() {
return carre;
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println(this.carre.getColor());
}
@Override
public void mouseEntered(MouseEvent e) {
if (selected.getCarre()!=null) {
this.carre.setColor(selected.getCarre().getColor());
this.setBackground(selected.getCarre().getColor());
}
}
@Override
public void mousePressed(MouseEvent e) {
etat=true;
selected.setCarre(this.carre);
xprev=e.getXOnScreen();
yprev=e.getYOnScreen();
}
@Override
public void mouseReleased(MouseEvent e) {
etat=false;
if(selected.getCarre()==this.carre) {
selected.setCarre(null);;
}
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
if(etat) {
int x=this.getX()+e.getXOnScreen()-xprev;
int y=this.getY()+e.getYOnScreen()-yprev;
this.setLocation(x,y);
xprev=e.getXOnScreen();
yprev=e.getYOnScreen();
}
}
@Override
public void mouseMoved(MouseEvent e) {
}
}
}
Here's the code for Carre ( which is square in French )这是 Carre 的代码(法语为正方形)
import java.awt.Color;
import java.util.Arrays;
import java.util.Random;
import java.awt.Color;
public class Carre {
private Color color;
public Carre() {
color=new Color(new Random().nextInt(255),new Random().nextInt(255),new Random().nextInt(255));
}
public Color getColor() {
return color;
}
public void setColor(Color c) {
color=c;
}
}
What I don't understand is why does it works sometimes, I don't know if the problem comes from how I did my drag event or if there's something wrong elsewhere.我不明白为什么它有时会起作用,我不知道问题是来自我如何进行拖动事件还是其他地方有问题。
Thank you for your awnser.谢谢你的遮阳篷。
What I don't understand is why does it works sometimes,我不明白为什么它有时会起作用,
When you drag a square to another square you will notice that sometimes the dragged square is painted:当您将一个正方形拖动到另一个正方形时,您会注意到有时拖动的正方形会被绘制:
When the square is painted above
the other square a mouseEntered
event is not generated because the default logic will only generate the event for the top component.当正方形被绘制在另一个正方形above
时,不会生成mouseEntered
事件,因为默认逻辑只会为顶部组件生成事件。
When the square is painted below
the other square, then your mouseEntered
event is generated and your logic works as expected.当正方形画在另一个正方形below
时,将生成mouseEntered
事件,并且您的逻辑按预期工作。
The order of painting of a component is determined by its ZOrder.组件的绘制顺序由其 ZOrder 决定。 So you can adjust the ZOrder of the dragged component to be the last component painted.因此,您可以将拖动组件的 ZOrder 调整为最后绘制的组件。
In the mousePressed
logic you can add:在mousePressed
逻辑中,您可以添加:
JPanel parent = (JPanel)getParent();
parent.setComponentZOrder(this, parent.getComponentCount() - 1);
This will make sure that the dragged component is always painted below
the other components.这将确保拖动的组件始终绘制在其他组件的below
。
Also note that your etat
variable is not needed.另请注意,不需要您的etat
变量。 The mouseDragged event is only generated while the mouse is pressed. mouseDragged 事件仅在鼠标按下时生成。
I created the following GUI.我创建了以下 GUI。
I added a java.awt.Rectangle
to the Carre
class to holds the bounds of each rectangle.我在Carre
class 中添加了一个java.awt.Rectangle
来保存每个矩形的边界。 The Carre
class now holds all of the information to draw a Carre
instance. Carre
class 现在包含绘制Carre
实例的所有信息。
I created a CarreModel
class to hold a java.util.List
of Carre
instances.我创建了一个CarreModel
class 来保存Carre
实例的java.util.List
。 I create all of the Carre
instances in the constructor of the CarreModel
class.我在CarreModel
class 的构造函数中创建了所有Carre
实例。
I created one JFrame
and one drawing JPanel
.我创建了一个JFrame
和一个绘图JPanel
。 I left your JFrame
extend, but generally, you should use Swing components.我留下了你的JFrame
扩展,但一般来说,你应该使用 Swing 组件。 You only extend a Swing component, like JPanel
in CarrePanel
, when you want to override one of the class methods.当您想要覆盖 class 方法之一时,您只能扩展 Swing 组件,例如CarrePanel
中的JPanel
。
I separated the MouseListener
and MouseMotionListener
from the CarrePanel
JPanel
class.我将MouseListener
和MouseMotionListener
与CarrePanel
JPanel
class 分开。 I find it helps to keep separate functions in separate methods and classes.我发现将单独的函数保存在单独的方法和类中是有帮助的。 It makes it much easier to focus on one part of the application at a time.它使一次专注于应用程序的一个部分变得更加容易。
The MouseListener
mousePressed
method has a function at the bottom to move the selected carre to the top of the Z-order. MouseListener
mousePressed
方法在底部有一个 function 以将选定的 carre 移动到 Z 顺序的顶部。 This makes the carre move more visually appealing.这使得carre动作更具视觉吸引力。
The MouseListener
updateCarreColor
method checks for carre intersections and changes the color of any carre that intersects the selected carre. MouseListener
updateCarreColor
方法检查 carre 交叉点并更改与所选 carre 相交的任何 carre 的颜色。
Here's the complete runnable code.这是完整的可运行代码。 I made all the classes inner classes so I can post the code as one block.我将所有类都设为内部类,因此我可以将代码作为一个块发布。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.MouseInputListener;
public class Etabli extends JFrame {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Etabli();
}
});
}
private CarreModel model;
private CarrePanel paneprinci;
public Etabli() {
this.model = new CarreModel();
this.setTitle("Cadre");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
paneprinci = new CarrePanel();
this.add(paneprinci, BorderLayout.CENTER);
this.pack();
this.setLocationByPlatform(true);
this.setVisible(true);
}
public class CarrePanel extends JPanel {
private static final long serialVersionUID = 1L;
public CarrePanel() {
this.setPreferredSize(new Dimension(550, 550));
ColorListener listener = new ColorListener();
this.addMouseListener(listener);
this.addMouseMotionListener(listener);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Carre carre : model.getCarres()) {
g2d.setColor(carre.getColor());
Rectangle r = carre.getBounds();
g2d.fillRect(r.x, r.y, r.width, r.height);
}
}
}
public class ColorListener implements MouseInputListener {
private Carre selectedCarre;
private Point pressedPoint;
@Override
public void mouseClicked(MouseEvent event) {
}
@Override
public void mouseEntered(MouseEvent event) {
}
@Override
public void mousePressed(MouseEvent event) {
pressedPoint = event.getPoint();
selectedCarre = null;
for (Carre carre : model.getCarres()) {
if (carre.getBounds().contains(pressedPoint)) {
selectedCarre = carre;
break;
}
}
if (selectedCarre != null) {
List<Carre> carres = model.getCarres();
carres.remove(selectedCarre);
carres.add(selectedCarre);
}
}
@Override
public void mouseReleased(MouseEvent event) {
updateCarrePosition(event.getPoint());
updateCarreColor();
}
@Override
public void mouseExited(MouseEvent event) {
}
@Override
public void mouseDragged(MouseEvent event) {
updateCarrePosition(event.getPoint());
updateCarreColor();
}
@Override
public void mouseMoved(MouseEvent event) {
}
private void updateCarrePosition(Point point) {
int x = point.x - pressedPoint.x;
int y = point.y - pressedPoint.y;
if (selectedCarre != null) {
selectedCarre.incrementBounds(x, y);
paneprinci.repaint();
pressedPoint.x = point.x;
pressedPoint.y = point.y;
}
}
private void updateCarreColor() {
if (selectedCarre != null) {
for (Carre carre : model.getCarres()) {
if (!carre.equals(selectedCarre) &&
carre.getBounds().intersects(selectedCarre.getBounds())) {
carre.setColor(selectedCarre.getColor());
paneprinci.repaint();
}
}
}
}
}
public class CarreModel {
private final List<Carre> carres;
public CarreModel() {
this.carres = new ArrayList<>();
for (int i = 0; i < 10; i++) {
this.carres.add(new Carre());
}
}
public List<Carre> getCarres() {
return carres;
}
}
public class Carre {
private Color color;
private final Random random;
private Rectangle bounds;
public Carre() {
random = new Random();
int red = random.nextInt(128);
int green = random.nextInt(128);
int blue = random.nextInt(128);
color = new Color(red, green, blue);
int x = random.nextInt(500);
int y = random.nextInt(500);
bounds = new Rectangle(x, y, 50, 50);
}
public void incrementBounds(int x, int y) {
bounds.x += x;
bounds.y += y;
}
public Color getColor() {
return color;
}
public void setColor(Color c) {
color = c;
}
public Rectangle getBounds() {
return bounds;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.