当我通过另一个面板时如何更改面板的颜色?
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;
}
}
我不明白的是为什么有时它会起作用,我不知道问题是出在我如何进行拖动事件还是其他地方有问题。
谢谢你的遮阳篷。
What I don't understand is why does it works sometimes,
当您将一个方块拖到另一个方块时,您会注意到有时拖动的方块会被绘制:
- 在另一个广场下方
- 在另一个正方形上方
当正方形被绘制时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 来保存 java.util.List
个 Carre
个实例。我在 CarreModel
class.
的构造函数中创建了所有 Carre
实例
我创作了一幅 JFrame
和一幅画作 JPanel
。我离开了你的 JFrame
extend,但一般来说,你应该使用 Swing 组件。当您想覆盖 class 方法之一时,您只需扩展一个 Swing 组件,例如 CarrePanel
中的 JPanel
。
我将 MouseListener
和 MouseMotionListener
与 CarrePanel
JPanel
class 分开了。我发现在单独的方法和 classes 中保留单独的函数很有帮助。这样可以更轻松地一次专注于应用程序的一部分。
MouseListener
mousePressed
方法在底部有一个函数,可以将选中的carre移动到z-order的顶部。这使得 carre move 在视觉上更具吸引力。
MouseListener
updateCarreColor
方法检查方格交叉点并更改与所选方格相交的任何方格的颜色。
这是完整的可运行代码。我将所有 classes 都放在 classes 中,这样我就可以 post 将代码作为一个块。
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;
}
}
}
我正在创建一个代码,我需要将面板颜色更改为我经过它时仍然按下的颜色。例如,如果我按下一个绿色面板并将其拖到另一个面板上,那么这个面板应该变成绿色。然而它并不是每次都有效,就像有时它会改变颜色但有时却不会。
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;
}
}
我不明白的是为什么有时它会起作用,我不知道问题是出在我如何进行拖动事件还是其他地方有问题。
谢谢你的遮阳篷。
What I don't understand is why does it works sometimes,
当您将一个方块拖到另一个方块时,您会注意到有时拖动的方块会被绘制:
- 在另一个广场下方
- 在另一个正方形上方
当正方形被绘制时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 来保存 java.util.List
个 Carre
个实例。我在 CarreModel
class.
Carre
实例
我创作了一幅 JFrame
和一幅画作 JPanel
。我离开了你的 JFrame
extend,但一般来说,你应该使用 Swing 组件。当您想覆盖 class 方法之一时,您只需扩展一个 Swing 组件,例如 CarrePanel
中的 JPanel
。
我将 MouseListener
和 MouseMotionListener
与 CarrePanel
JPanel
class 分开了。我发现在单独的方法和 classes 中保留单独的函数很有帮助。这样可以更轻松地一次专注于应用程序的一部分。
MouseListener
mousePressed
方法在底部有一个函数,可以将选中的carre移动到z-order的顶部。这使得 carre move 在视觉上更具吸引力。
MouseListener
updateCarreColor
方法检查方格交叉点并更改与所选方格相交的任何方格的颜色。
这是完整的可运行代码。我将所有 classes 都放在 classes 中,这样我就可以 post 将代码作为一个块。
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;
}
}
}