So I'm attempting to rotate an image using animation by having it change images to a new one that has been rotated 22.5 degrees. I'm doing this by having 1 class inheriting from a JFrame and the other class from a JPanel However it is not doing anything. Here is the code..
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.event.*;
public class LogoAnimatorJPanel extends JPanel implements ActionListener
{
protected ImageIcon[] images = new ImageIcon[16] ;
private int currentImage = 0;
private Timer animationTimer;
public LogoAnimatorJPanel()
{
for ( int count = 0; count < images.length; count++ ){
images [count] = new ImageIcon("car/yellowCar" + count + ".jpg");
}
startAnimation();
}
public void paintComponent( Graphics g )
{
super.paintComponent( g );
images[ currentImage ].paintIcon( this, g, 50 , 50 );
currentImage = ( currentImage + 1 ) % images.length;
}
public void startAnimation()
{
animationTimer = new Timer(20, this);
animationTimer.start();
}
public void actionPerformed( ActionEvent actionEvent )
{
repaint();
}
}
displayAnimator
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class displayAnimator extends JFrame
{
private LogoAnimatorJPanel fp;
public displayAnimator()
{
setTitle("car");
setBounds(200,200,200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = getContentPane();
cp.setLayout(null);
fp = new LogoAnimatorJPanel();
fp.setBounds(180, 25, 100, 100);
cp.add(fp);
}
public static void main(String[] args)
{
displayAnimator testRun = new displayAnimator();
testRun.setVisible(true);
}
}
Any Ideas?
Here is a working demo. of the things I was discussing above, along with a few more tweaks. Read code carefully for changes, do some research on the new/different method calls, and ask if you don't understand (from that research) why I included them. Note that this class includes a main method.
import java.awt.Image;
import java.awt.event.*;
import java.net.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class LogoAnimator {
private int currentImage = 0;
private JLabel animationDisplayLabel = new JLabel();
private Timer animationTimer;
private String prefix = "http://i.stack.imgur.com/";
private String suffix = ".png";
private String[] imageNames = {"gJmeJ", "L5DGx", "in9g1", "IucNt", "yoKxT"};
protected ImageIcon[] images = new ImageIcon[imageNames.length];
public LogoAnimator() {
for (int count = 0; count < images.length; count++) {
try {
URL url = new URL(prefix + imageNames[count] + suffix);
Image image = ImageIO.read(url);
images[count] = new ImageIcon(image);
} catch (Exception ex) { // TODO! Better exception handling!
ex.printStackTrace();
}
}
startAnimation();
}
public void startAnimation() {
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
currentImage = (currentImage + 1) % images.length;
animationDisplayLabel.setIcon(images[currentImage]);
}
};
animationDisplayLabel.setIcon(images[0]);
animationTimer = new Timer(200, listener);
animationTimer.start();
}
public JComponent getAnimationComponent() {
return animationDisplayLabel;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
LogoAnimator fp = new LogoAnimator();
JFrame f = new JFrame("car");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(fp.getAnimationComponent());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
Related
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class slide extends JFrame
{
ImageIcon[] iconArray = new ImageIcon[25];
int iconIndex = 0;
JLabel label;
JPanel panel;
slide ()
{
panel = new JPanel();
label = new JLabel();
add(panel);
setTitle("Slide Show");
panel.add(label);
for(int i = 0; i < iconArray.length; i++)
{
iconArray[i] = new ImageIcon("C:/SlideShow/slide0.jpg");
}
Timer timer = new Timer(1000, new TimerListener());
timer.start();
}
private class TimerListener implements ActionListener
{
public void actionPerformed(ActionEvent actionEvent)
{
label.setIcon(iconArray[iconIndex]);
iconIndex++ ;
if(iconIndex == 25)
iconIndex = 0;
}
}
public static void main(String[] args)
{
slide frame = new slide();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
}
}
Any idea how to make a slideshow to show pictures with different > > time intervals? For example 1 sec for the first picture, 200 ms for > > the next, 3 sec for the third and etc. > > > > many thanks for the help!!!
A Swing timer has at most two delays. You can set the initial delay and the interval delay.
A Thread gives you more control over how long you sleep between images.
Here's one way to develop a slide show viewer that allows you to set the delay for each image. I used 3 images from the Internet to test the viewer.
package com.ggl.testing;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Slideshow implements Runnable {
private JFrame frame;
private SSImage[] imageArray;
private SSShower showImages;
private SSViewer imageViewer;
public Slideshow() {
this.imageArray = new SSImage[3];
Image image0 = null;
Image image1 = null;
Image image2 = null;
try {
image0 = ImageIO.read(new URL(
"http://www.ericofon.com/collection/collection1.jpg"));
image1 = ImageIO
.read(new URL(
"http://magiclinks1.wikispaces.com/file/view"
+ "/collection11_lg.jpg/219833158/collection11_lg.jpg"));
image2 = ImageIO
.read(new URL(
"http://www.pokelol.com/wp-content/uploads/2011/12"
+ "/my_pokemon_collection_by_pa_paiya-d4iiuo5.jpg"));
} catch (IOException e) {
e.printStackTrace();
return;
}
imageArray[0] = new SSImage(image0, 4000L);
imageArray[1] = new SSImage(image1, 2500L);
imageArray[2] = new SSImage(image2, 1500L);
}
#Override
public void run() {
frame = new JFrame("Check Box Test");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
imageViewer = new SSViewer(700, 700);
frame.add(imageViewer);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
showImages = new SSShower(imageArray, imageViewer);
new Thread(showImages).start();
}
private void exitProcedure() {
showImages.setRunning(false);
frame.dispose();
System.exit(0);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Slideshow());
}
public class SSImage {
private final long delay;
private final Image image;
public SSImage(Image image, long delay) {
this.image = image;
this.delay = delay;
}
public long getDelay() {
return delay;
}
public Image getImage() {
return image;
}
}
public class SSViewer extends JPanel {
private static final long serialVersionUID = -7893539139464582702L;
private Image image;
public SSViewer(int width, int height) {
this.setPreferredSize(new Dimension(width, height));
}
public void setImage(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, (this.getWidth() - image.getWidth(this)) / 2,
(this.getHeight() - image.getHeight(this)) / 2, this);
}
}
public class SSShower implements Runnable {
private int counter;
private volatile boolean running;
private SSViewer ssviewer;
private SSImage[] imageArray;
public SSShower(SSImage[] imageArray, SSViewer ssviewer) {
this.imageArray = imageArray;
this.ssviewer = ssviewer;
this.counter = 0;
this.running = true;
}
#Override
public void run() {
while (running) {
SSImage ssimage = imageArray[counter];
ssviewer.setImage(ssimage.getImage());
repaint();
sleep(ssimage.getDelay());
counter = ++counter % imageArray.length;
}
}
private void repaint() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ssviewer.repaint();
}
});
}
private void sleep(long delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
}
public synchronized void setRunning(boolean running) {
this.running = running;
}
}
}
I have created this very simple animation class with a timer that is supposed to make a rectangle move across the screen:
package NinjaChefGame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Animation extends JPanel implements ActionListener{
Timer tm = new Timer (5,this);
int x= 0,velx=2;
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.setColor (Color.RED);
g.fillRect(x,30,50,30);
tm.start();
}
public void actionPerformed(ActionEvent e) {
x=x+velx ;
repaint();
}
}
here is my level one class:
package NinjaChefGame;
import org.jbox2d.common.Vec2;
import city.cs.engine.*;
public class DemoWorld extends GameHub {
private Ant ant;
private Ant anttwo;
private Ant antthree;
private Ant antfour;
private Ant antfive;
private Ant antsix;
private final static int NUM_ANTS =2;
private final static int NUM_ANTSTWO =2;
private SoupBowlOne soupbowlone;
private Fixture fixture;
private World world;
public void populate(Demo demo) {
super.populate(demo);
{
Shape floorshape = new BoxShape(20f, 0.5f);
Body floor = new StaticBody(this, floorshape);
floor.setPosition(new Vec2(0f, -15.5f));
}
{
Shape shapeplatformleft = new BoxShape(15.5f, 0.5f);
Body platformleft = new StaticBody(this, shapeplatformleft);
platformleft.setPosition(new Vec2(-19.5f, 0.5f));
platformleft.setAngleDegrees(90);
}
{
Shape shapeplatformright = new BoxShape(15.5f, 0.5f);
Body platformright = new StaticBody(this, shapeplatformright);
platformright.setPosition(new Vec2(19.5f, 0.5f));
platformright.setAngleDegrees(90);
}
{
for (int i = 0; i < NUM_ANTS; i++) {
Body ant = new Ant(this);
ant.setPosition(new Vec2(i * 4 - 8, -14));
ant.addCollisionListener(new Collect(getCharacter()));
//chef = new Chef(this);
//chef.setPosition(new Vec2(-16f, -13f));
}
for (int j = 0; j < NUM_ANTSTWO; j++) {
Body anttwo = new Ant(this);
anttwo.setPosition(new Vec2(j * 4 - -6, -14));
anttwo.addCollisionListener(new Collect(getCharacter()));
}
{
soupbowlone = new SoupBowlOne(this);
soupbowlone.setPosition(new Vec2(0f, -11.5f));
soupbowlone.addCollisionListener(new SoupBowlLost (getCharacter()));
}
{
Animation t = new Animation();
}
}
}
public Vec2 startPosition() {
return new Vec2(-15, -13);
}
#Override
public Vec2 doorPosition() {
return new Vec2(16f, -13.5f);
}
#Override
public boolean isCompleted() {
return getCharacter().getCount() == NUM_ANTS + NUM_ANTSTWO;
}
}
how do I incorporate this animation class into my level one? as in make the rectangle do its animation across the screen in level 1? as you can see I have tried making the simple constructor "Animation t= new Animation" but it has not worked.i am a complete noob and I do apologise.
this class contains the JFrame information:
package NinjaChefGame;
import javax.swing.JFrame;
import city.cs.engine.*;
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JLabel;
public class Demo {
private UserView view;
private DemoWorld demoworld;
private GameHub world;
private int level;
private Controller controller;
private Demo demo;
public Demo() {
level = 1;
world = new DemoWorld();
world.populate(this);
Character chef = world.getCharacter();
final JFrame frame = new JFrame("Chefninjagame");
view = new UserView (world,800,640);
frame.add(view);
UserView wideView = new UserView(world, 500, 100);
wideView.setZoom(4);
frame.add(wideView, BorderLayout.SOUTH);
CollectedLabel scoreLabel = new CollectedLabel(chef);
frame.add(scoreLabel, BorderLayout.NORTH);
chef.addChangeListener(scoreLabel);
JFrame window = new JFrame("Menu");
Container buttons = new ControlPanel();
window.add(buttons, BorderLayout.WEST);
JLabel versionLabel = new JLabel();
versionLabel.setText("Version 4.0");
window.add(versionLabel, BorderLayout.SOUTH);
window.pack();
window.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.add(view);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
// JFrame debugView = new DebugViewer(world, 500, 500);
frame.addKeyListener(new Controller(world.getCharacter()));
controller = new Controller(world.getCharacter());
frame.addKeyListener(controller);
world.start();
}
public Character getCharacter() {
return world.getCharacter();
}
public boolean isCurrentLevelCompleted() {
return world.isCompleted();
}
public void goNextLevel() {
if (level==1){
world.setPaused(true);
world = new DemoWorldLevelTwo();
world.populate(this);
controller.setBody(world.getCharacter());
view.setWorld(world);
world.start();
level=2;
}
else if(level==2){
world.setPaused(true);
world = new DemoWorldLevelThree();
world.populate(this);
controller.setBody(world.getCharacter());
view.setWorld(world);
world.start();
}
}
public static void main(String[] args) {
new Demo();
}
}
I have just written a program in Netbeans that moves/copies/deletes files, and I wanted to give it a "diagnostic mode" where information about selected files, folders, variables, etc is displayed in a Text Area. Now, I could set this to only be visible when the "diagnostic mode" toggle is selected, but I think it would look awesome if the text area started behind the program, and "slid" out from behind the JFrame when the button is toggled. Is there any way to do this?
Thanks!
-Sean
Here is some starter code for you. This will right-slide a panel
of just about any content type. Tweak as necessary. Add error
checking and exception handling.
Tester:
static public void main(final String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
final JPanel slider = new JPanel();
slider.setLayout(new FlowLayout());
slider.setBackground(Color.RED);
slider.add(new JButton("test"));
slider.add(new JButton("test"));
slider.add(new JTree());
slider.add(new JButton("test"));
slider.add(new JButton("test"));
final CpfJFrame42 cpfJFrame42 = new CpfJFrame42(slider, 250, 250);
cpfJFrame42.slide(CpfJFrame42.CLOSE);
cpfJFrame42.setSize(300, 300);
cpfJFrame42.setLocationRelativeTo(null);
cpfJFrame42.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
cpfJFrame42.setVisible(true);
}
});
}
Use GAP & MIN to adjust spacing from JFrame and closed size.
The impl is a little long...it uses a fixed slide speed but
that's one the tweaks you can make ( fixed FPS is better ).
package com.java42.example.code;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
public class CpfJFrame42 extends JFrame {
public static int GAP = 5;
public static int MIN = 1;
public static final int OPEN = 0x01;
public static final int CLOSE = 0x02;
private JDialog jWindow = null;
private final JPanel basePanel;
private final int w;
private final int h;
private final Object lock = new Object();
private final boolean useSlideButton = true;
private boolean isSlideInProgress = false;
private final JPanel glassPane;
{
glassPane = new JPanel();
glassPane.setOpaque(false);
glassPane.addMouseListener(new MouseAdapter() {
});
glassPane.addMouseMotionListener(new MouseMotionAdapter() {
});
glassPane.addKeyListener(new KeyAdapter() {
});
}
public CpfJFrame42(final Component component, final int w, final int h) {
this.w = w;
this.h = h;
component.setSize(w, h);
addComponentListener(new ComponentListener() {
#Override
public void componentShown(final ComponentEvent e) {
}
#Override
public void componentResized(final ComponentEvent e) {
locateSlider(jWindow);
}
#Override
public void componentMoved(final ComponentEvent e) {
locateSlider(jWindow);
}
#Override
public void componentHidden(final ComponentEvent e) {
}
});
jWindow = new JDialog(this) {
#Override
public void doLayout() {
if (isSlideInProgress) {
}
else {
super.doLayout();
}
}
};
jWindow.setModal(false);
jWindow.setUndecorated(true);
jWindow.setSize(component.getWidth(), component.getHeight());
jWindow.getContentPane().add(component);
locateSlider(jWindow);
jWindow.setVisible(true);
if (useSlideButton) {
basePanel = new JPanel();
basePanel.setLayout(new BorderLayout());
final JPanel statusPanel = new JPanel();
basePanel.add(statusPanel, BorderLayout.SOUTH);
statusPanel.add(new JButton("Open") {
private static final long serialVersionUID = 9204819004142223529L;
{
setMargin(new Insets(0, 0, 0, 0));
}
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slide(OPEN);
}
});
}
});
statusPanel.add(new JButton("Close") {
{
setMargin(new Insets(0, 0, 0, 0));
}
private static final long serialVersionUID = 9204819004142223529L;
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slide(CLOSE);
}
});
}
});
{
//final BufferedImage bufferedImage = ImageFactory.getInstance().createTestImage(200, false);
//final ImageIcon icon = new ImageIcon(bufferedImage);
//basePanel.add(new JButton(icon), BorderLayout.CENTER);
}
getContentPane().add(basePanel);
}
}
private void locateSlider(final JDialog jWindow) {
if (jWindow != null) {
final int x = getLocation().x + getWidth() + GAP;
final int y = getLocation().y + 10;
jWindow.setLocation(x, y);
}
}
private void enableUserInput() {
getGlassPane().setVisible(false);
}
private void disableUserInput() {
setGlassPane(glassPane);
}
public void slide(final int slideType) {
if (!isSlideInProgress) {
isSlideInProgress = true;
final Thread t0 = new Thread(new Runnable() {
#Override
public void run() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
disableUserInput();
slide(true, slideType);
enableUserInput();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
isSlideInProgress = false;
}
});
t0.setDaemon(true);
t0.start();
}
else {
Toolkit.getDefaultToolkit().beep();
}
}
private void slide(final boolean useLoop, final int slideType) {
synchronized (lock) {
for (int x = 0; x < w; x += 25) {
if (slideType == OPEN) {
jWindow.setSize(x, h);
}
else {
jWindow.setSize(getWidth() - x, h);
}
jWindow.repaint();
try {
Thread.sleep(42);
} catch (final Exception e) {
e.printStackTrace();
}
}
if (slideType == OPEN) {
jWindow.setSize(w, h);
}
else {
jWindow.setSize(MIN, h);
}
jWindow.repaint();
}
}
}
So I have to move my (multiple) images across a GUI, but for whatever reason my paint method is only being called twice, even though my x variable and my timer, which I am using to try and move the image, are incrementing correctly. Any help would be appriciated! Thanks
import javax.swing.*;
import java.awt.*;
import java.lang.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
public class Races extends JFrame
{
public int threadCount = 5;
public int x = 0;
public ImageIcon picture = new ImageIcon("races.jpeg");
public int height = picture.getIconHeight();
public int width = picture.getIconHeight();
public Races(int _threadCount)
{
threadCount = _threadCount;
int counter = 0;
while(counter<threadCount)
{
(new Thread(new RacesInner(threadCount))).start();
counter++;
}
initialize();
}
public static void main(String[] args)
{
if(args.length == 0)
{
JFrame f = new Races(5);
}
else
{
JFrame f = new Races(Integer.parseInt(args[0]));
}
}
public void initialize()
{
this.setVisible(true);
this.setTitle("Off to the Races - By ");
RacesInner inner = new RacesInner(threadCount);
this.add(inner);
this.setSize((width*20),(height*3)*threadCount);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.repaint();
}
protected class RacesInner extends JPanel implements Runnable
{
public int j = (int)(Math.random() * 50) + 20;
public void timer()
{
Timer timer1 = new Timer(j, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
x += 2;
repaint();
}
});
timer1.start();
}
public void run()
{
timer();
}
#Override
public void paint(Graphics g)
{
super.paintComponent(g);
//drawing the correct amount of icons based on input(or lack of input, default 5)
//Get the current size of this component
Dimension d = this.getSize();
//draw in black
g.setColor(Color.BLACK);
//calculating where finish line should be and drawing the line
int finishLine;
finishLine = (width*20)-(width*2);
g.drawLine(finishLine,0,finishLine,2000);
for(int i =0; i<threadCount; i++)
{
picture.paintIcon(this,g,1+x,(50*i));
}
}
public RacesInner(int _threadCount)
{
threadCount = _threadCount;
System.out.println(threadCount);
//JPanel
this.setVisible(true);
this.setLayout(new GridLayout(threadCount,1));
}
}//closes RacesInner class
}//closes races class
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