仔细揣摩题目意思,写出不一样的答案.
制作一个Java swing小程序,满足下列要求
1.一开始,有一个空窗口大小100X100,内部有一个按钮 
2.点击按钮,在坐标(X,Y)处显示一个小正方形大小20X20,X,Y≤80.要求生成的正方形与已有正方形不重叠
3.如果没有地方再生成正方形,就出现对话框报错 
4.双击此按钮,所有方块向上移动,之至上部到窗口顶,或接触上面一个方块。方块每次移动一个像素。所有方块停止,便结束 
5.窗口下方有一个“清理”按钮,点击重新回到程序起点
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;public class Ms1 extends JFrame{
private JButton b1;
private Canvas c;
List<Rect> list = new ArrayList<Rect>();
private JDialog jd;
Random r = new Random();
public Ms1(){ //绝对定位
this.setLayout(null); b1 = new JButton("B");
c = new Canvas(); c.setBounds(0, 0, 80, 80);
b1.setBounds(80, 80, 20, 20); c.setBackground(Color.YELLOW); this.setUndecorated(true);
this.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
this.add(c);
this.add(b1); this.setSize(100, 100);
this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); b1.addMouseListener(new MouseAdapter(){ @Override
public void mousePressed(MouseEvent e) {
if(e.getClickCount() == 2){//双击
System.out.println("双击");

}else if(e.getClickCount() == 1){//单击
//增加矩形
addRect();

}
} });
} public void addRect(){
//产生XY座标
int x = r.nextInt(60);
int x1 = x;
int y = r.nextInt(60);
int y1 = y; if(!isNotOverride(x1,y1)){//重叠,不能直接绘图
boolean flag = false;
outer: for(int i = 0; i < 60; i++){//穷举
for(int j = 0; j < 60; j++){
flag = isNotOverride(i,j);
if(flag){
x1 = i;
y1 = j;
break outer;//找到合适的地方,强行退出
}
}
}
if(!flag){//是找到合适的地方强行退出,还是找完了都有找到合适的地方
JOptionPane.showMessageDialog(null, "满了!");
return;
} } System.out.println("x:" + x1 + "\n y:" + y1);
Graphics g = c.getGraphics();
g.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255)));
g.fillRect(x1, y1, 20, 20);
Rect rect = new Rect(x1,y1);
list.add(rect);
} /**
 * 检查指定座标的矩形是否会产生重叠
 * @param x 横座标
 * @param y 纵座标
 * @return true 则不又重叠,false 重叠
 */
public boolean isNotOverride(int x, int y){
boolean flag = false;
if(list.size() == 0) return true;
for(Rect r : list){
if(x >= (r.getX() + 20) && (r.getX() + 20) < 60 || x <= (r.getX() - 20) && (r.getX() - 20) >= 0
|| y >= (r.getY() + 20) && (r.getY() + 20) < 60 || y <= (r.getY() - 20) && (r.getY() - 20) >= 0)
{
flag = true;
continue; }
else
{
flag = false;
break;
} }
return flag;
}
@Override
public void repaint() {
// TODO Auto-generated method stub
super.repaint();
} public static void main(String[] args){
new Ms1(); }}public class Rect {
private int x;
private int y;

public Rect(int x2, int y2) {
this.x = x2;
this.y = y2;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}

}

