So basically I'm trying to make a 2D maze-like game where you can either create a map yourself or load a premade one. You change the tiles of the map by giving the coordinates of the new desired object which can be a wall, grass, enemy, bomb, weapon, the hero, etc, after clicking the corresponding JButton. My question is: up until now I've been using just JLabels to place images of the grass in the map because they're the "basic tiles" on which the hero can move, and then I'm trying to change those to custom objects of the different classes so when the hero moves to one of them it triggers different actions, but it looks like a JLabel can only contain text or images, so how should I do it then? This is the code (I'm sorry it's in spanish):
public class Tablero extends JFrame {
private int numFilas;
private int numColumnas;
private int numMuros;
public Tablero(final int numFilas, final int numColumnas, final int numMuros) {
this.numFilas = numFilas;
this.numColumnas = numColumnas;
this.numMuros = numMuros;
JFrame tablero = new JFrame();
JPanel contenedor = new JPanel();
final JLabel[][] casilla = new JLabel[60][60];
tablero.setSize(1280, 720);
contenedor.setSize(1280, 720);
tablero.add(contenedor);
for (int x = 0; x < this.numFilas; x++) {
for (int y = 0; y < this.numColumnas; y++) {
casilla[x][y] = new JLabel();
casilla[x][y].setIcon(new ImageIcon("C:\\Users\\Andres\\Desktop\\Programación orientada a objetos\\Juego\\build\\classes\\juego\\pasto.png"));
contenedor.add(casilla[x][y]);
}
}
JOptionPane.showMessageDialog(null, "Cree a continuación el héroe");
int coorX = Integer.parseInt(JOptionPane.showInputDialog("Digite la coordenada en x del héroe: "));
int coorY = Integer.parseInt(JOptionPane.showInputDialog("Digite la coordenada en y del héroe: "));
int lives = Integer.parseInt(JOptionPane.showInputDialog("Digite la cantidad de vidas del héroe: "));
final Heroe heroe = new Heroe(coorX, coorY, lives);
JButton añadirMuros = new JButton("Añadir muros");
contenedor.add(añadirMuros);
añadirMuros.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
Muro[] muros = new Muro[numMuros];
for (int i = 0; i < numMuros; i++) {
int coorX = Integer.parseInt(JOptionPane.showInputDialog("Digite la coordenada en x del muro # " + i + 1));
int coorY = Integer.parseInt(JOptionPane.showInputDialog("Digite la coordenada en y del muro # " + i + 1));
muros[i] = new Muro(coorX, coorY, heroe);
casilla[coorX][coorY] = new JLabel();
}
System.out.println("Clicked! muros");
}
});
JButton añadirBombas = new JButton("Añadir bombas");
contenedor.add(añadirBombas);
JButton añadirPistolas = new JButton("Añadir pistolas");
contenedor.add(añadirPistolas);
JButton añadirBallestas = new JButton("Añadir ballestas");
contenedor.add(añadirBallestas);
JButton añadirEnemigos = new JButton("Añadir enemigos");
contenedor.add(añadirPistolas);
JButton determinarEntrada = new JButton("Determinar entrada");
contenedor.add(determinarEntrada);
JButton determinarSalida = new JButton("Determinar salida");
contenedor.add(determinarSalida);
tablero.setVisible(true);
tablero.setResizable(true);
tablero.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
Yes, a JLabel can only contain text or an ImageIcon.
You can use a JPanel to draw images directly. Your Wall and Enemy classes can draw a representation of themselves on a JPanel.
Here's a GameImages and GuessingGamePanel from a game I put together. The GuesssingGamePanel draws the images from the GameImages class.
package com.ggl.guessing.game.view;
import java.awt.Dimension;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class GameImages {
private Image backgroundImage;
private Image victoryImage;
public GameImages() {
readBackgroundImage();
readVictoryImage();
}
private void readBackgroundImage() {
Image image = null;
try {
URL url = getClass().getResource("/v8k3reduced.jpg");
image = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
this.backgroundImage = image;
}
private void readVictoryImage() {
Image image = null;
try {
URL url = getClass().getResource("/r7f8reduced.jpg");
image = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
this.victoryImage = image;
}
public Image getBackgroundImage() {
return backgroundImage;
}
public Dimension getPreferredSize() {
return new Dimension(backgroundImage.getWidth(null),
backgroundImage.getHeight(null));
}
public Image getVictoryImage() {
return victoryImage;
}
}
.
package com.ggl.guessing.game.view;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
import com.ggl.guessing.game.model.GuessingGameModel;
public class GuessingGamePanel extends JPanel {
private static final long serialVersionUID =
-2429103448910749064L;
private boolean guessed;
private Dimension guessesPanelDimension;
private GameImages gameImages;
private GuessesPanel guessesPanel;
private GuessingGameFrame frame;
private GuessingGameModel model;
public GuessingGamePanel(GuessingGameFrame frame,
GuessingGameModel model, GameImages gameImages,
Dimension guessesPanelDimension) {
this.frame = frame;
this.model = model;
this.gameImages = gameImages;
this.guessesPanelDimension = guessesPanelDimension;
this.guessed = false;
createPartControl();
}
private void createPartControl() {
this.setLayout(null);
this.setPreferredSize(gameImages.getPreferredSize());
guessesPanel = new GuessesPanel(frame, model);
Dimension gp = guessesPanelDimension;
Dimension tp = gameImages.getPreferredSize();
int x = (tp.width - gp.width) / 2;
int y = (tp.height - gp.height) / 2;
guessesPanel.getPanel().setBounds(x, y, gp.width, gp.height);
this.add(guessesPanel.getPanel());
}
public void setGuessed(boolean guessed) {
this.guessed = guessed;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(gameImages.getBackgroundImage(), 0, 0, null);
if (guessed) {
g.drawImage(gameImages.getVictoryImage(), 0, 0, null);
}
}
}
Related
How I could create Rectangle loop, to look like a wall in a game?
I don't have to create and draw each rectangle separately. In Rectangle class I haven't found setter for setting coordinates.
I created something you might be able to use for a Tank game I'm working on.
Here's the GUI
To use this GUI, you left-click on the location where you want a wall. If you left-click on a wall, the wall section disappears.
In the SaveGameGridListener class, actionPerformed method, I hardcoded a specific location for the text file output. You'll want to change that.
The output of this GUI is a 44 character by a 22 line text file made up of 0 and 1 values. Zero indicates a playing field, and one indicates a wall. You'll probably want to adjust the dimensions of the playing field for your Packman game.
Here's the text file for this particular game board.
00000000000000000000011000000000000000000000
00000000000000000000011000000000000000000000
00000000000000000000000000000000000000000000
00000111000000000000000000000000000011100000
00000000000000000000000000000000000000000000
00000000000001111000000000011110000000000000
00000000000001000000000000000010000000000000
00001100000000000000000000000000000000110000
00000100000000000000000000000000000000100000
00000100000000000000000000000000000000100000
00000100011000000000011000000000011000100000
00000100011000000000011000000000011000100000
00000100000000000000000000000000000000100000
00000100000000000000000000000000000000100000
00001100000000000000000000000000000000110000
00000000000001000000000000000010000000000000
00000000000001111000000000011110000000000000
00000000000000000000000000000000000000000000
00000111000000000000000000000000000011100000
00000000000000000000000000000000000000000000
00000000000000000000011000000000000000000000
00000000000000000000011000000000000000000000
Now, my game board is sparse. Your game board would have more walls, but you can use the same principle that I did.
Create a text file containing zeroes and ones to generate your game board.
Use the text file to create your game board.
Here's the complete runnable code I used. I made all the classes inner classes so I could post the code as one block. The code is expecting a grid.txt file in the Resources folder of your project.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
public class GenerateGameGrid implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new GenerateGameGrid());
}
#Override
public void run() {
new GenerateGameGridFrame(new GameGrid());
}
public class GenerateGameGridFrame {
private final GameGrid gameGrid;
private final GenerateGameGridPanel generateGameGridPanel;
private final JFrame frame;
public GenerateGameGridFrame(GameGrid gameGrid) {
this.gameGrid = gameGrid;
this.generateGameGridPanel = new GenerateGameGridPanel(this, gameGrid);
this.frame = createAndShowGUI();
}
private JFrame createAndShowGUI() {
JFrame frame = new JFrame("Generate Game Grid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(createJMenuBar());
frame.add(generateGameGridPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
System.out.println(frame.getSize());
return frame;
}
private JMenuBar createJMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem saveItem = new JMenuItem("Save Game Grid... ");
saveItem.setAccelerator(KeyStroke.getKeyStroke("control S"));
saveItem.addActionListener(new SaveGameGridListener(this, gameGrid));
fileMenu.add(saveItem);
fileMenu.addSeparator();
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setAccelerator(KeyStroke.getKeyStroke("alt X"));
exitItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
frame.dispose();
System.exit(0);
}
});
fileMenu.add(exitItem);
menuBar.add(fileMenu);
return menuBar;
}
public JFrame getFrame() {
return frame;
}
public void repaint() {
generateGameGridPanel.repaint();
}
}
public class GameGrid {
private final int blockwidth;
private final int margin;
private final int[][] grid;
private final Color backgroundColor;
private final Color foregroundColor;
public GameGrid() {
this.blockwidth = 24;
this.margin = 10;
this.backgroundColor = new Color(187, 71, 14);
this.foregroundColor = new Color(244, 192, 83);
this.grid = readGrid();
}
private int[][] readGrid() {
int[][] grid = new int[22][44];
try {
readGrid(grid, "grid.txt");
} catch (IOException e) {
e.printStackTrace();
}
return grid;
}
private void readGrid(int[][] grid, String filename) throws IOException {
InputStream is = getClass().getResourceAsStream("/" + filename);
InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader);
int row = 0;
String line = reader.readLine();
while (line != null) {
char[] chars = line.toCharArray();
for (int column = 0; column < chars.length; column++) {
grid[row][column] = Integer.valueOf(Character.toString(chars[column]));
}
row++;
line = reader.readLine();
}
reader.close();
}
public int[][] getGrid() {
return grid;
}
public Color getBackgroundColor() {
return backgroundColor;
}
public Color getForegroundColor() {
return foregroundColor;
}
public int getBlockwidth() {
return blockwidth;
}
public int getMargin() {
return margin;
}
}
public class GenerateGameGridPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final GameGrid gameGrid;
// private final GenerateGameGridFrame frame;
public GenerateGameGridPanel(GenerateGameGridFrame frame, GameGrid gameGrid) {
// this.frame = frame;
this.gameGrid = gameGrid;
int[][] grid = gameGrid.getGrid();
int blockwidth = gameGrid.getBlockwidth();
int margin = gameGrid.getMargin();
int height = blockwidth * (grid.length + 2) + margin + margin;
int width = blockwidth * (grid[0].length + 2) + margin + margin;
this.setBackground(gameGrid.getBackgroundColor());
this.setPreferredSize(new Dimension(width, height));
this.addMouseListener(new BlockListener(frame, gameGrid));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawBorder(g2d);
drawGrid(g2d, gameGrid.getGrid());
}
private void drawBorder(Graphics2D g2d) {
int blockwidth = gameGrid.getBlockwidth();
int margin = gameGrid.getMargin();
int x = margin;
int y = margin;
int width = getWidth() - margin - margin;
int height = blockwidth;
g2d.setColor(gameGrid.getForegroundColor());
g2d.fillRect(x, y, width, height);
x = margin;
y = margin;
width = blockwidth;
height = getHeight() - margin - margin;
g2d.fillRect(x, y, width, height);
x = margin;
y = getHeight() - margin - blockwidth;
width = getWidth() - margin - margin;
height = blockwidth;
g2d.fillRect(x, y, width, height);
x = getWidth() - blockwidth - margin;
y = margin;
width = blockwidth;
height = getHeight() - margin - margin;
g2d.fillRect(x, y, width, height);
}
private void drawGrid(Graphics2D g2d, int[][] grid) {
int blockwidth = gameGrid.getBlockwidth();
int margin = gameGrid.getMargin();
g2d.setColor(gameGrid.getForegroundColor());
for (int row = 0; row < grid.length; row++) {
for (int column = 0; column < grid[row].length; column++) {
if (grid[row][column] == 1) {
int x = (column + 1) * blockwidth + margin;
int y = (row + 1) * blockwidth + margin;
g2d.fillRect(x, y, blockwidth, blockwidth);
}
}
}
}
}
public class BlockListener extends MouseAdapter {
private final GameGrid gameGrid;
private final GenerateGameGridFrame frame;
public BlockListener(GenerateGameGridFrame frame, GameGrid gameGrid) {
this.frame = frame;
this.gameGrid = gameGrid;
}
#Override
public void mouseReleased(MouseEvent event) {
int[][] grid = gameGrid.getGrid();
int blockwidth = gameGrid.getBlockwidth();
int margin = gameGrid.getMargin();
Point point = event.getPoint();
int row = (point.y - margin - blockwidth) / blockwidth;
int column = (point.x - margin - blockwidth) / blockwidth;
grid[row][column] = grid[row][column] ^ 1;
frame.repaint();
}
}
public class SaveGameGridListener implements ActionListener {
private final GameGrid gameGrid;
private final GenerateGameGridFrame frame;
public SaveGameGridListener(GenerateGameGridFrame frame, GameGrid gameGrid) {
this.frame = frame;
this.gameGrid = gameGrid;
}
#Override
public void actionPerformed(ActionEvent event) {
OSFileChooser fc = new OSFileChooser();
File dir = new File("D:\\Eclipse\\Eclipse-2020-workspace\\com.ggl.combat\\resources");
fc.setCurrentDirectory(dir);
fc.addChoosableFileFilter(new FileTypeFilter(
"Text", "txt"));
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showSaveDialog(frame.getFrame());
if (returnVal == OSFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
try {
writeFile(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void writeFile(File file) throws IOException {
int[][] grid = gameGrid.getGrid();
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
for (int row = 0; row < grid.length; row++) {
StringBuilder builder = new StringBuilder();
for (int column = 0; column < grid[row].length; column++) {
builder.append(grid[row][column]);
}
builder.append(System.lineSeparator());
writer.write(builder.toString());
}
writer.close();
}
}
public class OSFileChooser extends JFileChooser {
private static final long serialVersionUID = 1L;
#Override
public void approveSelection() {
File f = getSelectedFile();
if (f.exists() && getDialogType() == SAVE_DIALOG) {
int result = JOptionPane.showConfirmDialog(this, f.getName() +
" exists, overwrite?",
"Existing file", JOptionPane.YES_NO_CANCEL_OPTION);
switch (result) {
case JOptionPane.YES_OPTION:
super.approveSelection();
return;
case JOptionPane.NO_OPTION:
return;
case JOptionPane.CLOSED_OPTION:
return;
case JOptionPane.CANCEL_OPTION:
cancelSelection();
return;
}
}
super.approveSelection();
}
#Override
public File getSelectedFile() {
File file = super.getSelectedFile();
if (file != null && getDialogType() == SAVE_DIALOG) {
String extension = getExtension(file);
if (extension.isEmpty()) {
FileTypeFilter filter = (FileTypeFilter) getFileFilter();
if (filter != null) {
extension = filter.getExtension();
String fileName = file.getPath();
fileName += "." + extension;
file = new File(fileName);
}
}
}
return file;
}
public String getExtension(File file) {
String extension = "";
String s = file.getName();
int i = s.lastIndexOf('.');
if (i > 0 && i < (s.length() - 1)) {
extension = s.substring(i + 1).toLowerCase();
}
return extension;
}
}
public class FileTypeFilter extends FileFilter {
private String extension;
private String description;
public FileTypeFilter(String description, String extension) {
this.extension = extension;
this.description = description;
}
#Override
public boolean accept(File file) {
if (file.isDirectory()) {
return true;
}
return file.getName().endsWith("." + extension);
}
#Override
public String getDescription() {
return description + String.format(" (*.%s)", extension);
}
public String getExtension() {
return extension;
}
}
}
I'm trying to build a Scrabble game to help get more familiar with building GUIs and practice java skills in general. The board is mainly composed of a JLayeredPane with JPanels to include the board image and board spaces. I'm trying to be able to drag and drop the Tile objects (extends JLabel) around the board by adding the tile to the drag_layer and then moving it from there, similar to the following example: dragging a jlabel around the screen. The mouse press is working and correctly adding the tile to the drag layer, but after that, it seems like the mouse stops listening completely. I tried just printing "Dragging" in the mouseDragged override method, but it won't even print that. There are two relevant classes - Console and MouseInput, which I'll show below, but I'll also add the link to the GitHub repo at the end if you want to pull the whole project.
Console:
public Console () throws IOException{
// Create gameConsole
gameConsole = new JFrame();
final int frameWidth = 850;
final int frameHeight = 950;
gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight));
gameConsole.setTitle("Scrabble");
gameConsole.setLayout(new GridBagLayout());
gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.ipadx = 810;
c.ipady = 950;
// Create center console panel and add to gameConsole
centerConsole = new JPanel();
centerConsole.setLayout(new BorderLayout());
gameConsole.add(centerConsole,c);
// Create layered pane that holds the board and playerbox
gameContainer = new JLayeredPane();
gameContainer.setBounds(0,0,810,950);
gameContainer.addMouseListener(new MouseInput(gameContainer));
gameContainer.addMouseMotionListener(new MouseInput(gameContainer));
centerConsole.add(gameContainer, BorderLayout.CENTER);
// Create board image label and add to JPanel
BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg"));
JLabel background = new JLabel(new ImageIcon(scrabbleImage));
boardImage = new JPanel();
boardImage.setBounds(0, 0, 810, 810);
boardImage.add(background);
boardImage.setOpaque(true);
// create JPanel with gridBagLayout
boardGrid = new JPanel();
boardGrid.setBounds(0, 3, 810, 810);
boardGrid.setLayout(new GridBagLayout());
boardGrid.setOpaque(false);
// Create panels to add to boardGrid
spaces = new BoardSpace [15][15];
BoardSpace.setBoardSpaces(spaces);
// Set grid constraints
GridBagConstraints cGrid = new GridBagConstraints();
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
// panel constraints
cGrid.gridx = i; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
spaces[i][j].setOpaque(false);
spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
boardGrid.add(spaces[i][j], cGrid);
}
}
// Add to layeredPane
gameContainer.add(boardImage, new Integer(0),0);
gameContainer.add(boardGrid, new Integer(1),0);
// Create player box panel
playerPanel = new JPanel();
playerPanel.setLayout(new GridBagLayout());
playerBox = new JPanel();
playerBox.setLayout(new GridLayout(1,7, 10, 0));
// Create player box constraints
GridBagConstraints cp = new GridBagConstraints();
cp.ipadx = 50;
cp.ipady = 50;
// Create playerBox spaces
playerSpaces = new BoardSpace [1][7];
BoardSpace.setPlayerSpaces(playerSpaces);
// Add playerSpaces to playerBox
for (int j = 0; j < 7; j++) {
// panel constraints
cGrid.gridx = 0; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
playerSpaces[0][j].setOpaque(false);
playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
playerBox.add(playerSpaces[0][j], cGrid);
}
// Add player box to south panel
playerPanel.add(playerBox, cp);
// Add player box to bottom of layeredPane
playerPanel.setBounds(0,825,810,75);
gameContainer.add(playerPanel, new Integer(0),0);
gameConsole.pack();
// Make gameConsole visible
gameConsole.setVisible(true);
}
Mouse Adapter:
public class MouseInput extends MouseAdapter {
/**
*
*/
private Component mouseArea;
private boolean dragging;
private Tile draggingTile;
private BoardSpace currentSpace;
private BoardSpace startingSpace;
private Component selectedObject;
Component [] panelObjects;
private JLayeredPane dragLayer;
private Point dragPoint;
private int dragWidth;
private int dragHeight;
public MouseInput(Component mouseArea) {
// TODO Auto-generated constructor stub
super();
mouseArea = this.mouseArea;
}
void eventOutput(String eventDescription, MouseEvent e) {
Point p = e.getPoint();
System.out.println(eventDescription
+ " (" + p.getX() + "," + p.getY() + ")"
+ " detected on "
+ e.getComponent().getClass().getName()
+ "\n");
}
public void mouseMoved(MouseEvent e) {
//eventOutput("Mouse moved", e);
}
public void mouseDragged(MouseEvent e) {
if (dragging) {
System.out.println("Dragging");
}
if (!dragging) {
return;
} else {
System.out.println("Dragging " + Tile.getLetter(draggingTile));
int x = e.getPoint().x - dragWidth;
int y = e.getPoint().y - dragHeight;
draggingTile.setLocation(x, y);
draggingTile.repaint();
}
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
//eventOutput("Mouse Clicked", e);
}
#Override
public void mouseEntered(MouseEvent e) {
/*
dragPoint = e.getPoint();
selectedObject = e.getComponent().getComponentAt(dragPoint);
// Get the current space
while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
try {
dragPoint = selectedObject.getMousePosition();
selectedObject = selectedObject.getComponentAt(dragPoint);
} catch (NullPointerException illegalSpace){
currentSpace = startingSpace;
break;
}
}
if (selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
currentSpace = (BoardSpace) selectedObject;
System.out.println(BoardSpace.getID(currentSpace));
} */
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
//eventOutput("Mouse Exited", e);
}
#Override
public void mousePressed(MouseEvent e) {
dragLayer = (JLayeredPane) e.getSource();
dragPoint = e.getPoint();
selectedObject = e.getComponent().getComponentAt(dragPoint);
// Get the current space
while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
try {
dragPoint = selectedObject.getMousePosition();
selectedObject = selectedObject.getComponentAt(dragPoint);
} catch (NullPointerException illegalSpace){
return;
}
}
currentSpace = (BoardSpace) selectedObject;
startingSpace = currentSpace;
// If the boardspace has a tile, remove Tile from boardspace and add to dragging layer
if (BoardSpace.Taken(currentSpace)) {
// get dragging tile
draggingTile = BoardSpace.getTile(currentSpace);
dragging = true;
// remove tile and repaint space
BoardSpace.removeTile(currentSpace, draggingTile);
currentSpace.revalidate();
currentSpace.repaint();
// Add tile to dragging layer
dragWidth = draggingTile.getWidth() / 2;
dragHeight = draggingTile.getHeight() / 2;
int x = e.getPoint().x - dragWidth;
int y = e.getPoint().y - dragHeight;
draggingTile.setLocation(x, y);
dragLayer.add(draggingTile, JLayeredPane.DRAG_LAYER);
draggingTile.revalidate();
draggingTile.repaint();
System.out.println("Selected Tile " + Tile.getLetter(draggingTile));
} else {
return;
}
}
#Override
public void mouseReleased(MouseEvent e) {
/*
// TODO Auto-generated method stub
if (!BoardSpace.Taken(currentSpace)) {
return;
} else {
dragging = false;
BoardSpace.setTile(currentSpace, draggingTile);
draggingTile = null;
currentSpace.repaint();
currentSpace.revalidate();
} */
}
}
Full code can be pulled from: https://github.com/jowarren13/scrabble.git
So after playing around some more, I figured out that every time a new mouse operation is called (mouse pressed, mouse dragged, etc.), it was instantiating new instances of the private class variables, so the variables weren't holding their set values. To work around this, I created a new class as an extension of JLayeredPane with these additional variables and used my new class as the layered game console. Still working out some error handling for when a tile is released outside of bounds or in an invalid space, but the code below at least lets me move the tiles around in valid spaces. The following post was helpful in figuring this out: MouseListener in separate class not working. Again, full code can be pulled from the git repo listed above.
BoardPane class:
package objects;
import java.awt.Component;
import java.awt.Point;
import javax.swing.JLayeredPane;
public class BoardPane extends JLayeredPane {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean dragging;
private Tile draggingTile;
private BoardSpace currentSpace;
private BoardSpace startingSpace;
private Component selectedObject;
Component [] panelObjects;
private BoardPane dragLayer;
private Point dragPoint;
private int dragWidth;
private int dragHeight;
public BoardPane() {
this.dragging = false;
this.draggingTile = null;
this.currentSpace = null;
this.startingSpace = null;
this.selectedObject = null;
this.panelObjects = null;
this.dragLayer = null;
this.dragPoint = null;
this.dragWidth = 51/2;
this.dragHeight = 51/2;
}
public static void resetPane(BoardPane board) {
board.dragging = false;
board.draggingTile = null;
board.currentSpace = null;
board.startingSpace = null;
board.selectedObject = null;
board.panelObjects = null;
board.dragLayer = null;
board.dragPoint = null;
}
public static Boolean getDragStatus(BoardPane board) {
return board.dragging;
}
public static void setDragStatus(BoardPane board, Boolean status) {
board.dragging = status;
}
public static Tile getDragTile(BoardPane board) {
return board.draggingTile;
}
public static void setDragTile(BoardPane board, Tile t) {
board.draggingTile = t;
}
public static BoardSpace getCurrentSpace(BoardPane board) {
return board.currentSpace;
}
public static void setCurrentSpace(BoardPane board, BoardSpace bs) {
board.currentSpace = bs;
}
public static BoardSpace getStartingSpace(BoardPane board) {
return board.startingSpace;
}
public static void setStartingSpace(BoardPane board, BoardSpace bs) {
board.startingSpace = bs;
}
public static Component getSelectedObj(BoardPane board) {
return board.selectedObject;
}
public static void setSelectedObj(BoardPane board, Component obj) {
board.selectedObject = obj;
}
public static Component [] getPanelObjects(BoardPane board) {
return board.panelObjects;
}
public static BoardPane getDragLayer(BoardPane board) {
return board.dragLayer;
}
public static void setDragLayer(BoardPane board) {
board.dragLayer = board;
}
public static void setPanelObjects(BoardPane board, Component [] obj) {
board.panelObjects = obj;
}
public static Point getDragPoint (BoardPane board) {
return board.dragPoint;
}
public static void setDragPoint(BoardPane board, Point p) {
board.dragPoint = p;
}
public static int getDragWidth(BoardPane board) {
return board.dragWidth;
}
public static int getDragHeight(BoardPane board) {
return board.dragHeight;
}
}
Console:
package Main;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import objects.BoardPane;
import objects.BoardSpace;
import javax.imageio.ImageIO;
public class Console {
private JFrame gameConsole;
private JPanel centerConsole;
private BoardPane gameContainer;
private JPanel playerPanel;
private JPanel gamePanel;
private JPanel north;
private JPanel south;
private JPanel east;
private JPanel west;
private JLayeredPane center;
private JPanel splash;
private JPanel playerBox;
private JPanel boardGrid;
private JPanel boardImage;
private JButton start;
private BoardSpace [][] spaces;
private BoardSpace [][] playerSpaces;
public Console () throws IOException{
// Create gameConsole
gameConsole = new JFrame();
final int frameWidth = 850;
final int frameHeight = 950;
gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight));
gameConsole.setTitle("Scrabble");
gameConsole.setLayout(new GridBagLayout());
gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.ipadx = 810;
c.ipady = 950;
// Create center console panel and add to gameConsole
centerConsole = new JPanel();
centerConsole.setLayout(new BorderLayout());
gameConsole.add(centerConsole,c);
// Create layered pane that holds the board and playerbox
gameContainer = new BoardPane();
gameContainer.setBounds(0,0,810,950);
MouseInput mouseActions = new MouseInput();
gameContainer.addMouseMotionListener(mouseActions);
gameContainer.addMouseListener(mouseActions);
centerConsole.add(gameContainer, BorderLayout.CENTER);
// Create board image label and add to JPanel
BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg"));
JLabel background = new JLabel(new ImageIcon(scrabbleImage));
boardImage = new JPanel();
boardImage.setBounds(0, 0, 810, 815);
boardImage.add(background);
boardImage.setOpaque(true);
// create JPanel with gridBagLayout
boardGrid = new JPanel();
boardGrid.setBounds(0, 3, 810, 810);
boardGrid.setLayout(new GridBagLayout());
boardGrid.setOpaque(false);
// Create panels to add to boardGrid
spaces = new BoardSpace [15][15];
BoardSpace.setBoardSpaces(spaces);
// Set grid constraints
GridBagConstraints cGrid = new GridBagConstraints();
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
// panel constraints
cGrid.gridx = i; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
spaces[i][j].setOpaque(false);
spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
boardGrid.add(spaces[i][j], cGrid);
}
}
// Add to layeredPane
gameContainer.add(boardImage, new Integer(0),0);
gameContainer.add(boardGrid, new Integer(1),0);
// Create player box panel
playerPanel = new JPanel();
playerPanel.setLayout(new GridBagLayout());
playerBox = new JPanel();
playerBox.setLayout(new GridLayout(1,7, 10, 0));
// Create player box constraints
GridBagConstraints cp = new GridBagConstraints();
cp.ipadx = 50;
cp.ipady = 50;
// Create playerBox spaces
playerSpaces = new BoardSpace [1][7];
BoardSpace.setPlayerSpaces(playerSpaces);
// Add playerSpaces to playerBox
for (int j = 0; j < 7; j++) {
// panel constraints
cGrid.gridx = 0; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
playerSpaces[0][j].setOpaque(false);
playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
playerBox.add(playerSpaces[0][j], cGrid);
}
// Add player box to south panel
playerPanel.add(playerBox, cp);
// Add player box to bottom of layeredPane
playerPanel.setBounds(0,825,810,75);
gameContainer.add(playerPanel, new Integer(0),0);
gameConsole.pack();
// Make gameConsole visible
gameConsole.setVisible(true);
}
}
Mouse Listener:
package Main;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JLayeredPane;
import objects.BoardSpace;
import objects.Tile;
import objects.BoardPane;
public class MouseInput implements MouseMotionListener, MouseListener {
/**
*
*/
private BoardPane dragLayer;
void eventOutput(String eventDescription, MouseEvent e) {
Point p = e.getPoint();
System.out.println(eventDescription
+ " (" + p.getX() + "," + p.getY() + ")"
+ " detected on "
+ e.getComponent().getClass().getName()
+ "\n");
}
#Override
public void mouseMoved(MouseEvent e) {
//eventOutput("Mouse moved", e);
}
#Override
public void mouseDragged(MouseEvent e) {
// Set dragLayer
dragLayer = BoardPane.getDragLayer((BoardPane) e.getSource());
// Drag tile across board
if (BoardPane.getDragStatus(dragLayer)) {
int x = e.getPoint().x - BoardPane.getDragWidth(dragLayer);
int y = e.getPoint().y - BoardPane.getDragHeight(dragLayer);
BoardPane.getDragTile(dragLayer).setLocation(x, y);
BoardPane.getDragTile(dragLayer).repaint();
System.out.println("Dragging Tile " + Tile.getLetter(BoardPane.getDragTile(dragLayer)));
}
}
#Override
public void mouseClicked(MouseEvent e) {
//eventOutput("Mouse Clicked", e);
}
#Override
public void mouseEntered(MouseEvent e) {
eventOutput("Mouse entered", e);
}
#Override
public void mouseExited(MouseEvent e) {
eventOutput("Mouse Exited", e);
}
#Override
public void mousePressed(MouseEvent e) {
eventOutput("Mouse Pressed", e);
// Set dragLayer, dragPoint, and selectedObject
BoardPane.setDragLayer((BoardPane) e.getSource());
dragLayer = (BoardPane) e.getSource();
BoardPane.setDragPoint(dragLayer, e.getPoint());
BoardPane.setSelectedObj(dragLayer, e.getComponent().getComponentAt(BoardPane.getDragPoint(dragLayer)));
// Find the current board space
try {
while (!BoardPane.getSelectedObj(dragLayer).getClass().getSimpleName().equals("BoardSpace")) {
BoardPane.setDragPoint(dragLayer, BoardPane.getSelectedObj(dragLayer).getMousePosition());
BoardPane.setSelectedObj(dragLayer, BoardPane.getSelectedObj(dragLayer).getComponentAt(BoardPane.getDragPoint(dragLayer)));
}
} catch (NullPointerException illegalSpace) {
return;
}
// Set the current board space & starting space
BoardPane.setCurrentSpace(dragLayer, (BoardSpace) BoardPane.getSelectedObj(dragLayer));
BoardPane.setStartingSpace(dragLayer, BoardPane.getCurrentSpace(dragLayer));
// If the board space has a tile, remove Tile from board space then add to dragging layer
if (BoardSpace.Taken(BoardPane.getCurrentSpace(dragLayer))) {
// get dragging tile
BoardPane.setDragTile(dragLayer, BoardSpace.getTile(BoardPane.getCurrentSpace(dragLayer)));
BoardPane.setDragStatus(dragLayer, true);
// remove tile and repaint space
BoardSpace.removeTile(BoardPane.getCurrentSpace(dragLayer), BoardPane.getDragTile(dragLayer));
BoardPane.getCurrentSpace(dragLayer).revalidate();
BoardPane.getCurrentSpace(dragLayer).repaint();
// Add tile to dragging layer at specified location
int x = e.getPoint().x - BoardPane.getDragWidth(dragLayer);
int y = e.getPoint().y - BoardPane.getDragHeight(dragLayer);
BoardPane.getDragTile(dragLayer).setLocation(x, y);
dragLayer.add(BoardPane.getDragTile(dragLayer), JLayeredPane.DRAG_LAYER);
BoardPane.getDragTile(dragLayer).revalidate();
BoardPane.getDragTile(dragLayer).repaint();
System.out.println("Selected Tile " + Tile.getLetter(BoardPane.getDragTile(dragLayer)));
} else {
return;
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (BoardPane.getDragStatus(dragLayer) == true) {
// Change drag status to false
BoardPane.setDragStatus(dragLayer, false);
// Set dragLayer & remove tile
dragLayer = BoardPane.getDragLayer((BoardPane) e.getSource());
dragLayer.remove(BoardPane.getDragTile(dragLayer));
dragLayer.revalidate();
dragLayer.repaint();
//get selected object at given point
BoardPane.setDragPoint(dragLayer, e.getPoint());
BoardPane.setSelectedObj(dragLayer, e.getComponent().getComponentAt(BoardPane.getDragPoint(dragLayer)));
// Find the current board space
try {
while(!BoardPane.getSelectedObj(dragLayer).getClass().getSimpleName().equals("BoardSpace")) {
BoardPane.setDragPoint(dragLayer, BoardPane.getSelectedObj(dragLayer).getMousePosition());
BoardPane.setSelectedObj(dragLayer, BoardPane.getSelectedObj(dragLayer).getComponentAt(BoardPane.getDragPoint(dragLayer)));
}
} catch (NullPointerException illegalSpace) {
// if released on an invalid space, put tile back in starting space
BoardPane.getStartingSpace(dragLayer).add(BoardPane.getDragTile(dragLayer));
BoardPane.getStartingSpace(dragLayer).revalidate();
BoardPane.getStartingSpace(dragLayer).repaint();
BoardPane.resetPane(dragLayer);
return;
}
// Set the current board space & starting space
BoardPane.setCurrentSpace(dragLayer, (BoardSpace) BoardPane.getSelectedObj(dragLayer));
// If space is not taken, add tile to space, otherwise put back in starting space
if (!BoardSpace.Taken(BoardPane.getCurrentSpace(dragLayer))) {
BoardSpace.setTile(BoardPane.getCurrentSpace(dragLayer), BoardPane.getDragTile(dragLayer));
BoardPane.getCurrentSpace(dragLayer).revalidate();
BoardPane.getCurrentSpace(dragLayer).repaint();
//BoardPane.setDragTile(dragLayer, null);
} else {
BoardPane.getStartingSpace(dragLayer).add(BoardPane.getDragTile(dragLayer));
BoardPane.getStartingSpace(dragLayer).revalidate();
BoardPane.getStartingSpace(dragLayer).repaint();
}
BoardPane.resetPane(dragLayer);
}
}
}
I hope some one can help me, this is what I want to do.
I have a JTextPane and I want to take a screenshot to that specific JTextPane coordinates and size, so far I can do a screenshot with the size of the JTextPane but I can't get the specific coordinates my screenshots always gets the (0,0) coordinates.
This is my method:
void capturaPantalla ()
{
try
{
int x = txtCodigo.getX();
int y = txtCodigo.getY();
Rectangle areaCaptura = new Rectangle(x, y, txtCodigo.getWidth(), txtCodigo.getHeight());
BufferedImage capturaPantalla = new Robot().createScreenCapture(areaCaptura);
File ruta = new File("P:\\captura.png");
ImageIO.write(capturaPantalla, "png", ruta);
JOptionPane.showMessageDialog(null, "Codigo de barras guardado!");
}
catch (IOException ioe)
{
System.out.println(ioe);
}
catch(AWTException ex)
{
System.out.println(ex);
}
}
When you call getX() and getY() on any Swing component, you get the x and y relative to the component's container, not the screen. Instead you want the location of the component relative to the screen and get position based on that via getLocationOnScreen()
Point p = txtCodigo.getLocationOnScreen();
int x = p.x;
int y = p.y;
As per MadProgrammer's comment, you could simply call printAll(Graphics g) on your txtCodigo component, passing in a Graphics object obtained from a properly sized BufferedImage and forgo use of a Robot.
Dimension d = txtCodigo.getSize();
BufferedImage img = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
txtCodigo.printAll(g);
g.dispose();
// use ImageIO to write BufferedImage to file
To compare to the two methods:
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class RobotVsPrintAll extends JPanel {
private static final int WORDS = 400;
private JTextArea textArea = new JTextArea(20, 40);
private JScrollPane scrollPane = new JScrollPane(textArea);
private Random random = new Random();
public RobotVsPrintAll() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < WORDS; i++) {
int wordLength = random.nextInt(4) + 4;
for (int j = 0; j < wordLength; j++) {
char myChar = (char) (random.nextInt('z' - 'a' + 1) + 'a');
sb.append(myChar);
}
sb.append(" ");
}
textArea.setText(sb.toString());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JButton robot1Btn = new JButton(new Robot1Action("Robot 1"));
JButton robot2Btn = new JButton(new Robot2Action("Robot 2"));
JButton printAllBtn = new JButton(new PrintAllAction("Print All"));
JPanel btnPanel = new JPanel();
btnPanel.add(robot1Btn);
btnPanel.add(robot2Btn);
btnPanel.add(printAllBtn);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private void displayImg(BufferedImage img) {
ImageIcon icon = new ImageIcon(img);
JOptionPane.showMessageDialog(this, icon, "Display Image",
JOptionPane.PLAIN_MESSAGE);
}
private class Robot1Action extends AbstractAction {
public Robot1Action(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
try {
Component comp = scrollPane.getViewport();
Point p = comp.getLocationOnScreen();
Dimension d = comp.getSize();
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(p.x, p.y, d.width, d.height);
BufferedImage img = robot.createScreenCapture(screenRect);
displayImg(img);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
private class Robot2Action extends AbstractAction {
public Robot2Action(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
try {
Component comp = textArea;
Point p = comp.getLocationOnScreen();
Dimension d = comp.getSize();
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(p.x, p.y, d.width, d.height);
BufferedImage img = robot.createScreenCapture(screenRect);
displayImg(img);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
private class PrintAllAction extends AbstractAction {
public PrintAllAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(ActionEvent e) {
Dimension d = textArea.getSize();
BufferedImage img = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
textArea.printAll(g);
g.dispose();
displayImg(img);
}
}
private static void createAndShowGui() {
RobotVsPrintAll mainPanel = new RobotVsPrintAll();
JFrame frame = new JFrame("Robot Vs PrintAll");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
If you print the text component with printAll, you get the entire text component, even the parts that are not displayed in the JScrollPane's viewport.
You can use the Screen Image class which does all the work for you. All you do is specify the component you want to capture.
The code would be:
BufferedImage bi = ScreenImage.createImage( component );
And you can save the image to a file using:
ScreenImage.writeImage(bi, "imageName.jpg");
This class will use the painting method of the Swing component which is more efficient than using a Robot.
I have a 2d array of Grids (JPanels) that are added to another JPanel using the GridLayout. That JPanel is added to the JFrame. Whenever a click happens on the JFrame I'm attempting to take the Point of the click and determine if any of those Grids in the 2d array contain that Point.
I'm attempting to do this inside frame.addMouseListener...
I know the frame is registering the mouse clicks. For some reason the Grids don't register that they should be containing that Point. Can anyone explain this? if(theView[i][j].contains(me.getPoint())){ This is the line of code that seems to be failing me.
I originally attempted to have the Grids know when they were clicked on so I wouldn't have to coordinate between the frame and grids, but I couldn't get that to work.
Here's the level designer.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import javax.swing.*;
public class LevelDesigner extends JPanel implements ButtonListener{
private final int SIZE = 12;
private int [][] thePit;
private Grid [][] theView;
private ButtonPanel bp;
public static int val;
private int rows, cols;
private JPanel gridPanel;
private JFrame frame;
public LevelDesigner(int r, int c){
frame = new JFrame();
int h = 10, w = 10;
setVisible(true);
setLayout(new BorderLayout());
setBackground(Color.BLUE);
rows = r;
cols = c;
thePit = new int[r][c];
theView = new Grid[r][c];
gridPanel = new JPanel();
gridPanel.setVisible(true);
gridPanel.setBackground(Color.BLACK);
gridPanel.setPreferredSize(getMaximumSize());
GridLayout gridLayout = new GridLayout();
gridLayout.setColumns(cols);
gridLayout.setRows(rows);
gridPanel.setLayout(gridLayout);
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
theView[i][j] = new Grid(i, j, SIZE, this);
gridPanel.add(theView[i][j]);
}
}
String test [] = {"0", "1","2","3","4","save"};
bp = new ButtonPanel(test, this);
this.add(bp, BorderLayout.SOUTH);
this.add(gridPanel, BorderLayout.CENTER);
frame.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me) {
for(int i = 0; i < rows; ++i){
for(int j = 0; j < cols; ++j){
if(theView[i][j].contains(me.getPoint())){
theView[i][j].actionPerformed(null);
return;
}
}
}
}
});
frame.setVisible(true);
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
frame.setTitle("Epic Crawl - Main Menu");
frame.pack();
frame.setLocationRelativeTo(null);
frame.repaint();
frame.add(this);
}
public String toString(){
int noRows = thePit.length;
int noColumns = thePit[0].length;
String s="";
for (int r=0;r<noRows;r++){
for (int c=0;c<noColumns;c++){
s=s + thePit[r][c] + " ";
}
s=s+"\n";
}
return(s);
}
public void notify( int i, int j){
thePit[i][j] = val;
}
public void print(){
final JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new java.io.File("."));
int returnVal = fc.showSaveDialog( null);
if( returnVal == JFileChooser.APPROVE_OPTION ){
try{
PrintWriter p = new PrintWriter(
new File( fc.getSelectedFile().getName() ) );
System.out.println(" printing");
p.println( this );
p.close();
}
catch( Exception e){
System.out.println("ERROR: file not saved");
}
}
}
public void buttonPressed(String buttonLabel, int id){
if(id == 5)
print();
else
val = id;
}
public void buttonReleased( String buttonLabel, int buttonId ){}
public void buttonClicked( String buttonLabel, int buttonId ){}
public static void main(String arg[]){
LevelDesigner levelDesigner = new LevelDesigner(4, 4);
}
}
And here is the Grid.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Grid extends JPanel implements ActionListener{
LevelDesigner grid;
int myI, myJ;
private String[] imageNames = {"dirt.png", "grass.png", "Door.png", "woodfloor.png", "32x32WoodFloor.png"};
BufferedImage gridImage;
private String imagePath;
public Grid(int i, int j, int size, LevelDesigner m){
imagePath = "";
grid = m;
myI = i;
myJ = j;
setBackground(Color.RED);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae){
grid.notify(myI, myJ);
imagePath = "Images/" + imageNames[LevelDesigner.val];
gridImage = null;
InputStream input = this.getClass().getClassLoader().getResourceAsStream(imagePath);
try{
gridImage = ImageIO.read(input);
}catch(Exception e){System.err.println("Failed to load image");}
}
public void paintComponent(Graphics g){
super.paintComponent(g); // Important to call super class method
g.clearRect(0, 0, getWidth(), getHeight()); // Clear the board
g.drawImage(gridImage, 0, 0, getWidth(), getHeight(), null);
}
}
The contains method checks if the Point is within the boundaries of the JPanel but using a coordinate system relative to the JPanel. Instead consider using findComponentAt(Point p).
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TestMouseListener {
private static final int SIDE_COUNT = 4;
private JPanel mainPanel = new JPanel();
private MyGridCell[][] grid = new MyGridCell[SIDE_COUNT][SIDE_COUNT];
public TestMouseListener() {
mainPanel.setLayout(new GridLayout(SIDE_COUNT, SIDE_COUNT));
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new MyGridCell();
mainPanel.add(grid[i][j].getMainComponent());
}
}
mainPanel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = mainPanel.findComponentAt(p);
for (MyGridCell[] gridRow : grid) {
for (MyGridCell myGridCell : gridRow) {
if (c == myGridCell.getMainComponent()) {
myGridCell.setLabelText("Pressed!");
} else {
myGridCell.setLabelText("");
}
}
}
}
});
}
public Component getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
TestMouseListener mainPanel = new TestMouseListener();
JFrame frame = new JFrame("TestMouseListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyGridCell {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
#SuppressWarnings("serial")
private JPanel mainPanel = new JPanel() {
public Dimension getPreferredSize() {
return MyGridCell.this.getPreferredSize();
};
};
private JLabel label = new JLabel();
public MyGridCell() {
mainPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.setLayout(new GridBagLayout());
mainPanel.add(label);
}
public Component getMainComponent() {
return mainPanel;
}
public void setLabelText(String text) {
label.setText(text);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Component#contains "Checks whether this component "contains" the specified point, where the point's x and y coordinates are defined to be relative to the coordinate system of this component"
This means that the contains will only return true if the Point is within the bounds of 0 x 0 x width x height.
So if the component is position at 400x200 and is sized at 200x200 (for example). When you click within in, the mouse point will be between 400x200 and 600x400, which is actually out side of the relative position of the component (200x200) - confused yet...
Basically, you either need to convert the click point to a relative coordinate within the context of the component you are checking...
Point p = SwingUtilities.convertPoint(frame, me.getPoint(), theView[i][j])
if (theView[i][j].contains(p)) {...
Or use the components Rectangle bounds...
if (theView[i][j].getBounds().contains(me.getPoint())) {...
So, remember, mouse events are relative to the component that they were generated for
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java swing background image
drawing your own buffered image on frame
I am trying to add a back ground image to my frame, but nothing that I have done works.
I designed a slot machine consisting of several panels added to the container. Now, I am trying to add a nice background to the frame.
I tried using the paint method. But, since I am already using the paint method to paint the reel images, it is not working on the background.
I also tried adding a JLabel, but when I do it overwrites everything or get overwritten depending on how I call it. Following is my code; any help will be much appreciated:
import javax.swing.event.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import sun.audio.*;
public class SlotMachine extends JFrame {
private Container c = getContentPane();
private ImageIcon handleIcon = new ImageIcon("starWars/slot-handle.png");
private ImageIcon quitIcon = new ImageIcon("starWars/quit2.jpg");
private ImageIcon logoIcon = new ImageIcon("starWars/logo3.jpg");
private ImageIcon BG = new ImageIcon("space.jpg");
private JButton spin = new JButton("Spin", handleIcon);
private JButton quit = new JButton("Quit", quitIcon);
private JLabel logo = new JLabel(logoIcon);
private JLabel bankTotal = new JLabel("Empire Total");
private JLabel bankLabel = new JLabel("$1000.00");
private JLabel playerLabel = new JLabel("$1000.00");
private JLabel playerTotal = new JLabel("Rebellion Total");
private Font newFont = new Font("DialogInput",Font.ITALIC, 25);
private JPanel logoPanel = new JPanel(new BorderLayout());
private JPanel moneyPanel = new JPanel(new GridLayout(1, 3, 5, 5));
private JPanel imagePanel;
private JPanel mainPanel = new JPanel(new BorderLayout());
private JPanel bankPanel = new JPanel(new GridLayout(2, 1, 5, 5));
private JPanel playerPanel = new JPanel(new GridLayout(2, 1, 5, 5));
private JPanel panel = new JPanel(new FlowLayout());
private SlotMachine.ReelPanel reel1 = new SlotMachine.ReelPanel();
private SlotMachine.ReelPanel reel2 = new SlotMachine.ReelPanel();
private SlotMachine.ReelPanel reel3 = new SlotMachine.ReelPanel();
private AudioPlayer audioPlayer = AudioPlayer.player;
private AudioDataStream continuousMusic;
private AudioDataStream winMusic;
private AudioDataStream force;
private AudioDataStream force2;
//private AudioDataStream intro;
private ContinuousAudioDataStream audioLoop;
private static final int DELAY = 1000;
private static final double FUNDS = 1000.00;
private static final float PRICE = 1;
private int timerCounter = 0;
private double bank = FUNDS;
private double playerMoney = 1000.00;
private Timer timer = new Timer(DELAY, new SlotMachine.TimeHandler());
public SlotMachine() {
try {
FileInputStream inputStream = new FileInputStream(new File("cantina4.wav"));
AudioStream audioStream = new AudioStream(inputStream);
AudioData audioData = audioStream.getData();
continuousMusic = new AudioDataStream(audioData);
audioLoop = new ContinuousAudioDataStream(audioData);
inputStream = new FileInputStream(new File("Cheer.wav"));
audioStream = new AudioStream(inputStream);
audioData = audioStream.getData();
winMusic = new AudioDataStream(audioData);
inputStream = new FileInputStream(new File("forceNN.wav"));
audioStream = new AudioStream(inputStream);
audioData = audioStream.getData();
force = new AudioDataStream(audioData);
inputStream = new FileInputStream(new File("force2NN.wav"));
audioStream = new AudioStream(inputStream);
audioData = audioStream.getData();
force2 = new AudioDataStream(audioData);
} catch (Exception e) {
e.printStackTrace();
}
audioPlayer.start(force);
// Set the font
spin.setFont(newFont);
quit.setFont(newFont);
bankLabel.setFont(newFont);
bankTotal.setFont(newFont);
playerLabel.setFont(newFont);
playerTotal.setFont(newFont);
// implements start button
spin.setVerticalTextPosition(SwingConstants.BOTTOM);
spin.setHorizontalTextPosition(SwingConstants.CENTER);
spin.setBackground(Color.GREEN);
spin.setForeground(Color.WHITE);
spin.setPreferredSize(new Dimension(100, 370));
spin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
audioPlayer.stop(force);
audioPlayer.stop(force2);
timer.start();
reel1.startAnimation();
reel2.startAnimation();
reel3.startAnimation();
spin.setEnabled(false);
audioPlayer.start(audioLoop);
}
});
// implements quit button
quit.setBackground(Color.RED);
quit.setForeground(Color.WHITE);
quit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
spin.setEnabled(true);
reel1.stopAnimation();
reel2.stopAnimation();
reel3.stopAnimation();
timer.stop();
audioPlayer.stop(continuousMusic);
audioPlayer.stop(audioLoop);
audioPlayer.stop(winMusic);
timerCounter = 0;
audioPlayer.stop(force);
audioPlayer.start(force2);
imagePanel.repaint(); // without this call for repaint, if you press quit but then choose to cancel
// the curent image and the next image would sometimes overlap this repaint may change the images but they do not overlap.
if (JOptionPane.showConfirmDialog(SlotMachine.this,
"Are you sure you want to quit?", "Quit Option",
JOptionPane.OK_CANCEL_OPTION) == 0) {
audioPlayer.start(force2);
System.exit(0);
}
}
});
// create image panel
imagePanel = new JPanel(new GridLayout(1, 3, 15, 15));
imagePanel.setBackground(Color.WHITE);
imagePanel.add(reel1);
imagePanel.add(reel2);
imagePanel.add(reel3);
// create a panel to hold bank values
bankTotal.setForeground(Color.WHITE);
bankLabel.setForeground(Color.WHITE);
bankPanel.setBackground(Color.GRAY);
bankPanel.add(bankTotal);
bankPanel.add(bankLabel);
// panel to hold player values
playerTotal.setForeground(Color.WHITE);
playerLabel.setForeground(Color.WHITE);
playerPanel.setBackground(Color.GRAY);
playerPanel.add(playerTotal);
playerPanel.add(playerLabel);
// create a panel to add bank and player panels and quit button
//moneyPanel.setBackground(Color.BLACK);
moneyPanel.add(bankPanel);
moneyPanel.add(playerPanel);
moneyPanel.add(quit);
moneyPanel.setOpaque(false);
// this panel adds the reel panel and spin button
panel.setPreferredSize(new Dimension(650, 350));
//panel.setBackground(Color.BLACK);
panel.add(imagePanel);
panel.add(spin);
panel.setOpaque(false);
// create the logo panel
logoPanel.add(logo);
//logoPanel.setBackground(Color.BLACK);
logoPanel.setOpaque(false);
mainPanel.add(logoPanel, BorderLayout.NORTH);
mainPanel.add(panel, BorderLayout.CENTER);
mainPanel.add(moneyPanel, BorderLayout.SOUTH);
mainPanel.setOpaque(false);
//////////////////////////////////// background ???????????????????
/// I could just set backgroung black but i want to add a image
add(mainPanel, BorderLayout.CENTER);
setTitle("Slot Machine");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(950, 750);
setResizable(false);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new SlotMachine();
}
public class ReelPanel extends JPanel {
private final static String IMAGE_NAME = "starWars/icon";
protected ImageIcon images[];
private int currentImage = 0;
private final int ANIMATION_DELAY = 150;
private final int TOTAL_IMAGES = 12;
private int width;
private int height;
private Timer animationTimer = new Timer(ANIMATION_DELAY, new SlotMachine.ReelPanel.TimerHandler());
private int index;
public ReelPanel() {
try {
images = new ImageIcon[TOTAL_IMAGES];
for (int count = 0; count < images.length; count++) {
images[ count] = new ImageIcon(IMAGE_NAME + (count + 1) + ".jpg");
}
width = images[ 1].getIconWidth();
height = images[ 1].getIconHeight();
currentImage = 0;
index = 0;
animationTimer.setInitialDelay(0);
} catch (Exception e) {
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
images[ currentImage].paintIcon(this, g, 0, 0);
if (animationTimer.isRunning()) {
currentImage = (int) (Math.random() * TOTAL_IMAGES);
}
}
public void startAnimation() {
animationTimer.start();
}
public void stopAnimation() {
animationTimer.stop();
}
public int getIndex() {
return index;
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
private class TimerHandler implements ActionListener {
public void actionPerformed(ActionEvent actionEvent) {
repaint();
index = currentImage;
}
}
}
private class TimeHandler implements ActionListener {
public void actionPerformed(ActionEvent actionEvent) {
audioPlayer.stop(winMusic);
++timerCounter;
if (timerCounter == 2) {
reel1.stopAnimation();
} else if (timerCounter == 3) {
reel2.stopAnimation();
} else if (timerCounter == 4) {
reel3.stopAnimation();
audioPlayer.stop(continuousMusic);
audioPlayer.stop(audioLoop);
timerCounter = 0;
timer.stop();
spin.setEnabled(true);
if (reel1.getIndex() == reel2.getIndex() && reel1.getIndex() == reel3.getIndex()) {
if (playerMoney > 0) {
playerMoney += bank;
} else {
playerMoney = bank;
}
bank = FUNDS;
winMusic.reset();
audioPlayer.start(winMusic);
} else {
bank += PRICE;
playerMoney -= PRICE;
}
bankLabel.setText("$" + bank + 0);
playerLabel.setText("$" + playerMoney + 0);
if (playerMoney <= 0) {
JOptionPane.showMessageDialog(SlotMachine.this,
"You are out of funds. GAME IS OVER", "Error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
}
}
}
You can simply override paintComponent for your mainPanel and draw the background image in that method. You should choose the appropriate strategy for painting your image (stretch it, keep aspect ratio, repeat horizontally/vertically) but that should not be too hard.
Here is an example that stretches the image over the content pane.
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestBackgroundImage {
private static final String BACKHGROUND_IMAGE_URL = "http://cache2.allpostersimages.com/p/LRG/27/2740/AEPND00Z/affiches/blue-fiber-optic-wires-against-black-background.jpg";
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(TestBackgroundImage.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageIcon backgroundImage = new ImageIcon(new URL(BACKHGROUND_IMAGE_URL));
JPanel mainPanel = new JPanel(new BorderLayout()) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(backgroundImage.getImage(), 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width = Math.max(backgroundImage.getIconWidth(), size.width);
size.height = Math.max(backgroundImage.getIconHeight(), size.height);
return size;
}
};
mainPanel.add(new JButton("A button"), BorderLayout.WEST);
frame.add(mainPanel);
frame.setSize(400, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestBackgroundImage().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Set the layout of your main panel to BorderLayout
Create a JLabel and add it to you main panel
Set the image icon of the label using your background image
Set the layout of the label to what ever you want to use
Continue adding your components to the label as you normally would
An example can be found here