PaintIcon no longer letting me paint images - java

So I'm just exploring java and trying to make a procedural map for fun but when I started picking random spots in my array to set as a certain image it will no longer paint. The problem only occurs in the last for loop and occurs on:
if(world[c][r] == 2)
or
mountain.paintIcon(this, g, r*Run2.distBetweenTiles, c*Run2.distBetweenTiles);
I removed the starting grass and water to see if it was getting painted under but that's not the case, it's just never getting painted. If anyone could enlighten me that'd be great!
Pics Used: , ,
P.S. Run2.rowSize, Run2.colSize, Run2.distBetweenTiles = 20 (All Static)
import java.io.IOException;
import java.util.Properties;
import javax.swing.JFrame;
public class Run2
{
public static final int rowSize = 20;
public static final int colSize = 20;
public static final int distBetweenTiles = 20;
public static void main (String [] args) throws IOException
{
JFrame frame = new JFrame();
WorldCreation2 panel = new WorldCreation2();
frame.add(panel);
frame.setTitle("RandomScape");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1280, 720);
frame.setVisible(true);
frame.setResizable(false);
Properties properties = new Properties();
properties.setProperty("Health", "20");
System.out.println(properties.getProperty("Health"));
}
}
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
public class WorldCreation2 extends JComponent
{
private static final long serialVersionUID = 1L;
int rowAmount, colAmount;
int[][] world;
int islandAmount = 3;
ArrayList<Point> islandStartingPositions = new ArrayList<Point>();
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
int rowAmount, colAmount;
int randomRow, randomCol;
ImageIcon water = new ImageIcon("C:\\Users\\CJ Petruzzelli\\Pictures\\Water 20x20.jpg");
ImageIcon grass = new ImageIcon("C:\\Users\\CJ Petruzzelli\\Pictures\\Grass 20x20.jpg");
ImageIcon mountain = new ImageIcon("C:\\Users\\CJ Petruzzelli\\Pictures\\Mountain 20x20.jpg");
colAmount = height/Run2.colSize;
rowAmount = width/Run2.rowSize;
world = new int[colAmount][rowAmount];
//System.out.println(rowAmount + " , " + colAmount);
Random rand = new Random();
//Initialize all values to default 0
for(int r = 0; r < rowAmount; r++)
{
for(int c = 0; c < colAmount; c++)
{
//Sets tiles to 0 so full array is instantiated
world[c][r] = 0;
grass.paintIcon(this, g, r*Run2.distBetweenTiles, c*Run2.distBetweenTiles);
}
}
////Puts water on all edges of the map
for(int r = 0; r < rowAmount; r++)
{
for(int c = 0; c < colAmount; c++)
{
//Left Side, Right Side, Top Side, Bottom Side
if(r == 0 && c < colAmount || r == rowAmount-1 && c < colAmount || r < rowAmount && c == 0 || r < rowAmount && c == colAmount-1)
{
world[c][r] = 1;
water.paintIcon(this, g, r*Run2.distBetweenTiles, c*Run2.distBetweenTiles);
}
}
}
//Pick starting points
int islandStartingPointNum = 0;
for(int t = islandAmount; t > 0; t--)
{
//Pick a random square (Cannot be an edge tile)
randomRow = rand.nextInt(rowAmount-1)+1;
randomCol = rand.nextInt(colAmount-1)+1;
String rowString = String.valueOf(randomRow);
String colString = String.valueOf(randomCol);
if(world[randomCol][randomRow] == 1)
{
System.out.println(colString + " , " + rowString + " This is an edge tile");
islandAmount++;
}
else
{
System.out.println(colString + " , " + rowString + " This is a grass tile, turning to mountain");
world[randomCol][randomRow] = 2;
islandAmount--;
//Store it
islandStartingPositions.add(new Point(randomCol, randomRow));
}
System.out.println(islandStartingPositions.get(islandStartingPointNum));
islandStartingPointNum++;
}
//Turn starting points into something
for(int r = 0; r < rowAmount; r++)
{
for(int c = 0; c < colAmount; c++)
{
if(world[c][r] == 2) // Checking number of location not current locations number?
{
System.out.println("This is a mountain tile");
mountain.paintIcon(this, g, r*Run2.distBetweenTiles, c*Run2.distBetweenTiles);
}
}
}
}
}