解决方案 »

  1.   


    public class HiwayTest6 extends JFrame{ private HiwayTest6 self;
    private JPanel panel;
    private JButton jb_add;
    private JButton jb_clear;
    private JButton jb_move;
    private int panelWidth = 100;
    private int panelHeight = 100;
    private int squareWidth = 20;
    private int squareHeight = 20;
    private Random rand = new Random();
    private ArrayList<Point> list = new ArrayList<Point>();
    private Graphics g ;
    private Location location = new Location();
    private MyListener listener;
    private int temp = 1;

    public static void main(String...args){
    HiwayTest6 ht = new HiwayTest6();
    ht.init();
    }
    public HiwayTest6(){
    super("Hiway's Demo");
    }
    private void init(){
    self = this;
    listener = new MyListener();
    self.setLayout(null);
    panel = new MyJPanel();
    panel.setBounds(0,0,panelWidth,panelHeight);
    panel.setBackground(Color.red);
    self.getContentPane().add(panel);
    jb_add = new JButton("add");
    jb_add.addMouseListener(listener);
    jb_add.setBounds(new Rectangle(10,120,80,25));
    jb_clear = new JButton("clear");
    jb_clear.addMouseListener(listener);
    jb_clear.setBounds(new Rectangle(100,120,80,25));
    jb_move = new JButton("move");
    jb_move.addMouseListener(listener);
    jb_move.setBounds(new Rectangle(210,120,80,25));
    self.getContentPane().add(jb_move);
    self.getContentPane().add(jb_add);
    self.getContentPane().add(jb_clear);
    self.setBounds(new Rectangle(100,100,300,200));
    self.setVisible(true);
    self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    g = self.panel.getGraphics();
    }

    private void drawSquare(Graphics g){
    g.setColor(Color.black);
    for(int i=0;i<list.size();i++){
    g.drawRect(list.get(i).x, list.get(i).y, squareWidth, squareHeight);
    }
    }
    private void moveUpAllSquare(Graphics g){
    int unmovableCount = 0 ;
    synchronized(self.list){
    while(true){
    unmovableCount = 0;
    for(int i=0;i<self.list.size();i++){
    // System.out.println(self.list.get(i).y +""+ self.overlap(self.list.get(i).x, self.list.get(i).y-1));
    if((self.list.get(i).y-1>=0) && (!self.overlap(self.list.get(i).x, self.list.get(i).y-1,i))){
    // System.out.println("第"+(i+1)+"個Square向上移動一個像素");
    self.list.get(i).y = self.list.get(i).y - 1;
    self.panel.repaint();
    }else{
    unmovableCount++;
    // System.out.println("第"+unmovableCount+"Square不能移動~ 共有"+list.size()+"個Square");
    }
    }
    if(unmovableCount == self.list.size()){
    System.out.println("所有的Square都不能再移動");
    break;
    }
    }
    }
    }
    // 判斷給定的點 x y 所形成的正方形是否會與已經存在的正方形重疊
    private boolean overlap(int x,int y){
    for(int i=0;i<list.size();i++){
    Rectangle oldRect = new Rectangle(list.get(i).x,list.get(i).y,squareWidth,squareHeight);
    Rectangle newRect = new Rectangle(x,y,squareWidth,squareHeight);
    if(oldRect.intersects(newRect)){
    return true;
    }
    }
    return false;
    }
    // 判斷給定的點x y 是否會與其它的正方形重疊(不包括指定的正方形)
    private boolean overlap(int x,int y,int excludeIndex){
    for(int i=0;i<list.size();i++){
    if(i==excludeIndex){
    continue;
    }
    Rectangle oldRect = new Rectangle(list.get(i).x,list.get(i).y,squareWidth,squareHeight);
    Rectangle newRect = new Rectangle(x,y,squareWidth,squareHeight);
    if(oldRect.intersects(newRect)){
    // System.out.println(excludeIndex+"與"+i+"重疊");
    return true;
    }
    }
    // System.out.println(excludeIndex+"與其它所有正方形都不重疊");
    return false;
    }

    private class MyListener extends MouseAdapter{
    @Override
    public void mouseReleased(MouseEvent e){
    if(e.getSource()==jb_add){
    if(e.getClickCount()==1){
    Point point = location.getRandomInstance();
    if(point==null){
    return ;
    }else{
    list.add(point);
    }
    // list.add(new Point(50*temp,20*temp));
    // temp++;
    // list.add(new Point(50*(temp-1),20*temp+30));
    drawSquare(g);
    System.out.println("新增一個Square");
    }
    /*if(e.getClickCount()==2){
    System.out.println("向上移動所有Square");
    moveUpAllSquare(g);
    }*/
    }
    if(e.getSource()==jb_clear){
    list.clear();
    repaint();
    }
    if(e.getSource()==jb_move){
    self.moveUpAllSquare(g);
    }
    }
    }

    private class Location{
    int x;
    int y;
    // 隨機產生一個不在已有區域的點
    public Point getRandomInstance(){
    while(true){
    if(this.isFull()){
    JOptionPane.showMessageDialog(null, "填充區域已滿", "提示", JOptionPane.INFORMATION_MESSAGE);
    return null;
    }
    this.x = rand.nextInt(panelWidth-squareWidth);
    this.y = rand.nextInt(panelHeight-squareHeight);
    // System.out.println("新產生的點:"+x+"\t"+y);
    // System.out.println(list);
    if(self.overlap(this.x,this.y)){
    // System.out.println("新產生的點在範圍內");
    continue;
    }
    // list.add(this);
    return new Point(x,y);
    }
    }
    // 判斷此區域是否填滿
    private boolean isFull(){
    for(int i=0;i<panelWidth-squareWidth;i++){
    for(int j=0;j<panelHeight-squareHeight;j++){
    if(!self.overlap(i, j)){//只要有一個還未重疊,說明該區域還未填滿
    return false;
    }
    }
    }
    return true;
    }
    }

    private class MyJPanel extends JPanel{
    @Override
    public void paint(Graphics g){
    super.paint(g);// must invoked
    self.drawSquare(g);
    }
    }
    }做了好长时间,关键就是画面的重绘要重写paint()这个方法~
    ps:为什么我在mouseReleased()中根据clickCount来调用不同的方法,但是双击两次还是会执行clickCount==1中的代码,难道是因为我的鼠标问题?
    无奈~ 重新加了一个button 
      

  2.   

    moveUpAllSquare()方法中 是不需要synchronized(self.list)的。
      

  3.   

    简单,我也是用Java做的这类动画效果:
    纯Java游戏引擎