0 0

JPanel中通过鼠标点击事件删除点中的组件为什么要repaint()后才能看到更新5

最近学习java图形的时候,准备写个打砖块的游戏练手,但是遇到很多问题。
请帮忙看看以下代码,RedBrick是一个红色的砖块,它需要被添加到一个游戏窗体BrickFrame中。BrickFrame添加了鼠标监听事件,测试代码时,我在事件中进行以下处理:删除通过鼠标点中的RedBrick。

import java.awt.*;

import javax.swing.*;
import javax.swing.border.*;

public class RedBrick extends JPanel {

        
        // 砖块的长和宽,常量
        public static final int WIDTH = 50;
        public static final int HEIGHT = 20;
        
        //常量名以颜色命名,值为颜色对应被销毁需要的次数
        public static final int RED = 1;
        public static final int ORANGE = 2;
        public static final int YELLOW = 3;
        public static final int GREEN = 4;
        public static final int CYAN = 5;
        public static final int BLUE = 6;
        public static final int MAGENTA = 7;
        
        //砖块在整个砖块方阵中所处的排数
        private int row;
        //砖块在整个砖块方阵中所处的列数
        private int column;
        
        //砖块的坐标
        private int x;
        private int y;
        
        private int color;
        //填充色,与变量color对应,通过方法getColor(color)来得到fillColor
        private Color fillColor;
        //边的颜色
        private Color edgeColor;


        public RedBrick(int row, int column){
this(RED, row, column);
        }
        
public RedBrick(int color, int row, int column){
                this.color = color;
                setFillColor(this.color);
                setBorder(new LineBorder(Color.BLUE));

                this.row = row;
                this.column = column;
                x = BrickFrame.START_X + WIDTH * column;
                y = BrickFrame.START_Y + HEIGHT * row;
        }

        /**
         * 设置砖块颜色
         * @param color 
         */
        private void setFillColor(int color) {
                fillColor = getColor(color);
        }
        
        
        /**
         * 通过该类中的颜色常量RED,ORANGE,YELLOW,GREEN,CYAN,BLUE,MAGENTA对应的Color类中的颜色,如果不为以上7种颜色,则返回Color.BLACK
         */
        private Color getColor(int color) {
                switch(color) {
                case RED: return Color.RED;
                case ORANGE: return Color.ORANGE;
                case YELLOW: return Color.YELLOW;
                case GREEN: return Color.GREEN;
                case CYAN: return Color.CYAN;
                case BLUE: return Color.BLUE;
                case MAGENTA: return Color.MAGENTA;
                default: return Color.BLACK;
                }
        }
        
        public void paintComponent(Graphics g){
                super.paintComponent(g);
                g.setColor(fillColor);
                g.fillRect(0, 0, WIDTH, HEIGHT);
                this.setLocation(x, y);
                this.setSize(WIDTH, HEIGHT);  //如果不设置size,一个Brick就会把整个Frame占满
        }

}

 

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;

public class BrickFrame extends JPanel {
        private ArrayList<Brick> bricks = new ArrayList<Brick>(); //

        // 窗体的宽和高
        public final static int FRAME_WIDTH = 800;
        public final static int FRAME_HEIGHT = 600;

        // 砖块的起始坐标
        public final static int START_X = 0;
        public final static int START_Y = 60;

        private MouseAdapter mouseListener = new MouseAdapter() {

                public void mouseClicked(final MouseEvent e) {

                        remove(getComponentAt(e.getPoint()));
                        repaint(); //如果不调用repaint()方法,组件删除后不能马上看到效果,为什么?

                }
        };

        /**
         * 重写add方法,如果c是Brick类的一个实例,则将其转换为Brick类型然后添加到bricks中
         */
        public Component add(Component c) {
                super.add(c);
                if (c instanceof Brick) {
                        bricks.add((Brick) c);
                }
                return c;
        }

        /**
         * 重写add方法,如果c是Brick类的一个实例,则将其从bricks中删除
         */
        public void remove(Component c) {
                super.remove(c);
                if (c instanceof Brick) {
                        bricks.remove((Brick) c);
                }
        }

