JComponent和JPanel的不同
写了个程序,继承的类开始是JPanel,老师不对,有问题,debug还是不行,最后把JPanel换成了JComponent马上就好了。然后网上找这两个的区别,API看的云里雾里的,想要个直白点的解释。贴上代码吧。就是在MousePanel那个类里面。希望哪位大大能把这两个的各种区别讲出来。谢谢。如下:[code=Java][/code]
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.*;
public class MouseTest {
/**
* @param args
* 用鼠标简单的画画
*/
public static void main(String[] args) {
MouseFrame frame = new MouseFrame();
}
}
class MouseFrame extends JFrame {
public MouseFrame() {
this.setTitle("MouseTest");
this.setSize(WIDTH, HEIGHT);
this.setLocation(X, Y);
this.add(new MousePanel());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
private final int WIDTH = 500;
private final int HEIGHT = 500;
private final int X = 200;
private final int Y = 50;
}
class MousePanel extends JComponent {
public MousePanel (){
squres = new ArrayList<Rectangle2D>();
rect = null;
addMouseListener(new MouseMoniter());
addMouseMotionListener(new MouseMonitorHandler());
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
for(Rectangle2D rect : squres) {
g2.draw(rect);
}
}
// 如果包含鼠标点击的坐标则不绘制,否则加入集合进行绘制。
public Rectangle2D find(Point2D point) {
for(Rectangle2D r: squres) {
if(r.contains(point)) {
return r;
}
}
return null;
}
// 添加点击要画的矩形。
public void addSqures(Point2D p) {
double x = p.getX() - SQURESIZE/2;
double y = p.getY() - SQURESIZE/2;
rect = new Rectangle2D.Double(x, y, SQURESIZE, SQURESIZE);
squres.add(rect);
repaint();
}
// 移除双击及其以上的矩形
public void removeSqures(Rectangle2D s) {
if(s == null)return;
if(s == rect) rect = null;
squres.remove(s);
repaint();
}
private ArrayList<Rectangle2D> squres;
private Rectangle2D rect;
private final int SQURESIZE = 10;
private class MouseMoniter extends MouseAdapter {
// 不用mousecliked是为了让用户操作立即得到响应。不必等到鼠标松开。
public void mousePressed(MouseEvent e) {
rect = find(e.getPoint());
if(rect == null) {
addSqures(e.getPoint());
}
}
// 判断是否擦出矩形
public void mouseClicked(MouseEvent e) {
rect = find(e.getPoint());
if(rect != null && e.getClickCount()>=2) {
removeSqures(rect);
}
}
}
private class MouseMonitorHandler implements MouseMotionListener {
// 鼠标进入矩形后变成十字架
public void mouseMoved(MouseEvent e) {
if(find(e.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
// 拖动矩形
public void mouseDragged(MouseEvent e) {
if(rect != null) {
int x = e.getX();
int y = e.getY();
rect.setFrame(x-SQURESIZE/2, y-SQURESIZE/2, SQURESIZE, SQURESIZE);
repaint();
}
}
}
}
------解决方案--------------------
如果是 JPanel 的话
在重写 paintComponent 时,第一句协上:
super.paintComponent(g);
就没问题了
这样就会擦除上一次的绘制
原因就是 JPanel 默认的 Opaque 属性为 true
而 JComponent 默认的 Opaque 属性为 false
关于这个属性你可以查看 API