当我通过另一个面板时如何更改面板的颜色?

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,

当您将一个方块拖到另一个方块时,您会注意到有时拖动的方块会被绘制:

  1. 在另一个广场下方
  2. 在另一个正方形上方

当正方形被绘制时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.ListCarre 个实例。我在 CarreModel class.

的构造函数中创建了所有 Carre 实例

我创作了一幅 JFrame 和一幅画作 JPanel。我离开了你的 JFrame extend,但一般来说,你应该使用 Swing 组件。当您想覆盖 class 方法之一时,您只需扩展一个 Swing 组件,例如 CarrePanel 中的 JPanel

我将 MouseListenerMouseMotionListenerCarrePanel JPanel class 分开了。我发现在单独的方法和 classes 中保留单独的函数很有帮助。这样可以更轻松地一次专注于应用程序的一部分。

MouseListenermousePressed方法在底部有一个函数,可以将选中的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;
        }
        
    }

}