URGENT IMPORTANT PLEASE HELP in this program you are to cre
URGENT - IMPORTANT PLEASE HELP!
in this program, you are to create a Java application that produces a colored mosaic of tiles. The form your application produces should look like this:
Whenever the user presses the button, the arrangement of tiles must change at random.
You will need to define the following classes.
Tile
Represents one of the shapes shown in the picture. Each tile can be circular or square. Each tile will have a color and a letter that it shows. Each tile will be placed in a particular row or column, so each tile object must keep track of those values, too. The Tile class must have a toString function that lists the various attributes of the tile, including its type, row, column, associated letter, and the red, green, and blue components of its color.
TileFrame
The heavyweight component that houses the panel of tiles as well as another panel that features the Randomize button.
TilePanel
The panel that occupies most of the TileFrame and paints and displays the set of tiles. Its paintComponent function will be responsible for rendering each tile in its proper place.
TilePrinter
A class that has a function called print that takes in an array of Tiles and prints them to System.out by calling toString on each Tile.
TileRandomizer
A class that has functions for building a tile with random parameters, for changing an existing tile’s attributes to random values, and for changing the attributes of an entire array of tiles. You could call those functions buildTile, changeTile, and changeTiles, respectively.
The Randomize Button could be a run-of-the-mill JButton, or it could be a JButton descendant. You must write an ActionListener either as an anonymous class or a named one that will randomize the tiles in the mosaic when the button is pressed.
The program will be graded as follows:
The Tile class has all necessary parameters properly declared, at least two constructors, all necessary get and set functions, and a toString function that returns a comma-separated String that shows the tile’s shape, row, column, letter, and color components.
5 points
The TilePrinter class has a function called print that writes the toString representation of each tile to System.out.
2 points
The TileRandomizer class has functions buildTile, changeTile, and changeTiles. buildTile creates a new Tile with random parameters. changeTile takes an existing tile and changes its letter, color, and shape.
3 points
The TileFrame class holds two panels, a TilePanel and another panel that contains the “Randomize” button. It has a BorderLayout to arrange them.
3 points
The TilePanel’s paintComponent function draws all the tiles in the proper location with the proper colors and with the correct letters. The letters must be centered and rendered in a color that makes them visible.
4 points
When the Randomize button is clicked, the tiles are shuffled so that a new pattern emerges. This is accomplished using TileRandomizer’s changeTiles function.
3 points
The main function creates an array of 100 tiles. It creates and uses a TilePrinter to print the tiles to System.out. It creates and shows the TileFrame to display the tiles.
3 points
The code is sufficiently commented.
1 point
Your program is submitted as Tiles_LastName.java.
1 point
| Tile | Represents one of the shapes shown in the picture. Each tile can be circular or square. Each tile will have a color and a letter that it shows. Each tile will be placed in a particular row or column, so each tile object must keep track of those values, too. The Tile class must have a toString function that lists the various attributes of the tile, including its type, row, column, associated letter, and the red, green, and blue components of its color. |
| TileFrame | The heavyweight component that houses the panel of tiles as well as another panel that features the Randomize button. |
| TilePanel | The panel that occupies most of the TileFrame and paints and displays the set of tiles. Its paintComponent function will be responsible for rendering each tile in its proper place. |
| TilePrinter | A class that has a function called print that takes in an array of Tiles and prints them to System.out by calling toString on each Tile. |
| TileRandomizer | A class that has functions for building a tile with random parameters, for changing an existing tile’s attributes to random values, and for changing the attributes of an entire array of tiles. You could call those functions buildTile, changeTile, and changeTiles, respectively. |
Solution
import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.imageio.ImageIO;
import mosaic.palettegenerator.ColorPaletteGenerator;
import mosaic.palettegenerator.ImageBasedColorPaletteGenerator;
public class MosaicGenerator {
private static final String OUTPUT_EXTENSION = \"png\";
public void run(String inputUrl, String outputDirectory, List<Integer> colorCounts, List<Integer> widths) throws MalformedURLException, IOException {
BufferedImage rawImage = ImageIO.read(new URL(inputUrl));
BufferedImage compositeImage = generateCompositeMosaic(rawImage, colorCounts, widths, new ImageBasedColorPaletteGenerator(rawImage));
String outputFilename = getOutputFilename(inputUrl);
File outputFile = new File(outputDirectory, outputFilename);
outputFile.mkdirs();
System.out.println(\"Writing mosaic: \" + outputFile.getAbsolutePath());
ImageIO.write(compositeImage, OUTPUT_EXTENSION, outputFile);
}
public BufferedImage generateCompositeMosaic(BufferedImage sourceImage, List<Integer> colorCounts, List<Integer> widths, ColorPaletteGenerator paletteGenerator) {
int labelOffsetY = 10;
int cellWidth = Collections.max(widths);
int cellHeight = cellWidth * sourceImage.getHeight() / sourceImage.getWidth();
int containerWidth = cellWidth * widths.size();
int containerHeight = cellHeight * colorCounts.size();
BufferedImage outImage = new BufferedImage(containerWidth, containerHeight, sourceImage.getType());
Graphics graphics = outImage.getGraphics();
int destX1 = 0, destY1 = 0, destX2 = cellWidth, destY2 = cellHeight, srcX1 = 0, srcY1 = 0, srcX2 = 0, srcY2 = 0;
for (Integer colorCount : colorCounts) {
destX1 = 0;
List<Color> colors = paletteGenerator.generateColorPalette(colorCount);
for (Integer width : widths) {
BufferedImage tileImage = generateMosaic(sourceImage, width, colors);
srcX2 = tileImage.getWidth();
srcY2 = tileImage.getHeight();
graphics.drawImage(tileImage, destX1, destY1, destX2, destY2, srcX1, srcY1, srcX2, srcY2, null);
graphics.drawString(srcX2 + \"x\" + srcY2 + \"-\" + colorCount + \"color\", destX1, destY1 + labelOffsetY);
destX1 = destX2;
destX2 += cellWidth;
}
destY1 = destY2;
destY2 += cellHeight;
destX2 = cellWidth;
}
return outImage;
}
public BufferedImage generateMosaic(BufferedImage sourceImage, int width, List<Color> colors) {
BufferedImage mosaic = colorImage(scaleImage(sourceImage, width), colors);
return mosaic;
}
public BufferedImage scaleImage(BufferedImage image, int targetWidth) {
double scaleFactor = ((double) targetWidth) / image.getWidth();
AffineTransform scaleTrans = AffineTransform.getScaleInstance(scaleFactor, scaleFactor);
AffineTransformOp scaleOp = new AffineTransformOp(scaleTrans, AffineTransformOp.TYPE_BILINEAR);
int scaledWidth = (int) (image.getWidth() * scaleFactor);
int scaledHeight = (int) (image.getHeight() * scaleFactor);
BufferedImage scaledImage = scaleOp.filter(image, new BufferedImage(scaledWidth, scaledHeight, image.getType()));
return scaledImage;
}
/**
* Generate an image containing only the colors in the specified palette.
*/
private BufferedImage colorImage(BufferedImage image, List<Color> availableColors) {
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
Color c = new Color(image.getRGB(x, y));
image.setRGB(x, y, getNearestColor(c, availableColors).getRGB());
}
}
return image;
}
/**
* Find the closest color in the palette to the specified target color.
*/
private Color getNearestColor(Color targetColor, List<Color> availableColors) {
Color closestColor = null;
int minDistance = Integer.MAX_VALUE;
for (Color color : availableColors) {
int distance = getDistance(targetColor, color);
if (distance < minDistance) {
closestColor = color;
minDistance = distance;
}
}
return closestColor;
}
/**
* Find the Euclidean distance between two colors.
*/
private int getDistance(Color c1, Color c2) {
int distance = (int) Math.sqrt((double) Math.pow(c2.getRed() - c1.getRed(), 2) + Math.pow(c2.getGreen() - c1.getGreen(), 2) + Math.pow(c2.getBlue() - c1.getBlue(), 2));
return distance;
}
/**
* Create a filename for a mosaic
* e.g. mosaic-IMG_1913-20130817-084938.png
*/
private String getOutputFilename(String inputUrl) {
try {
String filename = (new File(inputUrl).getName()); // eg IMG_1913.jpg
String filenameBase = filename.split(\"\\\\.\")[0]; // eg IMG_1913
String date = new SimpleDateFormat(\"yyyyMMdd-hhmmss\").format(new Date());
return \"mosaic-\" + filenameBase + \"-\" + date + \".\" + OUTPUT_EXTENSION;
} catch (Exception e) {
System.out.println(\"Error while generating output filename. Resorting to default.\");
e.printStackTrace();
return \"mosaic-\" + System.currentTimeMillis() + \".\" + OUTPUT_EXTENSION;
}
}
}



