![](/img/trans.png)
[英]How to change a JButton color when I hover over it but change it permanently to something else even if I hover afterwards when I click it?
[英]How to change the color of a panel when I pass over it with another one?
我正在创建一个代码,我需要将面板颜色更改为当我通过它时仍然按下的颜色。 例如,假设我按下一个绿色面板并将其拖到另一个面板上,这个面板应该是绿色的。 但是,它并非每次都有效,例如有时它确实会改变颜色,但有时却不会。
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) {
}
}
}
这是 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;
}
}
我不明白为什么它有时会起作用,我不知道问题是来自我如何进行拖动事件还是其他地方有问题。
谢谢你的遮阳篷。
我不明白为什么它有时会起作用,
当您将一个正方形拖动到另一个正方形时,您会注意到有时拖动的正方形会被绘制:
当正方形被绘制在另一个正方形above
时,不会生成mouseEntered
事件,因为默认逻辑只会为顶部组件生成事件。
当正方形画在另一个正方形below
时,将生成mouseEntered
事件,并且您的逻辑按预期工作。
组件的绘制顺序由其 ZOrder 决定。 因此,您可以将拖动组件的 ZOrder 调整为最后绘制的组件。
在mousePressed
逻辑中,您可以添加:
JPanel parent = (JPanel)getParent();
parent.setComponentZOrder(this, parent.getComponentCount() - 1);
这将确保拖动的组件始终绘制在其他组件的below
。
另请注意,不需要您的etat
变量。 mouseDragged 事件仅在鼠标按下时生成。
我创建了以下 GUI。
我在Carre
class 中添加了一个java.awt.Rectangle
来保存每个矩形的边界。 Carre
class 现在包含绘制Carre
实例的所有信息。
我创建了一个CarreModel
class 来保存Carre
实例的java.util.List
。 我在CarreModel
class 的构造函数中创建了所有Carre
实例。
我创建了一个JFrame
和一个绘图JPanel
。 我留下了你的JFrame
扩展,但一般来说,你应该使用 Swing 组件。 当您想要覆盖 class 方法之一时,您只能扩展 Swing 组件,例如CarrePanel
中的JPanel
。
我将MouseListener
和MouseMotionListener
与CarrePanel
JPanel
class 分开。 我发现将单独的函数保存在单独的方法和类中是有帮助的。 它使一次专注于应用程序的一个部分变得更加容易。
MouseListener
mousePressed
方法在底部有一个 function 以将选定的 carre 移动到 Z 顺序的顶部。 这使得carre动作更具视觉吸引力。
MouseListener
updateCarreColor
方法检查 carre 交叉点并更改与所选 carre 相交的任何 carre 的颜色。
这是完整的可运行代码。 我将所有类都设为内部类,因此我可以将代码作为一个块发布。
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.