        public BrickFrame() {
                this.addMouseListener(mouseListener);
                this.addMouseMotionListener(mouseMotionListener);
        }

}

 下面是初始化代码

public class Test {
        public static void main(String[] args) {
                final JFrame jf = new JFrame(); 
                BrickFrame bf = new BrickFrame();
                
                //在窗体中添加Brick,
                for (int i = 0; i < 400 / Brick.HEIGHT; i++) {
                        for (int j = 0; j <(BrickFrame.FRAME_WIDTH - BrickFrame.START_X) / Brick.WIDTH; j++) {
                                bf.add(new RedBrick(i, j));
                        }
                }
                
                //下面代码放在for循环后,为什么?是不是for循环也要加入到EDT中?
                jf.add(bf);
                SwingUtilities.invokeLater(new Runnable() {
                        
                        public void run() {
                                jf.setTitle("打砖块");
                                jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                jf.setSize(816, 638);
                                jf.setVisible(true);
                        }
                });
        }
}

 在鼠标监听事件中通过remove来删除鼠标点中的组件RedBrick

remove(getComponentAt(e.getPoint()));
但是如果不调用repaint()则不会马上看到砖块删除,需要改变窗体大小后才能看到。
我知道swing有个事件派发线程,但是还是不太明白为什么。

2014年3月18日 09:49

1个答案 按时间排序 按投票排序

0 0

repaint(),首先你得了解是在什么样的情况下会产生窗口重画。另外,我觉得最无语的是为什么都是组件来当一个砖头,你不觉得太夸张了吗。。。。请使用Graphics2D去完成。

2014年3月18日 10:50

相关推荐

    java事件 鼠标事件 实例代码

    在这个特定的主题中,我们关注的是"Java事件",特别是"鼠标事件",并通过实例代码来深入理解这一概念。 Java事件模型基于观察者模式,其中事件源(通常是组件如按钮或文本框)生成事件,而事件监听器则注册以接收...

    基于JPanel以及鼠标监听的Java 画图程序

    在这个项目中,JPanel被用作画布,用户可以通过鼠标操作在上面绘制各种图形。 【描述】提到,这个程序允许用户画出直线、圆、线和点。这表明代码中可能包含了对这些基本图形的处理方法。例如,可能会有针对鼠标按下...

    Java继承JPanel实现自适应布局的面板

    在Java Swing库中,`JPanel`是一个非常基础且重要的组件,它被广泛用于构建用户界面。本示例中,我们讨论的是一个自定义的`JPanel`子类,名为`AutojustChildPanel`,该子类实现了自适应布局的能力。这种能力使得组件...

    java鼠标事件使用的简单例子

    在Java编程中,处理鼠标事件是一项基础且重要的任务,它使得用户可以通过鼠标与应用程序进行交互。本篇文章将深入探讨如何在Java中实现鼠标事件监听,包括点击、移动和释放等行为,并通过一个简单的例子来说明。 ...

    画图工具java的简单鼠标事件

    在Java中,我们可以通过实现`MouseListener`和`MouseMotionListener`接口来监听鼠标的点击、移动等事件。以下是一些常见的鼠标事件: 1. `mousePressed(MouseEvent e)`:鼠标按钮被按下。 2. `mouseReleased...

    java鼠标事件--正弦曲线

    在Java编程中,鼠标事件(MouseEvent)是图形用户界面(GUI)编程的重要组成部分,它允许程序响应用户的鼠标操作。在这个“java鼠标事件--正弦曲线”的主题中,我们将深入探讨如何利用Java AWT和Swing库来处理鼠标...

    如何卸载JPanel面板

    在Java Swing库中,JPanel是一个非常常用的组件,它用于创建自定义的用户界面。有时,根据应用程序的需求,我们可能需要动态地添加或卸载JPanel。本文将深入讲解如何在Java程序中卸载JPanel面板,以及相关的重要知识...

    java-JPanel滑动切换

    Java JPanel 是Java Swing库中的一个组件,用于在GUI(图形用户界面)中创建自定义的绘制区域。在Java编程中,我们经常使用JPanel来构建复杂的用户界面,因为它提供了高度的可定制性,允许程序员添加自己的绘图代码...

    swing多个jpanel布局切换实例

    在Java的Swing库中,JPanel是组件容器,它允许开发者组织和管理GUI中的组件。JPanel可以使用不同的布局管理器,以便根据需求灵活地调整组件的位置和大小。本实例将探讨如何在Swing应用中实现多个JPanel布局的切换。 ...

    Swing控件(JPanel,Container等)设置背景图片

    在Java的Swing库中,JPanel和Container是两种重要的组件,它们被广泛用于构建图形用户界面(GUI)。Swing提供了丰富的功能,包括允许开发者为这些组件设置自定义的背景图片,以提升应用的视觉效果。这篇博文主要讨论...

    Java中Graphics的paint和repaint方法.pdf

    总的来说,`paint`和`repaint`是Java GUI编程中图形更新的关键工具,`paint`用于实际的绘图操作,而`repaint`则负责调度和管理组件的重绘过程。正确理解和使用这两个方法能够帮助你创建动态且高效的图形用户界面。

    java屏蔽鼠标右键和键盘相关事件

    在Java编程环境中,有时我们需要对用户的输入事件进行特定的控制,比如在开发特定的应用程序时,可能希望禁用鼠标右键菜单或者键盘某些特定按键的功能。这个任务涉及到Java的事件处理机制,主要涵盖AWT(Abstract ...

    基于Java的鼠标拖拽功能.zip

    在`mousePressed`事件中记录鼠标点击时的坐标(相对于组件),然后在`mouseDragged`事件中计算鼠标的当前坐标和初始坐标之间的差值,以此来更新组件的位置。 7. **重绘组件**: 在更新组件位置后,通常需要调用`...

    可插入背景图片的JPanel

    在Java GUI编程中,我们经常会遇到需要为组件添加视觉效果,比如设置背景图片。标题“可插入背景图片的JPanel”指向的就是一个解决此类问题的技巧。Java的标准库并未提供直接在`JPanel`上设置背景图片的方法,但是...

    用java JFrame,JPanel写的大鱼吃小鱼小游戏

    通过在JPanel上进行重绘,游戏可以实现动态效果,如鱼的游动、碰撞检测和分数更新。 标签中的“JAVA swing awt”表明开发者不仅使用了Swing库,可能也利用了AWT的一些功能。AWT是Java早期的图形用户界面库,虽然...

    用java中的jpanel实现的扫雷小游戏.zip

    在这个扫雷游戏中,开发者需要监听鼠标的点击事件,当用户点击面板上的某个格子时,触发相应的游戏逻辑。 4. **多线程**: 扫雷游戏通常需要在用户交互和游戏逻辑之间进行同步,这可能涉及使用多线程技术,确保...

    Java实现跟踪鼠标运行坐标的源码.7z

    要让组件监听鼠标事件,我们需要将监听器添加到对应的组件上,例如`JFrame`或`JPanel`。这可以通过`addMouseListener()`和`addMouseMotionListener()`方法实现。 4. **获取鼠标坐标**: 在`mouseMoved()`方法中,...

    Java实现跟踪鼠标运行坐标的源码

    当鼠标在`JPanel`上移动时,`mouseMoved`方法会被调用,然后我们更新`JPanel`的内容并调用`repaint()`,这样就会在窗口中显示鼠标的当前位置。 在`paintComponent`方法中,我们使用`Graphics`对象来绘制文本,显示...

    java拖拽透明组件源码

    当用户按下鼠标并移动时,我们可以计算出鼠标的偏移量,然后在鼠标移动事件中更新组件的位置,以此实现拖动效果。 透明组件的实现涉及到Java的AWT和Swing的一些底层机制。在Java中,组件的透明度由`setOpaque(false...

    java迷宫设计,JPanel实现

    在这个项目中,`JPanel`被用作迷宫的基础框架,通过自定义绘制方法,可以在`JPanel`上绘制出迷宫的结构。开发者可能使用了`Graphics`类提供的绘图方法,如`drawLine()`、`fillRect()`等,来创建迷宫的墙壁、路径以及...

Global site tag (gtag.js) - Google Analytics