简体   繁体   English

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

[英]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:当您将一个正方形拖动到另一个正方形时,您会注意到有时拖动的正方形会被绘制:

  1. below the other square在另一个广场下方
  2. above the other square在另一个广场之上

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.我将MouseListenerMouseMotionListenerCarrePanel 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.

相关问题 如何在我将鼠标悬停在 JButton 上时更改它的颜色,但即使我在单击它之后悬停时将其永久更改为其他颜色? - 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? 当我用另一个面板包裹面板时,为什么胶水会消失? - Why does glue disappear when I wrap a Panel with another one? 如何通过另一个面板更改CardLayout的面板 - how to change a panel of CardLayout through another panel 如何传递按钮意图在另一个活动中制作可绘制的变色? - how to pass button intent to make drawable change color in another activity? 如何在JavaFX中将一个图像制作成另一个图像,然后在ActionTimer中再次更改它? - How can I make one Image over another in JavaFX and change it again in an ActionTimer? 如何通过从另一个类中执行操作来更改一个类中的Graphics的颜色? - How can I change the color of my Graphics in one class by preforming an action from another class? 单击查看所有连接时如何一一更改这些按钮的背景色 - How to change the background color for these buttons one by one when I click check all connections 当 FireTV 遥控器在按钮上导航时如何更改按钮的颜色 - How to Change Color of Button when FireTV remote navigates over it 如何更改Java面板上的背景颜色? - How to change the background color on a Java panel? 悬停在一个矩形上时如何为它着色? - How to specifically color one rect when it's hovered over?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM