我有很多建议,但首先...
您选择随机排名的方式已关闭...
int myX = randomNumber(0,(int)w);
int myY = randomNumber(0,(int)h);
这样可以生成重复的位置(以及重叠的单元格)
更新(使用布局管理器)
好的,这是范式的微小转变。而不是产生一个剪辑并将其传递给作品,我让作品可以选择如何渲染作品。相反,我将负责的矩形传递给了它。
这意味着,您可以简单地使用一些类似的东西setCell(Rectangle)来进行更改(除非您因拖放而下地狱;)
Board由于Java 7的一些有趣行为,我最终使用了panel,但这是另一个问题;)
package puzzel;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.*;
public class PuzzlePieceDriver extends JFrame {
public PuzzlePieceDriver(ImageIcon myPuzzleImage) {
setTitle("Hot Puzz");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(new Board(myPuzzleImage));
pack();
setVisible(true);
}//end constructor
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
ImageIcon image = new ImageIcon(PuzzlePieceDriver.class.getResource("/issue459.jpg"));
PuzzlePieceDriver driver = new PuzzlePieceDriver(image);
driver.setLocationRelativeTo(null);
driver.setVisible(true);
}
});
}
}//end class
一块面板...该面板会覆盖preferred和minimum尺寸方法...虽然在本示例中适用,但最好使用setPreferredSize和setMiniumumSize代替;)
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package puzzel;
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class PuzzlePiece extends JPanel {
private BufferedImage masterImage;
private Rectangle pieceBounds;
private BufferedImage clip;
public PuzzlePiece(BufferedImage image, Rectangle bounds) {
masterImage = image;
pieceBounds = bounds;
// Make sure the rectangle fits the image
int width = Math.min(pieceBounds.x + pieceBounds.width, image.getWidth() - pieceBounds.x);
int height = Math.min(pieceBounds.y + pieceBounds.height, image.getHeight() - pieceBounds.y);
clip = image.getSubimage(pieceBounds.x, pieceBounds.y, width, height);
}//end constructor
@Override
public Dimension getPreferredSize() {
return pieceBounds.getSize();
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 0;
int y = 0;
g.drawImage(clip, x, y, this);
g.setColor(Color.RED);
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
}//end paintComponent
}//end class PuzzlePiece
面板面板...主要是因为我在Java 7中遇到了一些有趣的问题...实现a MouseListener,当您运行程序时,单击面板,这很有趣;)
package puzzel;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
/**
*
* @author shane
*/
public class Board extends JPanel {
public static final int X_PIECES = 4;
public static final int Y_PIECES = 4;
private PuzzlePiece[] puzzle = new PuzzlePiece[X_PIECES * Y_PIECES];
private static BufferedImage image;
public Board(ImageIcon myPuzzleImage) {
image = iconToImage(myPuzzleImage); //pass image into bufferedImage form
puzzle = createClip();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
removeAll();
invalidate();
createClip();
// doLayout();
invalidate();
revalidate();
repaint();
}
});
}
public static BufferedImage iconToImage(ImageIcon icon) {
Image img = icon.getImage();
int w = img.getWidth(null);
int h = img.getHeight(null);
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
// Paint the image onto the buffered image
g.drawImage(img, 0, 0, null);
g.dispose();
return image;
}//end BufferedImage
protected int randomNumber(int min, int max) {
int temp = min + (int) (Math.random() * ((max - min) + 1));
return temp;
}//end randomNumber
private PuzzlePiece[] createClip() {
int cw, ch;
int w, h;
w = image.getWidth(null);
h = image.getHeight(null);
cw = w / X_PIECES;
ch = h / Y_PIECES;
// Generate a list of cell bounds
List lstBounds = new ArrayList<>(25);
for (int y = 0; y < h; y += ch) {
for (int x = 0; x < w; x += cw) {
lstBounds.add(new Rectangle(x, y, cw, ch));
}
}
BufferedImage clip = image;
setLayout(new GridBagLayout());
for (int x = 0; x < X_PIECES; x++) {
for (int y = 0; y < Y_PIECES; y++) {
// Get a random index
int index = randomNumber(0, lstBounds.size() - 1);
// Remove the bounds so we don't duplicate any positions
Rectangle bounds = lstBounds.remove(index);
PuzzlePiece piece = new PuzzlePiece(clip, bounds);
puzzle[x * X_PIECES + y] = piece;
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.fill = GridBagConstraints.BOTH;
add(piece, gbc);
piece.invalidate();
piece.repaint();
}//end nested for
}//end for
invalidate();
repaint();
return puzzle;
}//end createClip
}
现在,我知道您最终将要问有关如何移动零件的问题,GridBagLayout是否有一个名为getConstraints的出色方法,该方法使您可以检索用于布置有问题的组件的约束。然后,您可以修改gridx和gridy值,并使用setConstraints对其进行更新(别忘了调用invalidate和repaint;))
我建议阅读有关如何使用GridBagLayout的详细信息;)