// JavaProject SquarePuzzle

// SquarePuzzle.java
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
class IList extends LinkedList<Integer> { //
LinkedList
private static final long serialVersionUID = 0L;
public IList() {
new
LinkedList<>();
}
}
class Canvas extends JPanel implements Runnable {
private static final long serialVersionUID = 0L;
Thread intro;
private Rectangle2D.Float rectangle;
private DraggableSqr[] squ = new DraggableSqr[12];
private Color[] col = new Color[12];
private IList order = new IList();
// Mit der Liste order wird die aktuelle Reihenfolge festgelegt,
// in der die farbigen Quadrate gezeichnet werden.
private int act = 0;
// Der Wert von act entspricht der Nummer des momentan
// "aktiven" Quadrats. Der Wert 0 bedeutet:
// Kein Quadrat ist derzeit aktiv.
public Canvas() {
intro = new Thread(this);
setBackground(new Color(190, 190, 190));
rectangle = new Rectangle2D.Float(75, 46, 177, 176);
Adapter adapter = new Adapter();
addMouseMotionListener(adapter);
addMouseListener(adapter);
squ[1] = new DraggableSqr(75, 46, 99, 99);
squ[2] = new DraggableSqr(174, 46, 78, 78);
squ[3] = new DraggableSqr(75, 145, 77, 77);
squ[4] = new DraggableSqr(195, 124, 57, 57);
squ[5] = new DraggableSqr(152, 145, 43, 43);
squ[6] = new DraggableSqr(211, 181, 41, 41);
squ[7] = new DraggableSqr(152, 188, 34, 34);
squ[8] = new DraggableSqr(186, 197, 25, 25);
squ[9] = new DraggableSqr(174, 124, 21, 21);
squ[10] = new DraggableSqr(195, 181, 16, 16);
squ[11] = new DraggableSqr(186, 188, 9, 9);
col[1] = new Color(176, 15, 33);
col[2] = new Color(245, 222, 56);
col[3] = new Color(119, 155, 57);
col[4] = new Color(224, 203, 90);
col[5] = new Color(54, 122, 187);
col[6] = new Color(14, 67, 133);
col[7] = new Color(105, 15, 15);
col[8] = new Color(226, 117, 22);
col[9] = new Color(160, 41, 161);
col[10] = new Color(146, 187, 71);
col[11] = new Color(12, 23, 15);
order.add(0);
for (int i=1; i<12; i++) order.add(i);
intro.start();
}
@Override
public void run() {
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
squ[1].x = 201; squ[1].y = 144;
squ[2].x = 182; squ[2].y = 95;
squ[3].x = 105; squ[3].y = 179;
squ[4].x = 38; squ[4].y = 178;
squ[5].x = 17; squ[5].y = 98;
squ[6].x = 244; squ[6].y = 82;
squ[7].x = 55; squ[7].y = 155;
squ[8].x = 228; squ[8].y = 189;
squ[9].x = 141; squ[9].y = 169;
squ[10].x = 195; squ[10].y = 128;
squ[11].x = 303; squ[11].y = 118;
repaint();
}
class DraggableSqr extends Rectangle2D.Float {
private static final long serialVersionUID = 0L;
public DraggableSqr (float x, float y, float width, float height) {
setRect(x, y, width, height);
}
public boolean isHit(float x, float y) {
return contains(x, y);
}
public void changeX(float dx) {
this.x += dx;
}
public void changeY(float dy) {
this.y += dy;
}
public void changeWidth(float dw) {
this.width += dw;
}
public void changeHeight(float dh) {
this.height += dh;
}
}
private void defineRendering(Graphics2D g) {
RenderingHints rh;
rh = new RenderingHints (
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
g.setRenderingHints(rh);
}
private void drawShapes(Graphics2D g) {
// zeichnet die elf Quadrate in der durch order
// festgelegten Reihenfolge
for (int i=1; i<12; i++) {
g.setPaint(col[order.get(i)]);
g.fill(squ[order.get(i)]);
}
}
private void draw(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
defineRendering(g2d);
g2d.setPaint(new Color(245, 245, 245));
g2d.fill(rectangle);
drawShapes(g2d);
g2d.dispose();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
class Adapter extends MouseAdapter {
private int x;
private int y;
@Override
public void mousePressed(MouseEvent e) {
// Wo wurde eine Maustaste gedrückt?
x = e.getX();
y = e.getY();
// Welches der farbigen Quadrate wurde angeklickt?
for (int i=1; i<12; i++)
if (squ[order.get(i)].isHit(x, y))
act = order.get(i);
}
@Override
public void mouseDragged(MouseEvent e) {
handleDuringDragging(e);
}
@Override
public void mouseReleased(MouseEvent e) {
act = 0;
}
private void moveActiveRectangle(int dx, int dy) {
if (act != 0) {
squ[act].changeX(dx);
squ[act].changeY(dy);
repaint();
}
}
private boolean haveCommonArea(DraggableSqr a, DraggableSqr b) {
// prüft, ob sich die Quadrate a und b überlappen oder nicht
boolean result = false;
if (a.intersects(b.x, b.y, b.width, b.height)) result = true;
return result;
}
private int getIndex(int n) {
// ermittelt die Position des Quadrates mit der Nummer n in der Liste order
int position = 0;
for (int i=1; i<12; i++) if (order.get(i) == n) position = i;
return position;
}
private IList getOverlappingSquares(int n) {
IList list = new IList();
if (n == act) {
for (int i = getIndex(n)+1; i<12; i++) {
if (haveCommonArea(squ[n], squ[order.get(i)]))
list.add(order.get(i));
}
} else {
for (int i = getIndex(act)+1; i<getIndex(n)+1; i++) {
if (haveCommonArea(squ[n], squ[order.get(i)]))
list.add(order.get(i));
}
}
return list;
}
private IList getBundledSquares() {
// liefert eine Liste aller aktuell mit dem aktiven Quadrat
// zusammenhängenden Quadrate zurück, wobei nur solche
// Quadrate berücksichtigt werden, die n a c h dem aktiven
// Quadrat gezeichnet wurden
IList list = new IList();
boolean isBundled;
int act_index = getIndex(act);
for (int i = act_index+1; i<12; i++) {
isBundled = false;
for (int j = 0; j<list.size(); j++)
if (haveCommonArea(squ[list.get(j)], squ[order.get(i)]))
isBundled = true;
if (haveCommonArea(squ[act], squ[order.get(i)]))
isBundled = true;
if (isBundled) list.add(order.get(i));
}
return list;
}
private void renewOrder(Integer act, Integer n) {
// ändert die Reihenfolge, in welcher die
// Quadrate gezeichnet werden
int act_index = getIndex(act);
int n_index = getIndex(n);
IList bundledsquares = getBundledSquares();
order.remove(act);
order.add(n_index, act);
int k = act_index;
while (k < getIndex(n)) {
Integer ik = order.get(k);
if (bundledsquares.contains(ik)) {
order.remove(ik);
order.add(n_index, ik);
}
else k++;
}
}
private void handleDuringDragging(MouseEvent e) {
if (act != 0) {
int dx = e.getX() - x;
int dy = e.getY() - y;
int act_index = getIndex(act);
int n_index;
Integer n;
IList oldlist = getOverlappingSquares(act);
moveActiveRectangle(dx, dy);
IList newlist = getOverlappingSquares(act);
for (int i=0; i<newlist.size(); i++) {
n = newlist.get(i);
n_index = getIndex(n);
if (!oldlist.contains(n)) {
// n ist nun die Nummer des aktuell
// neu getroffenen Quadrates
IList list = getOverlappingSquares(n);
boolean ordertochange = true;
for (int j=act_index+1; j<n_index; j++) {
Integer squj = order.get(j);
if ((list.contains(squj))&&(oldlist.contains(squj))) {
ordertochange = false;
break;
}
}
if (ordertochange) renewOrder(act, n);
}
}
x += dx;
y += dy;
if (x < 1) squ[act].x = 1;
if (x > 332) squ[act].x = 332 - squ[act].width;
if (y < 1) squ[act].y = 1;
if (y > 262) squ[act].y = 262 - squ[act].height;
}
}
}
}
class CFrame extends JFrame {
private static final long serialVersionUID = 0L;
Image icon;
public CFrame() {
setTitle("Quadratpuzzle");
icon = Toolkit.getDefaultToolkit().getImage("dh.png");
setIconImage(icon);
setSize(349, 301);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
setBackground(Color.LIGHT_GRAY);
add(new Canvas());
setVisible(true);
}
}
public class SquarePuzzle {
public static void main(String[] args) {
new CFrame();
}
}
Download SquarePuzzle