我在练习中尝试将一组图片对象放到ArrayList中,然后随机地对它们进行洗牌,并将它们显示为一个3x3的网格。但是,shuffle方法对我来说不能正常工作。或者也许我在draw或drawImage方法中做错了什么,我不知道。我总是得到图片显示从9件在他们的原始顺序,而不是随机洗牌。
请看下面我的PicturePiece类以及主类。
package lab;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import javax.imageio.ImageIO;
public class PicturePiece {
private int IMAGE_X = 266;
private int IMAGE_Y = 224;
private final int row;
private final int col;
private Image img;
private static int count = 0;
private int id = 0;
public PicturePiece(int row, int col, File f) {
try {
this.img = ImageIO.read(f);
} catch (Exception e) {
e.printStackTrace();
}
this.row = this.IMAGE_X * row;
this.col = this.IMAGE_Y * col;
PicturePiece.count++;
this.id = PicturePiece.count;
}
public void draw(Graphics2D g2) {
g2.drawImage(this.img, this.row, this.col, null);
}
public void setPosition(int row, int col) {
this.IMAGE_X = row;
this.IMAGE_Y = col;
}
public int getXposition() {
return this.IMAGE_X;
}
public int getYposition() {
return this.IMAGE_Y;
}
public int getRow() {
return this.row;
}
public int getCol() {
return this.col;
}
public String getImage() {
return this.img.toString();
}
public static int getPictureCount() {
return PicturePiece.count;
}
public int getId() {
return this.id;
}
}下面是我的主类:
/*从互联网上找到一个漂亮的图像,并使用图像编辑器将其分解为9个部分(例如,您可以在Windows中使用应用程序Paint )。在3×3网格中以随机顺序显示9个图像。添加鼠标侦听器。允许用户通过单击来交换两个图像。游戏的目标是重新创建原始图像。当用户获胜时显示相应的消息。*/
package lab;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.*;
public class Puzzle {
public static void main(String[] args) throws Exception {
MyFrame frame = new MyFrame();
frame.setSize(1000, 1000);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MyFrame extends JFrame {
MyPanel p;
public MyFrame() {
p = new MyPanel();
add(p);
setVisible(true);
}
}
class MyPanel extends JPanel {
private ArrayList<PicturePiece> images = new ArrayList<PicturePiece>();
public MyPanel() {
this.setFocusable(true);
try {
int j = 0, k = 0, pocet = 0;
for (int i = 1; i <= 9; i++) {
//g2.drawImage(images.get(i), (IMAGE_X * (j)), (IMAGE_Y * (k)), null);
images.add(new PicturePiece(j, k, new File(("/home/ivo/Pictures/domcek/domcek" + i + ".jpg"))));
pocet++;
//System.out.println("j = " + (j - 1) + "; k = " + (k - 1) + "; i = " + i + "; pocet = " + pocet);
if ((pocet % 3) == 0) {
j = 0;
k++;
} else {
j = j + 1;
}
}
} catch (Exception e) {
}
//Random rnd = new Random();
//rnd.setSeed(400);
//Collections.shuffle(images, rnd);
Collections.shuffle(images);
}
public void draw(Graphics2D g2) {
try {
for (int i = 0; i <= images.size(); i++) {
images.get(i).draw(g2);
}
} catch (Exception my) {
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
draw(g2);
}
}发布于 2015-03-02 20:47:48
发布于 2015-03-02 20:55:58
问题是,您基于初始化坐标绘制图像,即使您将它们置乱,PicturePiece对象中的坐标也保持不变。
简短的解决方案:
PicturePiece中的更改:
public void draw(Graphics2D g2, int i, int j) {
g2.drawImage(this.img, this.IMAGE_X *i, this.IMAGE_Y * j, null);
}拼图中的变化:
public void draw(Graphics2D g2) {
try {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.println(i*3+j);
images.get(i*3+j).draw(g2, i ,j);
}
}
} catch (Exception my) {
}
}注意:这是一个硬编码版本(只适用于3x3矩阵),但我希望你得到了ideea。有许多其他的解决方案,但这是我能想到的最短的一个。
发布于 2015-03-02 22:20:04
明智的做法是使用JLabel,而不是在JPanel/JComponent上绘制,这将使您的工作变得更容易,因为您只需关心索引位置。
这里有一个例子:
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class TestingImages {
private static final String IMAGE_HEADER = "/images/windowicon/windowicon";
private GUIView guiView;
private void performTask () {
try {
guiView = new GUIView (IMAGE_HEADER);
} catch (Exception exp) {
exp.printStackTrace ();
}
Runnable runnable = new Runnable () {
@Override
public void run () {
guiView.displayGUI ();
}
};
EventQueue.invokeLater (runnable);
}
public static void main (String[] args) {
new TestingImages ().performTask ();
}
}
class GUIView {
private static final int ROWS = 3;
private static final int COLUMNS = 3;
private static final int GAP = 5;
private static final int TOTAL_IMAGES = 9;
private JLabel originalImageLabel;
private JLabel[] splitImageLabel;
private int counter;
private int[] imageMap;
private int previousIndex;
private int currentIndex;
private MouseAdapter labelAdapter = new MouseAdapter () {
private int counter = 0;
@Override
public void mouseClicked (MouseEvent me) {
JLabel label = (JLabel) me.getSource ();
if (counter == 0) {
/*
* On first click, we simply keeping track of on which label
* the user clicked in the first place
*/
previousIndex = findLabelIndex (label);
System.out.println("Previous Index: " + previousIndex);
counter = 1;
} else if (counter == 1) {
/*
* On second click, firstly we will get the location of the JLabel
* on which the user clicked, then we will simply swap the icon as
* well as the Name of this JLabel with the JLabel at previousIndex
*/
currentIndex = findLabelIndex (label);
System.out.println("Current Index: " + currentIndex);
ImageIcon tempIcon = (ImageIcon) splitImageLabel[previousIndex].getIcon ();
splitImageLabel[previousIndex].setIcon (splitImageLabel[currentIndex].getIcon ());
splitImageLabel[currentIndex].setIcon (tempIcon);
String labelName = splitImageLabel[previousIndex].getName ();
splitImageLabel[previousIndex].setName (splitImageLabel[currentIndex].getName ());
splitImageLabel[currentIndex].setName (labelName);
prepareModel ();
counter = 0;
}
if (hasWon()) {
System.out.println("CONGRATULATIONS you won :-)");
}
}
};
public GUIView (String imageHeader) throws IOException {
imageMap = new int[TOTAL_IMAGES];
counter = 0;
originalImageLabel = new JLabel ();
originalImageLabel.setIcon (new ImageIcon (
ImageIO.read (GUIView.class.getResource (
imageHeader + ".jpg"))));
splitImageLabel = new JLabel[TOTAL_IMAGES];
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLUMNS; ++j) {
splitImageLabel[counter] = new JLabel ();
String indexValue = "" + counter;
/*
* Since JLabel[] is a 1-D Array, hence we simply giving
* each JLabel, at each index a name, as 0 1 2 3 and so on
*/
splitImageLabel[counter].setName (indexValue);
splitImageLabel[counter].setIcon (new ImageIcon (ImageIO.read (
GUIView.class.getResource (imageHeader + i + "-" + j + ".png"))));
splitImageLabel[counter].addMouseListener (labelAdapter);
++counter;
}
}
}
public void displayGUI () {
JFrame frame = new JFrame("Testing Images");
frame.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel ();
contentPane.setBorder (BorderFactory.createEmptyBorder (GAP, GAP, GAP, GAP));
contentPane.setLayout (new GridLayout (2, 1, GAP, GAP));
JPanel headerPanel = new JPanel ();
headerPanel.setBorder (BorderFactory.createEmptyBorder (GAP, GAP, GAP, GAP));
headerPanel.add (originalImageLabel);
contentPane.add (headerPanel);
JPanel footerPanel = new JPanel ();
footerPanel.setBorder (BorderFactory.createEmptyBorder (GAP, GAP, GAP, GAP));
footerPanel.setLayout (new GridLayout (ROWS, COLUMNS, GAP, GAP));
/*
* This will Shuffle the JLable[] array
*/
Collections.shuffle (Arrays.asList (splitImageLabel));
prepareModel ();
for (int i = 0; i < TOTAL_IMAGES; ++i) {
footerPanel.add (splitImageLabel[i]);
}
contentPane.add (footerPanel);
frame.setContentPane (contentPane);
frame.pack ();
frame.setLocationByPlatform (true);
frame.setVisible (true);
}
private int findLabelIndex (JLabel label) {
int index = 0;
for (int i = 0; i < TOTAL_IMAGES; ++i) {
if (label.getName ().equals(splitImageLabel[i].getName ())) {
index = i;
break;
}
}
return index;
}
/*
* hasWon() is used to simply check, if the array has values
* 0 1 2 3 4 till TOTAL_IMAGES, i.e. in increasing order, then it
* means, that the image has been rightly placed, by the user.
* Hence, the GAME is OVER
*/
private boolean hasWon () {
boolean flag = true;
for (int i = 0; i < TOTAL_IMAGES; ++i) {
if (imageMap[i] != i) {
flag = false;
}
}
return flag;
}
/*
* PrepareModel() is used to assign values to imageMap[] array,
* in the same sequence, in which the JLabel is placed inside
* JLabel[] array. Say JLabel[] array has JLabels with names in
* this order 1 5 4 3 and so on, thus imageMap[] will contain
* values 1 5 4 3 and so on, once they are in sorted order, then
* we can easily check for winning condition
*/
private void prepareModel () {
System.out.println("Preparing MODEL");
for (int i = 0; i < TOTAL_IMAGES; ++i) {
imageMap[i] = getIntValue(splitImageLabel[i].getName ());
System.out.println("i: " + i + " Name: " + splitImageLabel[i].getName ());
}
System.out.println("Exiting MODEL");
}
private int getIntValue (String text) {
int value = 0;
try {
value = Integer.parseInt (text);
} catch (Exception exp) {
exp.printStackTrace ();
}
return value;
}
}输出:



使用的图像:
https://stackoverflow.com/questions/28809341
复制相似问题