Here is a quick example of adding tiles to a JComponent.
If you need more help, post an MCVE of you problem. It should be something like this:
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Run2
{
public static void main (String [] args) throws IOException
{
JFrame frame = new JFrame();
frame.add( new WorldCreation2());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class WorldCreation2 extends JComponent
{
private int rows = 15, cols = 10;
private URL[] urls = { //use embedded resources for posting question
getUrl("http://static.coach.com/aapz_prd/on/demandware.static/-/Library-Sites-globalLibrary/default/dw1777ce46/201708/canada-wwcm/close_grey.png"),
getUrl("https://s7d2.scene7.com/is/image/JCPenney/DP0423201517014421S.jpg?wid=20&hei=20&op_usm=.4,.8,0,0&resmode=sharp2"),
getUrl("https://i2.wp.com/www.todaytells.com/wp-content/uploads/2018/07/new-and-ongoing-cinema-releases-uk-ire-from-thu-jul-12.jpg?fit=20%2C20&ssl=1")
};
public WorldCreation2() {
setLayout(new GridLayout(rows, cols));
for(int row = 0; row < rows; row++) {
for(int col = 0; col < cols; col++) {
if(row < 5)
{
add(getTile(urls[0]));
}else if (row < 10) {
add(getTile(urls[1]));
}else {
add(getTile(urls[2]));
}
}
}
}
private JLabel getTile(URL url){
return new JLabel(new ImageIcon(url));
}
private URL getUrl(String path) {
URL url = null;
try {
url = new URL(path);
} catch (MalformedURLException ex) { ex.printStackTrace(); }
return url;
}
}

Related

(JAVA battleships) button/image grid works fine but when I add a second grid next to it they both get messed up

I'm creating a battleships program for java. Using a gridlayout I want to have the player board in the west panel and NPC board in the east panel (as well as some other info and means of input in the centre panel and the south panel).
I started by adding the players board like follows (full code can be found at the bottom of this post as well):
public void placePlyrGrids()
{
plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
for(n = 0; n < 10; n++)
plyrBoard.add(letterGridLabels[n]); //the first row is the first 10 letters of the alphabet
for (y = 1; y < 11; y++) //For every (y) row...
{
for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
{
if (x == 0) //To the start of each row, add a number (image JLabel)
{
plyrBoard.add(numberGridLabels[numberCounter]);
numberCounter++;
}
else //for the rest of each row, add buttons
{
plyrBoard.add(buttonGrids[y-1][x-1]);
}
}
}
}
This worked fine.
Then I tried adding the dealer board in two ways, none of which seemed to work, as they both got messed up, and seemed to mess up the player board as well which had seemed to work fine on its own.
1: Placing both boards simultaneously in the same method.
public void placeBoards()
{
plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
NPCBoard.add(cornerGridLabel);
for(n = 0; n < 10; n++)
plyrBoard.add(letterGridLabels[n]); //the first row is the first 10 letters of the alphabet
NPCBoard.add(letterGridLabels[n]);
for (y = 1; y < 11; y++) //For every (y) row...
{
for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
{
if (x == 0) //To the start of each row, add a number (image JLabel)
{
plyrBoard.add(numberGridLabels[numberCounter]);
NPCBoard.add(numberGridLabels[numberCounter]);
numberCounter++;
}
else //for the rest of each row, add buttons
{
plyrBoard.add(buttonGrids[y-1][x-1]);
NPCBoard.add(emptyGridLabel);
}
}
}
}
2: Placing both each in a different method (used in combination with the pladePlyrGrids method at the top)
public void placeNPCGrids()
{
NPCBoard.add(cornerGridLabel);
for(n = 0; n < 10; n++)
NPCBoard.add(letterGridLabels[n]);
for (y = 1; y < 11; y++)
{
for (x = 0; x < 11; x++)
{
if (x == 0)
{
NPCBoard.add(numberGridLabels[numberCounter]);
numberCounter++;
}
else
{
NPCBoard.add(emptyGridLabel);
}
}
}
}
My full code:
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Battleships {
public static void main(String[] args)
{
Interface Win = new Interface ();
}
}
class Interface extends JFrame implements ActionListener
{
//Identify variables
int n;
int numberCounter = 0;
int y;
int x;
// lengths of the various ships in the game
//ADD IMAGE COMPONENTS
//Coordinate axes and empty grids
ImageIcon emptyGrid = new ImageIcon("EmptyGrid.png");
ImageIcon cornerGrid = new ImageIcon("CornerGrid.png");
ImageIcon [] numberGrids = new ImageIcon[11];
{
for (n = 0; n < 11; n ++)
numberGrids[n] = new ImageIcon("Grid" + (n + 1) + ".png");
}
ImageIcon [] letterGrids = new ImageIcon [11];
{
for (n = 0; n < 11; n ++)
letterGrids[n] = new ImageIcon("GridA" + (n + 1)+ ".png");
}
//Ship parts
//Clickable ships (for placement)
ImageIcon fullBattleship = new ImageIcon("FullBattleship.png");
ImageIcon fullCruiser = new ImageIcon("FullCruiser.png");
ImageIcon fullPatrolBoat1 = new ImageIcon("FullPatrolBoat.png");
ImageIcon fullPatrolBoat2 = new ImageIcon("FullPatrolBoat.png");
//JLabels
JLabel cornerGridLabel = new JLabel(cornerGrid);
JLabel [] numberGridLabels = new JLabel[10];
{
//The first 11 grids are an empty grid followed by letters A-J
for (n = 0; n < 10; n++)
{
numberGridLabels[n] = new JLabel(numberGrids[n]);
}
}
JLabel [] letterGridLabels = new JLabel [10];
{
for (n = 0; n < 10; n ++)
{
letterGridLabels[n] = new JLabel (letterGrids[n]);
}
}
JLabel emptyGridLabel = new JLabel(emptyGrid);
JButton [][] buttonGrids = new JButton [10][10];
{
for (y = 0; y < 10; y++)
{
for (x = 0; x < 10; x++)
{
buttonGrids[x][y] = new JButton(emptyGrid);
buttonGrids[x][y].setPreferredSize(new Dimension(50,50));
}
}
}
JLabel [] NPCGrids = new JLabel[121]; //grid placements for the dealer board
{
for (n = 0; n < 121; n ++)
NPCGrids[n] = new JLabel (emptyGrid);
}
JLabel [] clickableBoats = new JLabel [4];
{
clickableBoats[0] = new JLabel (fullBattleship);
clickableBoats[1] = new JLabel (fullCruiser);
clickableBoats[2] = new JLabel (fullPatrolBoat1);
clickableBoats[3] = new JLabel (fullPatrolBoat2);
}
JButton [] plyrClickableGrids = new JButton [100];
{
for (n = 0; n < 99; n++);
plyrClickableGrids[n] = new JButton(emptyGrid);
}
//Add interface components
JTextArea playerInformation = new JTextArea(20,5);
JScrollPane textPane1 = new JScrollPane (playerInformation);
JButton playTurnBtn = new JButton ("Play Turn");
//add JPanels
JPanel plyrBoard = new JPanel (new GridLayout(11,11));
JPanel infoPanel = new JPanel(new GridLayout(1,1));
JPanel NPCBoard = new JPanel(new GridLayout(11,11));
JPanel inputPanel = new JPanel(new GridLayout(1,10));
public Interface ()
{
super ("Battleships");
setSize (1367,729);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//Set the background color
Container contentArea = getContentPane();
//Set each panel to "opaque", so that the background becomes visible
plyrBoard.setOpaque(false);
NPCBoard.setOpaque(false);
inputPanel.setOpaque(false);
setVisible (true);
playerInformation.setEditable(false);
//Add panels to different compass points on the content area
contentArea.add("West", plyrBoard);
contentArea.add("Center", infoPanel);
contentArea.add("East", NPCBoard);
contentArea.add("South", inputPanel);
//Add imageLabels and buttons to panels
placePlyrGrids();
numberCounter = 0;
placeNPCGrids();
infoPanel.add(playerInformation);
for (n = 0; n < 4; n++)
{
inputPanel.add(clickableBoats[n]);
}
inputPanel.add(playTurnBtn);
// TODO Vanity
//Button format
playTurnBtn.setPreferredSize(new Dimension(1, 141));
}
public void placePlyrGrids()
{
plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
//NPCBoard.add(cornerGridLabel);
for(n = 0; n < 10; n++)
plyrBoard.add(letterGridLabels[n]); //the first row is the first 10 letters of the alphabet
//NPCBoard.add(letterGridLabels[n]);
for (y = 1; y < 11; y++) //For every (y) row...
{
for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
{
if (x == 0) //To the start of each row, add a number (image JLabel)
{
plyrBoard.add(numberGridLabels[numberCounter]);
//NPCBoard.add(numberGridLabels[numberCounter]);
numberCounter++;
}
else //for the rest of each row, add buttons
{
plyrBoard.add(buttonGrids[y-1][x-1]);
//NPCBoard.add(emptyGridLabel);
}
}
}
}
public void placeNPCGrids()
{
NPCBoard.add(cornerGridLabel);
for(n = 0; n < 10; n++)
NPCBoard.add(letterGridLabels[n]);
for (y = 1; y < 11; y++)
{
for (x = 0; x < 11; x++)
{
if (x == 0)
{
NPCBoard.add(numberGridLabels[numberCounter]);
numberCounter++;
}
else
{
NPCBoard.add(emptyGridLabel);
}
}
}
}
public void actionPerformed(ActionEvent e)
{
}
}
As I'm sure you understand by now I am very confused with this and I don't understand at all why this is happening. After all, the first method works fine on its own. Why shouldn't the second one and why are they destroying each other?
Any suggestions or tips to help put me in the right direction would be very appreciated.
Edit:
Solution:
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Battleships {
public static void main(String[] args)
{
Interface Win = new Interface ();
}
}
class Interface extends JFrame implements ActionListener
{
//Identify variables
int n;
int numberCounter = 0;
int y;
int x;
// lengths of the various ships in the game
//ADD IMAGE COMPONENTS
//Coordinate axes and empty grids
ImageIcon emptyGrid = new ImageIcon("EmptyGrid.png");
ImageIcon cornerGrid = new ImageIcon("CornerGrid.png");
ImageIcon [] numberGrids = new ImageIcon[11];
{
for (n = 0; n < 11; n ++)
numberGrids[n] = new ImageIcon("Grid" + (n + 1) + ".png");
}
ImageIcon [] letterGrids = new ImageIcon [11];
{
for (n = 0; n < 11; n ++)
letterGrids[n] = new ImageIcon("GridA" + (n + 1)+ ".png");
}
//Ship parts
//Clickable ships (for placement)
ImageIcon fullBattleship = new ImageIcon("FullBattleship.png");
ImageIcon fullCruiser = new ImageIcon("FullCruiser.png");
ImageIcon fullPatrolBoat1 = new ImageIcon("FullPatrolBoat.png");
ImageIcon fullPatrolBoat2 = new ImageIcon("FullPatrolBoat.png");
//JLabels
JLabel plyrCornerGridLabel = new JLabel(cornerGrid);
JLabel [] plyrNumberGridLabels = new JLabel[10];
{
//The first 11 grids are an empty grid followed by letters A-J
for (n = 0; n < 10; n++)
{
plyrNumberGridLabels[n] = new JLabel(numberGrids[n]);
}
}
JLabel [] plyrLetterGridLabels = new JLabel [10];
{
for (n = 0; n < 10; n ++)
{
plyrLetterGridLabels[n] = new JLabel (letterGrids[n]);
}
}
JLabel NPCCornerGridLabel = new JLabel(cornerGrid);
JLabel [] NPCNumberGridLabels = new JLabel[10];
{
//The first 11 grids are an empty grid followed by letters A-J
for (n = 0; n < 10; n++)
{
NPCNumberGridLabels[n] = new JLabel(numberGrids[n]);
}
}
JLabel [] NPCLetterGridLabels = new JLabel [10];
{
for (n = 0; n < 10; n ++)
{
NPCLetterGridLabels[n] = new JLabel (letterGrids[n]);
}
}
JLabel[][] emptyGridLabels = new JLabel [10][10];
{
for (y = 0; y < 10; y++)
{
for (x = 0; x < 10; x++)
{
emptyGridLabels[x][y] = new JLabel(emptyGrid);
}
}
}
JButton [][] buttonGrids = new JButton [10][10];
{
for (y = 0; y < 10; y++)
{
for (x = 0; x < 10; x++)
{
buttonGrids[x][y] = new JButton(emptyGrid);
buttonGrids[x][y].setPreferredSize(new Dimension(50,50));
}
}
}
JLabel [] NPCGrids = new JLabel[121]; //grid placements for the dealer board
{
for (n = 0; n < 121; n ++)
NPCGrids[n] = new JLabel (emptyGrid);
}
JLabel [] clickableBoats = new JLabel [4];
{
clickableBoats[0] = new JLabel (fullBattleship);
clickableBoats[1] = new JLabel (fullCruiser);
clickableBoats[2] = new JLabel (fullPatrolBoat1);
clickableBoats[3] = new JLabel (fullPatrolBoat2);
}
JButton [] plyrClickableGrids = new JButton [100];
{
for (n = 0; n < 99; n++);
plyrClickableGrids[n] = new JButton(emptyGrid);
}
//Add interface components
JTextArea playerInformation = new JTextArea(20,5);
JScrollPane textPane1 = new JScrollPane (playerInformation);
JButton playTurnBtn = new JButton ("Play Turn");
//add JPanels
JPanel plyrBoard = new JPanel (new GridLayout(11,11));
JPanel infoPanel = new JPanel(new GridLayout(1,1));
JPanel NPCBoard = new JPanel(new GridLayout(11,11));
JPanel inputPanel = new JPanel(new GridLayout(1,10));
public Interface ()
{
super ("Battleships");
setSize (1367,729);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//Set the background color
Container contentArea = getContentPane();
//Set each panel to "opaque", so that the background becomes visible
plyrBoard.setOpaque(false);
NPCBoard.setOpaque(false);
inputPanel.setOpaque(false);
setVisible (true);
playerInformation.setEditable(false);
playTurnBtn.setPreferredSize(new Dimension(1, 141));
//Add panels to different compass points on the content area
contentArea.add("West", plyrBoard);
contentArea.add("Center", infoPanel);
contentArea.add("East", NPCBoard);
contentArea.add("South", inputPanel);
//Add imageLabels and buttons to panels
infoPanel.add(playerInformation);
for (n = 0; n < 4; n++)
{
inputPanel.add(clickableBoats[n]);
}
inputPanel.add(playTurnBtn);
placePlyrGrids();
numberCounter = 0;
placeNPCGrids();
// TODO Vanity
//Button format
}
public void placePlyrGrids()
{
plyrBoard.add(plyrCornerGridLabel); //add an empty grid to the top left
//NPCBoard.add(cornerGridLabel);
for(n = 0; n < 10; n++)
plyrBoard.add(plyrLetterGridLabels[n]); //the first row is the first 10 letters of the alphabet
//NPCBoard.add(NPCLetterGridLabels[n]);
for (y = 1; y < 11; y++) //For every (y) row...
{
for (x = 0; x < 11; x++) //...add ten (x) grids to make columns
{
if (x == 0) //To the start of each row, add a number (image JLabel)
{
plyrBoard.add(plyrNumberGridLabels[numberCounter]);
//NPCBoard.add(NPCNumberGridLabels[numberCounter]);
numberCounter++;
}
else //for the rest of each row, add buttons
{
plyrBoard.add(buttonGrids[y-1][x-1]);
//NPCBoard.add(emptyGridLabel);
}
}
}
}
public void placeNPCGrids()
{
NPCBoard.add(NPCCornerGridLabel);
for(n = 0; n < 10; n++)
NPCBoard.add(NPCLetterGridLabels[n]);
for (y = 1; y < 11; y++)
{
for (x = 0; x < 11; x++)
{
if (x == 0)
{
NPCBoard.add(NPCNumberGridLabels[numberCounter]);
numberCounter++;
}
else
{
NPCBoard.add(emptyGridLabels[x-1][y-1]);
}
}
}
}
public void actionPerformed(ActionEvent e)
{
}
}
The issue is that in all the code you are always referring to the same object, E.G.
public void placeBoards()
{
//Both player board and npc board are going to have the same cornerGirdLabel, you should be creating two separate instances of it
plyrBoard.add(cornerGridLabel); //add an empty grid to the top left
NPCBoard.add(cornerGridLabel);
//Rest of the code
}
All the way through your code, you keep using the reference to the same objects, which is not going to help you when you want to build two boards with their own grids!
It might be better, especially for readability to separate your board building into different classes and have them create their own instances of these objects, rather than trying to fit this all in one class with your main method. Have a look at some best design practice documents. for example, they have some nice tips here

Java drawImage method

I am trying within exercise to put into ArrayList a set of Picture objects, then shuffle them randomly and display them as a grid of 3x3. However, the shuffle method does not work correctly for me. Or perhaps I am doing anything wrong within draw or drawImage methods, I don't know.
I am always getting picture displayed from 9 pieces in their original order, not randomly shuffled.
See below my PicturePiece class as well as the main class.
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;
}
}
And here is my main class:
/*
Find a pretty image from the Internet and use an image editor to break it down
into 9 pieces (for example, you can use the application Paint in Windows).
Display the 9 images in a 3×3 grid in a random order. Add a mouse listener.
Allow the user to swap two images by clicking on them.
The goal of the game is to re-create the original image.
Display an appropriate message when the user wins.
*/
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);
}
}
Your error arises because you are setting the row/column (j and k) in the MyPanel function.
So the shuffle only changes the order of the PicturePiece in the list, not the j/k that you use for the position.
In order to achieve the behavior you would like I would generate the row/column from the order in the list.
the problem is that you draw the image based in init coordinates, even if you suffle them, the coordinates remain the same in the PicturePiece objects.
short solution:
change in PicturePiece:
public void draw(Graphics2D g2, int i, int j) {
g2.drawImage(this.img, this.IMAGE_X *i, this.IMAGE_Y * j, null);
}
change in Puzzle:
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) {
}
}
this way you will get images in the same order from the array, but if they are shuffled inside the array, the image will be different at each execution.
Note: this is a hardcoded version (ok only for 3x3 matrix) but I hope you got the ideea. There are many other solutions to this but this is the shortest one I could think of.
Instead of drawing, on to the JPanel/JComponent, it would be wise to use a JLabelfor this purpose, which will make your work a bit easier, as you only have to worry about the index positions.
Here is one example:
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;
}
}
OUTPUT:
IMAGES USED:
ORIGINAL IMAGE: http://i.imgur.com/GNIZRQy.jpg
To SPLIT, I used this site: http://imagesplitter.net/
let me first thank you for your time and effort.
I wrote my application/lab this way:
package lab;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class PicturePiece extends JPanel {
private Image img;
private int id = 0;
public PicturePiece(int id) {
this.id = id;
}
public void setImage(File f) {
try {
this.img = ImageIO.read(f);
} catch (Exception e) {
}
}
public String getImage() {
return this.img.toString();
}
public int getId() {
return this.id;
}
public void draw(Graphics2D g2, int row, int col) {
g2.drawImage(this.img, row, col, null);
}
}
/**
* Find a pretty image from the Internet and use an image editor to break it
* down into 9 pieces (for example, you can use the application Paint in
* Windows). Display the 9 images in a 3×3 grid in a random order. Add a mouse
* listener. Allow the user to swap two images by clicking on them. The goal of
* the game is to re-create the original image. Display an appropriate message
* when the user wins.
*/
package lab;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.io.File;
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((266 * 3) + 10, (224 * 3) + 10);
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 implements MouseListener {
public static final int IMAGE_X = 266;
public static final int IMAGE_Y = 224;
public static final int PAD = 5;
private int counter = 0;
private int previouspicture = -1;
private int currentpicture = -1;
private boolean won = false;
private ArrayList<PicturePiece> images = new ArrayList<PicturePiece>();
public MyPanel() {
this.setFocusable(true);
for (int i = 0; i < 9; i++) {
images.add(new PicturePiece(i));
}
Random rnd = new Random();
rnd.setSeed(40000);
Collections.shuffle(images, rnd);
try {
for (int i = 0; i < images.size(); i++) {
images.get(i).setImage(new File(("src/chapter/domcek/domcek" + (images.get(i).getId() + 1) + ".jpg")));
}
} catch (Exception e) {
}
addMouseListener(this);
}
public void draw(Graphics2D g2) {
int j = 0, k = 0, pocet = 0;
for (int i = 0; i < 9; i++) {
images.get(i).draw(g2, j * (IMAGE_X + PAD), k * (IMAGE_Y + PAD));
pocet++;
if ((pocet % 3) == 0) {
j = 0;
k++;
} else {
j = j + 1;
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
validate();
draw(g2);
if (won == true) {
showMessage("You won!!!", g2);
}
}
/**
* checks whether user clicked on two different pictures and if yes, changes
* their order
*
* #param e - event object
*/
#Override
public void mouseClicked(MouseEvent e) {
int picturepiece_id;
if (counter == 0) {
previouspicture = getPicturePiece(e.getX(), e.getY());
counter = 1;
} else if (counter == 1) {
counter = 0;
currentpicture = getPicturePiece(e.getX(), e.getY());
if ((previouspicture != currentpicture) && (previouspicture != -1) && (currentpicture != -1)) {
swap(previouspicture, currentpicture);
repaint();
int j = 0;
int i = 0;
i = 0;
while ((j == i) && (i < images.size()) && (j < images.size())) {
i++;
j = images.get(i).getId();
if ((j == 8) && (i == 8)) {
won = true;
removeMouseListener(this);
repaint();
break;
}
}
}
}
}
/**
* prints message on winning
*
* #param s - message to print
* #param g2 - graphical context
*/
public void showMessage(String s, Graphics2D g2) {
Font myFont = new Font(" SansSerif ", Font.BOLD, 100);
g2.setFont(myFont);
g2.setColor(Color.BLUE);
Rectangle2D textBox = myFont.getStringBounds(s, g2.getFontRenderContext());
g2.drawString(s, (int) (getWidth() / 2 - textBox.getWidth() / 2), (int) (getHeight() / 2 - textBox.getHeight()));
}
/**
* returns order number of picture within 3x3 grid where user clicked
*
* #param x - X coordinate
* #param y - Y coordinate
* #return
*/
private int getPicturePiece(int x, int y) {
if ((x <= IMAGE_X) && (y <= IMAGE_Y)) {
return 0;
} else if (((x > IMAGE_X) && (x <= IMAGE_X * 2)) && (y <= IMAGE_Y)) {
return 1;
} else if (((x > IMAGE_X) && (x <= IMAGE_X * 3)) && (y <= IMAGE_Y)) {
return 2;
} else if ((x <= IMAGE_X) && ((y > IMAGE_Y) && (y <= (IMAGE_Y * 2)))) {
return 3;
} else if (((x > IMAGE_X) && (x <= (IMAGE_X * 2))) && ((y > IMAGE_Y) && (y <= (IMAGE_Y * 2)))) {
return 4;
} else if (((x > IMAGE_X) && (x <= (IMAGE_X * 3))) && ((y > IMAGE_Y) && (y <= (IMAGE_Y * 2)))) {
return 5;
} else if ((x <= IMAGE_X) && ((y > IMAGE_Y) && (y <= (IMAGE_Y * 3)))) {
return 6;
} else if (((x > IMAGE_X) && (x <= (IMAGE_X * 2))) && ((y > IMAGE_Y) && (y <= (IMAGE_Y * 3)))) {
return 7;
} else if (((x > IMAGE_X) && (x <= (IMAGE_X * 3))) && ((y > IMAGE_Y) && (y <= (IMAGE_Y * 3)))) {
return 8;
} else {
return -1;
}
}
/**
* swaps two clicked different pictures
*
* #param previouspic - first picture
* #param currentpic - second picture
*/
public void swap(int previouspic, int currentpic) {
int temp = 0;
int a = previouspic;
int b = currentpic;
PicturePiece p = images.get(a);
PicturePiece p2 = images.get(b);
images.set(a, p2);
images.set(b, p);
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}

Drawing an assembled image to the JPanel

I am working on a program that I can use to present topics in front of my class. While MS Powerpoint and similar programs are nice, I feel like they are lacking in some areas. I am not trying to re-create these programs, I am only trying to make a program where I can type text into String arrays, add images, and position them all on the screen.
Currently my program opens a fullscreen dark window with a little X in the top left, which when clicked will close the program.
Here is the class file:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
static JFrame frame;
static MyPanel panel;
static MouseListener listener;
static final int letterWidth = 6;
static final int letterHeight = 9;
static final int letterRow = 10;
static final int letterCol = 11;
static final int letterNum = 110;
static String[] textA = {"Hello World,",
"Here is a test",
"of what I can do.",
"Isn't it neat?!"
};
static int textX = 100;
static int textY = 100;
public static void main(String[] args){
System.out.println("Welcome to Presenter");
System.out.println("Beginning loading");
frame = new JFrame();
panel = new MyPanel();
listener = new MouseListener(){
public void mouseClicked(MouseEvent arg0) {
if(arg0.getButton() ==MouseEvent.BUTTON1){
//Close button
int x = (int) MouseInfo.getPointerInfo().getLocation().getX();
int y = (int) MouseInfo.getPointerInfo().getLocation().getY();
if(x>20 && x<48 && y>20 && y<56){
frame.dispose();
System.exit(0);
}
}
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
};
frame.setUndecorated(true);
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.add(panel);
frame.addMouseListener(listener);
System.out.println("");
System.out.println("Loading Complete");
}
public static class MyPanel extends JPanel{
private static final long serialVersionUID = 1L;
HashMap<String, BufferedImage> iLetters;
static BufferedImage exitButton = new BufferedImage(28, 36, BufferedImage.TYPE_INT_ARGB);
static BufferedImage letters = new BufferedImage(120, 198, BufferedImage.TYPE_INT_ARGB);
Scanner lightbulb;
static boolean point = false;
int x;
int y;
BufferedImage textBox;
int boxW, boxH;
public MyPanel(){
//pictures
File a = new File("Exit.png");
try { exitButton = ImageIO.read(a); } catch (IOException e) {e.printStackTrace();}
a = new File("Letters.png");
try { letters = ImageIO.read(a); } catch (IOException e) {e.printStackTrace();}
//letter index
try { lightbulb = new Scanner(new File("letters.txt")); } catch (FileNotFoundException e) {e.printStackTrace();}
System.out.println("Files Read");
//create letters
System.out.println("Beginning tiling");
iLetters = new HashMap<String, BufferedImage>();
BufferedImage[] pics = new BufferedImage[letterNum];
int count = 0;
for(int x=0; x<letterCol; x++){
for(int y=0; y<letterRow; y++){
pics[count] = new BufferedImage(letterWidth, letterHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D gr = pics[count++].createGraphics();
gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null);
gr.dispose();
}
System.out.println("Row " + x + " tiled.");
}
System.out.println("Completed Tiling");
System.out.println("Beginning indexing");
int loc = 0;
String key = "";
while(lightbulb.hasNext()){
loc = lightbulb.nextInt()-1;
key = lightbulb.next();
iLetters.put(key, pics[loc]);
}
System.out.println("Indexing Complete");
System.out.println("Making Text Boxes");
makeTextBox(textA);
System.out.println("Text Boxes Made");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(new Color(0, 0, 10));
g.drawImage(exitButton, 20, 20, null);
// g.drawImage(iLetters.get("A"), 100, 100, null);
drawTexts(g);
}
public void drawTexts(Graphics g){
g.drawImage(textBox, textX, textY, textX+(boxW*2), textY+(boxH*2), null);
}
public int findLongest(String[] text){
int longest = 0;
for(int i=0; i<text.length; i++){
if(text[i].length() > longest)
longest = text[i].length();
}
return longest;
}
public void makeTextBox(String[] text){
int longest = findLongest(text);
boxW = (longest*6)+(longest-1);
boxH = (text.length*9)+(text.length-1);
textBox = new BufferedImage(boxW, boxH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = textBox.createGraphics();
char[] line;
int drawX = 0;
int drawY = 0;
for(int i=0; i<text.length; i++){
line = text[i].toCharArray();
for(int j=0; j<line.length; j++){
if(j<line.length-1){
g2d.drawImage(iLetters.get(line[j]), drawX, drawY, null);
drawX += letterWidth + 1;
}
else{
g2d.drawImage(iLetters.get(line[j]), drawX, drawY, null);
}
}
if(i<text.length-1){
drawY += letterHeight + 1;
}
else{
drawY += letterHeight;
}
}
g2d.dispose();
}
}
}
The rest of the files needed for it to run are here http://www.mediafire.com/?jq8vi4dm3t4b6
2 PNGs and 1 text file.
The program runs fine with no errors. The only problem is the drawTexts() method. When the method is called, the lines of text do not appear anywhere on screen, when they should be appearing at (100, 100) at 2x the size of the letters in the file.
It's been a while since I did graphics. I remember needing to call repaint() somewhere, but I cannot remember if I need it here, and if I do, where it goes.
Okay, this might take some time...
There are 10 columns and 11 rows, these are around the wrong way...
static final int letterRow = 10;
static final int letterCol = 11;
I don't think you understand what gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null); is actually doing, what you really want is BufferedImage#getSubImage...
BufferedImage subimage = letters.getSubimage(letterWidth * x, letterHeight * y, letterWidth, letterHeight);
You're reading the Letters.png file in row/column order, but building the mapping as if it was in column/row order...
Instead of...
for (int x = 0; x < letterCol; x++) {
for (int y = 0; y < letterRow; y++) {
You should be using...
for (int y = 0; y < letterRow; y++) {
for (int x = 0; x < letterCol; x++) {
The lightbulb Scanner is not reading the file...I'm don't use Scanner that often, but when I changed it to lightbulb = new Scanner(new BufferedReader(new FileReader("letters.txt"))); it worked...
In your makeTextBox method you are trying to retrieve the image using a char instead of String, this means the lookup fails as the two keys are incompatible. You need to use something more like...
BufferedImage img = iLetters.get(Character.toString(line[j]));
Also, on each new line, you are not resting the drawX variable, so the text just keeps running off...In fact, I just re-wrote the loop to look more like...
for (int i = 0; i < text.length; i++) {
line = text[i].toCharArray();
for (int j = 0; j < line.length; j++) {
BufferedImage img = iLetters.get(Character.toString(line[j]));
g2d.drawImage(img, drawX, drawY, null);
if (j < line.length - 1) {
drawX += letterWidth + 1;
}
}
drawX = 0;
if (i < text.length - 1) {
drawY += letterHeight + 1;
} else {
drawY += letterHeight;
}
}
And yes, it could be simplified more, but little steps...
There might be a bunch of other things, but that should get you a step closer...

JPanel size not changing

Hi guys i'm trying to create a draughts game in Java and am using JPanels to represent the squares, if I were to change the size of the panels how would I do so ? if I use a layout manager the squares are not big enough. At the moment i'm not using a layout manager to try and change the size, but the size doesnt seem to change - just stays at 1,1 pixel.
private void createSquares(){
for(int i = 0; i < 65; i++){
squares[i] = new JPanel();
squares[i].setLayout(null);
squares[i].setSize(20,20);
board.add(squares[i]);
}
}
You could always "borrow" an image or two online, and put that into your program. For example this code:
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GetChessSquareImages {
public static final String PATH_TO_SQUARES = "http://www.colourbox.com/preview/" +
"4578561-622234-seamless-oak-square-chess-like-parquet-texture.jpg";
private static final int IMG_SIDE_COUNT = 4;
private static final double SCALE = 0.8;
private Map<SquareColor, List<Icon>> squareColorMap = new HashMap<SquareColor, List<Icon>>();
private Random random = new Random();
public void downloadImages() throws IOException {
URL lrgImgUrl = new URL(PATH_TO_SQUARES);
BufferedImage largeImg = ImageIO.read(lrgImgUrl);
int w = largeImg.getWidth() / IMG_SIDE_COUNT;
int h = largeImg.getHeight() / IMG_SIDE_COUNT;
for (int i = 0; i < IMG_SIDE_COUNT; i++) {
int x = (i * largeImg.getWidth()) / IMG_SIDE_COUNT;
for (int j = 0; j < IMG_SIDE_COUNT; j++) {
if (j != 1 && j != 2) {
int y = (j * largeImg.getHeight()) / IMG_SIDE_COUNT;
extractSubImg(largeImg, i, j, x, y, w, h);
}
}
}
}
private void extractSubImg(BufferedImage largeImg,
int i, int j, int x, int y, int w, int h) {
Image subImg = largeImg.getSubimage(x, y, w, h);
int width = (int) (w * SCALE);
int height = (int) (h * SCALE);
subImg = subImg.getScaledInstance(width, height, Image.SCALE_SMOOTH);
List<Icon> iconList = null;
if (i % 2 == j % 2) {
iconList = squareColorMap.get(SquareColor.LIGHT);
if (iconList == null) {
iconList = new ArrayList<Icon>();
squareColorMap.put(SquareColor.LIGHT, iconList);
}
} else {
iconList = squareColorMap.get(SquareColor.DARK);
if (iconList == null) {
iconList = new ArrayList<Icon>();
squareColorMap.put(SquareColor.DARK, iconList);
}
}
iconList.add(new ImageIcon(subImg));
}
public Icon getRandomIcon(SquareColor sqrColor) {
List<Icon> iconList = squareColorMap.get(sqrColor);
if (iconList == null) {
return null;
} else {
return iconList.get(random.nextInt(iconList.size()));
}
}
public static void main(String[] args) {
GetChessSquareImages getImages = new GetChessSquareImages();
try {
getImages.downloadImages();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
int side = 8;;
JPanel panel = new JPanel(new GridLayout(side , side));
for (int i = 0; i < side; i++) {
for (int j = 0; j < side; j++) {
SquareColor sqrColor = (i % 2 == j % 2) ? SquareColor.LIGHT : SquareColor.DARK;
Icon icon = getImages.getRandomIcon(sqrColor);
panel.add(new JLabel(icon));
}
}
JOptionPane.showMessageDialog(null, panel);
}
}
enum SquareColor {
DARK, LIGHT
}
returns this JPanel:
Then your square size will be based on the sizes of your ImageIcons. For example, I have scaled my squares back with a scale factor of 0.8 (the SCALE constant above) to make the grid a more reasonable size.

Scrolling through JPanel clears its graphics

I am a beginner with Java Programming and I have a problem. I am using a JPanel in a JScrollPane all contained in a JFrame.
I am using paintComponent() method to draw a certain curve and that's done correctly. The problem is that when I scroll through my panel I see that the image is being cleared. I've searched and learned about flickering but I'm not quiet sure yet what it means and whether that's the problem I am having. I did notice also that when repaint is called the image is cleared.
Here is my code, can anyone let me know if I am doing something wrong?
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.QuadCurve2D;
import javax.swing.JFrame;
import java.lang.Math;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class DrawCurve extends JPanel {
class MyAdjustmentListener implements AdjustmentListener {
public MyAdjustmentListener() {
}
public void adjustmentValueChanged(AdjustmentEvent evt) {
setFocusable(true);
jScroll.setFocusable(false);
//repaint();
//revalidate();
}
}
Graphics gr;
Stroke drawingStroke = new BasicStroke(0.5f);
double x;
int y = 0;
static String seq = "AAGTCGACCTGTAGCTAGATCGGATCATAGCTCGATCCAGAGATT";
QuadCurve2D curve;
char s;
int a = 0;
int c = 0;
int g = 0;
int t = 0;
int af = 0;
int cf = 0;
int gf = 0;
int tf = 0;
int h = 0;
int flag = 0;
final JScrollPane jScroll = new JScrollPane();
final JFrame parFrame;
Vector<Double> xrand = new Vector<Double>();
public DrawCurve() {
super();
parFrame = new JFrame();
parFrame.pack();
jScroll.setFocusable(false);
setFocusable(true);
parFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
this.setBackground(Color.WHITE);
jScroll.setViewportView(this);
jScroll.getHorizontalScrollBar().addAdjustmentListener(new MyAdjustmentListener());
jScroll.getVerticalScrollBar().addAdjustmentListener(new MyAdjustmentListener());
if (checkSequence(seq) == 0) {
jScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jScroll.setViewportBorder(new LineBorder(Color.WHITE));
setFocusable(true);
setPreferredSize(new Dimension(1000, 300));
setBackground(Color.magenta);
parFrame.add(jScroll, BorderLayout.CENTER);
parFrame.setSize(600, 320);
parFrame.setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "invalid input", "Warning!", JOptionPane.PLAIN_MESSAGE);
}
}
public int checkSequence(String sequ) {
int f = 0;
for (int i = 0; i < sequ.length(); i++) {
if (sequ.charAt(i) != "A".charAt(0) && sequ.charAt(i) != "C".charAt(0) && sequ.charAt(i) != "G".charAt(0) && sequ.charAt(i) != "T".charAt(0)) {
f = 1;
break;
}
xrand.add(Math.random() * 300 - 200);
}
return f;
}
public void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D ga = (Graphics2D) gr;
System.out.println("in");
ga.setStroke(drawingStroke);
for (int i = 0; i < seq.length(); i++) {
s = seq.charAt(i);
if (s == "A".charAt(0)) {
ga.setColor(Color.RED);
a = 1;
af = 1;
cf = 0;
gf = 0;
tf = 0;
h = -1;
} else if (s == "C".charAt(0)) {
ga.setColor(Color.YELLOW);
c = 1;
af = 0;
cf = 1;
gf = 0;
tf = 0;
h = -3;
} else if (s == "G".charAt(0)) {
ga.setColor(Color.GREEN);
g = 1;
af = 0;
cf = 0;
gf = 1;
tf = 0;
h = 1;
} else if (s == "T".charAt(0)) {
ga.setColor(Color.BLUE);
t = 1;
af = 0;
cf = 0;
gf = 0;
tf = 1;
h = 3;
} else {
af = 0;
cf = 0;
gf = 0;
tf = 0;
h = 0;
}
x = Math.random() * 300 - 200;
curve = new QuadCurve2D.Double(y, 250 + h, y + 10, xrand.elementAt(i), y + 20, 250 + h);
ga.draw(curve);
if (a == 1 && af == 0) {
ga.setColor(Color.RED);
h = -1;
ga.drawLine(y, 250 + h, y + 20, 250 + h);
}
if (c == 1 && cf == 0) {
ga.setColor(Color.YELLOW);
h = -3;
ga.drawLine(y, 250 + h, y + 20, 250 + h);
}
if (g == 1 && gf == 0) {
ga.setColor(Color.GREEN);
h = 1;
ga.drawLine(y, 250 + h, y + 20, 250 + h);
}
if (t == 1 && tf == 0) {
ga.setColor(Color.BLUE);
h = 3;
ga.drawLine(y, 250 + h, y + 20, 250 + h);
}
y += 20;
}
}
public static void main(String[] args) {
final DrawCurve panel = new DrawCurve();
}
}
I figured out what's wrong with that code, it turned out that in my loop I forgot to initialize where the curve should start every time the paintComponent is called. Adding y=0; at the start of paintComponent would solve it

Categories

Resources