I'm developing an memory card game in java. I need a delay after SelectedTile.hideFace();
Control.java
package control;
public class Control extends JFrame {
private static final long serialVersionUID = 1L;
public static Control CurrentWindow = null;
private ImageIcon background1,background2,background3,background4,background5,background6,background7,background8;
private final String title ="Remembory";
private Tile SelectedTile = null;
private int points = 0;
private int fails = 0;
private int failsleft = 5;
private JLabel score = new JLabel("Score:0");
private JLabel pogingen = new JLabel("Pogingen:5");
public Control() {
setSize(334,464);
setTitle(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.BLACK);
setUpGame();
add(score,BorderLayout.SOUTH);
score.setForeground(new Color(1,21,118));
score.setFont(score.getFont().deriveFont(18.0f));
add(pogingen,BorderLayout.SOUTH);
pogingen.setForeground(new Color(1,21,118));
pogingen.setFont(pogingen.getFont().deriveFont(18.0f));
setVisible(true);
}
public void setUpGame()
{
background1 = new ImageIcon("src//card.png");
background2 = new ImageIcon("src//card1.png");
background3 = new ImageIcon("src//card2.png");
background4 = new ImageIcon("src//card3.png");
background5 = new ImageIcon("src//card4.png");
background6 = new ImageIcon("src//card5.png");
background7 = new ImageIcon("src//card6.png");
background8 = new ImageIcon("src//card7.png");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(new Tile(background1));
getContentPane().add(new Tile(background1));
getContentPane().add(new Tile(background2));
getContentPane().add(new Tile(background2));
getContentPane().add(new Tile(background3));
getContentPane().add(new Tile(background3));
getContentPane().add(new Tile(background4));
getContentPane().add(new Tile(background4));
getContentPane().add(new Tile(background5));
getContentPane().add(new Tile(background5));
getContentPane().add(new Tile(background6));
getContentPane().add(new Tile(background6));
getContentPane().add(new Tile(background7));
getContentPane().add(new Tile(background7));
getContentPane().add(new Tile(background8));
getContentPane().add(new Tile(background8));
}
private void Addfails() {
fails++;
failsleft--;
pogingen.setText("Pogingen:" + failsleft);
repaint();
System.out.println( "Poging " + fails + " u heeft nog " + failsleft + " poging over" );
}
private void AddPoint() {
points++;
score.setText("Score:" + points);
repaint();
System.out.println(" + " + points + "Punten");
}
public void TileClicked (Tile tile){
if (SelectedTile == null) {
tile.showFace();
SelectedTile = tile;
return;
}
if (SelectedTile == tile) {
tile.hideFace();
SelectedTile = null;
return;
}
if (points < 8){
tile.showFace();
}
if (fails > 3){
JOptionPane.showMessageDialog(null, "Helaas u hebt geen pogingen meer");
System.exit(0);
}
if (points == 7){
JOptionPane.showMessageDialog(null, "Gefeliciteerd! Jou score is : " + points);
System.exit(0);
}
if (SelectedTile.getFaceColor().equals(tile.getFaceColor())) {
AddPoint();
SelectedTile = null;
return;
}
SelectedTile.hideFace();
//delay here
tile.hideFace();
Addfails();
System.out.println("Probeer het nogmaals");
SelectedTile = null;
}
public static void main(String[] args){
CurrentWindow = new Control();
}
}
Tile.java
package Tiles;
public class Tile extends JLabel implements MouseListener{
private static final long serialVersionUID = 1L;
private ImageIcon faceColor = new ImageIcon("src//background.png"); // standaard image (back)
private final static Dimension size = new Dimension(71,96);
public Tile(ImageIcon kleur)
{
setFaceColor(kleur);
setMinimumSize(size);
setMaximumSize(size);
setPreferredSize(size);
setOpaque(true);
setIcon(new ImageIcon("src//background.png"));
addMouseListener(this);
}
public void showFace()
{
//setBackground(faceColor);
setIcon(faceColor);
}
public void hideFace()
{
setIcon(new ImageIcon("src//background.png"));
//setBackground(new Color(213,86,31));
}
protected void setFaceColor(ImageIcon c)
{
this.faceColor = c;
}
public ImageIcon getFaceColor()
{
return this.faceColor;
}
public void mouseClicked(MouseEvent arg0) {
control.Control.CurrentWindow.TileClicked(this);
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
}
What do mean with "delay"? Normally, a Thread.sleep(milliseconds) would do the job, but the program will completely stop at this moment!
If you want to have an action with a delay (like hiding your cards after 500 milliseconds) you can schedule it like this:
import java.util.Timer;
import java.util.TimerTask;
// ...
SelectedTile.hideFace();
new Timer().schedule(new TimerTask() {
public void run() {
tile.hideFace();
}
}, 500); // hide face after 500 ms
// ...
Related
I have two Pane classes with respective JFrames. I also have another JFrame that acts as a level menu and when I open one of the JFrame both timers start I'm sure I'm missing something simple, but could someone please help me.
First level
Pane class
private static final long serialVersionUID = 1L;
private int x=0;
private int h=getHeight();
private int x1=20;
private int y1=100;
private int w;
private Timer timer;
private Timer timer2;
private Timer timer3;
private int t=60;
private String ti=Integer.toString(t);
private int ccounter=0;
private int angle=60;
private int time=1;
private int initialx=5;
private int initialy=1;
private double dx=Ballphysics.xveloctiy(angle, initialx);
private double dy=Ballphysics.yveloctiy(angle, initialy, time);
private int c1x=45;
private int c2x=60;
private int c3x=75;
private int gamex=-500;
private int points=0;
private Game_Model model;
private boolean a=false;
public Game_Pane(Game_Model model) {
this.setModel(model);
model.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
repaint();
}
});
setFocusable(true);
addKeyListener(this);
setBackground(Color.black);
timer= new Timer(50,new TimerCallback());
timer2=new Timer(5,new TimerCallback2());
timer3=new Timer(1000,new TimerCallback3());
timer.start();
timer2.start();
timer3.start();
}
public boolean isA() {
return a;
}
public void setA(boolean a) {
this.a = a;
}
public class TimerCallback implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
new Ballphysics();
if(x1 < 0 || x1 > w-10)
{
dx=-dx;
}
if (x1 < 0)
{
x1 = 0;
}
if (x1 > w-10)
{
x1 = w-10;
}
else
{
x1 = (int) (x1 + dx);
}
if (y1<50)
{
dy=-dy;
}
if (y1>h-50&&x1>=x&&x1<=x+150&&y1<h-40) {
dy=-dy;
points++;
}
if (y1<50) {
y1=50;
}
else
{
y1=(int)(y1+dy);
}
if (y1>1000) {
ccounter+=1;
y1=50;
x1=0;
if (ccounter==1) {
c3x=-500;
}
if (ccounter==2) {
c2x=-500;
}
if (ccounter==3) {
c1x=-500;
timer2.stop();
timer3.stop();
gamex=w/2-75;
timer.stop();
}
}
if (t==0) {
new Start_Menu(model).setC(true);
if (ccounter==0) {
points+=50;
}
else if (ccounter==1) {
points+=25;
}
else if (ccounter==2) {
points+=5;
}
points+=50;
}
repaint();
}}
public class TimerCallback2 implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}}
public class TimerCallback3 implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
t-=1;
time++;
ti=Integer.toString(t);
if (t==-1) {
timer.stop();
timer3.stop();
timer2.stop();
}
}
}
public void paintComponent(Graphics g) {
h=getHeight();
w=getWidth();
super.paintComponent(g);
g.setColor(Color.white);
g.drawString("Lives:", 10, 20);
g.drawString("Time Remaing:", w-140, 20);
g.drawString(ti, w-50, 20);
g.fillOval(c1x, 10, 10, 10);
g.fillOval(c2x, 10, 10, 10);
g.fillOval(c3x, 10, 10, 10);
g.drawLine(0,50,w,50);
g.drawLine(x, h-40, x+150, h-40);
g.setColor(Color.red);
g.fillOval(x1, y1, 10, 10);
g.setFont(new Font("Times New Roman",Font.BOLD,30));
g.drawString("Game Over", gamex, h/2);
String str=Integer.toString(points);
g.drawString(str, w/2-15, 30);
}
#Override
public void keyPressed(KeyEvent e) {
h=getHeight();
w=getWidth();
if (x>=0) {
if (e.getKeyCode()==37) {
x-=5;
}
else if (e.getKeyCode()==39) {
x+=5;
}}
if (x<0) {
x=0;
}
else if (x>w-150) {
x=w-150;}
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
public Game_Model getModel() {
return model;
}
public void setModel(Game_Model model) {
this.model = model;
}
Frame for the first Pane (level)
Frame for pane
private static final long serialVersionUID = 1L;
private Game_Model model= new Game_Model();
private Game_Pane p= new Game_Pane(model);
public Game_Frame() {
add(p);
setSize(600,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Level 1");
}
The pane for level 2 is identical and so is the frame as I haven't changed it to be unique yet so I won't add it too.
The level menu
private static final long serialVersionUID = 1L;
private JButton button= new JButton("1 player level 1");
private JButton button2= new JButton ("1 player level 2");
private JButton button3= new JButton ("2 player level 1");
private JButton button4= new JButton ("2 player level 2");
private Dimension d= new Dimension(300,50);
private Game_Frame Game_Frame= new Game_Frame();
private Game_Frame2 Frame2= new Game_Frame2();
public Level_Menu() {
setLayout (new GridBagLayout());
GridBagConstraints gbc= new GridBagConstraints();
gbc.gridwidth=GridBagConstraints.REMAINDER;
gbc.fill=GridBagConstraints.HORIZONTAL;
add(button,gbc);
add(button2,gbc);
add(button3,gbc);
add(button4,gbc);
button.setPreferredSize(d);
button2.setPreferredSize(d);
button3.setPreferredSize(d);
button4.setPreferredSize(d);
button.setBackground(Color.GREEN);
button2.setBackground(Color.green);
button3.setBackground(Color.GREEN);
button4.setBackground(Color.green);
setBackground(Color.BLACK);
button.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
button4.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
Object a=e.getSource();
if (a==button) {
Game_Frame.setVisible(true);
}
else if (a==button2) {
Frame2.setVisible(true);
}
else if (a==button3) {
}
else if (a==button4) {
}
}
Menu Frame
private static final long serialVersionUID = 1L;
private Level_Menu level= new Level_Menu();
public Level_Frame() {
add(level);
setSize(600,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Level Menu");}
I'm working on a vertical scrolling game, and I'm using a thread to generate new enemies every 2 seconds. Each enemy is an image in a JPanel. For some reason, The generated enemies are not showing up in the JFrame, but they are present. When the player collides with one of the enemies, all the enemies show up.
This is the main class:
package asteroidblaster;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.event.*;
import java.awt.*;
public class Main extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public Main() {
initUI();
}
private void initUI() {
add(new Board());
setResizable(false);
pack();
setTitle("Alien Blaster");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame ex = new Main();
ex.setVisible(true);
});
}
}
This is the main game logic:
package asteroidblaster;
import javax.swing.*;
import javax.swing.Timer;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public class Board extends JPanel {
private static final long serialVersionUID = 1L;
private final int B_WIDTH = 1500;
private final int B_HEIGHT = 700;
private final int REFRESH_TIME = 150;
private AlienShip alien;
private PlayerShip player;
private ArrayList<AlienShip> enemies = new ArrayList<AlienShip>();
private Timer alienScrollTimer, mainTimer;
public Board() {
initBoard();
}
private void initBoard() {
setBackground(Color.BLACK);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
setPlayer();
initAlienTimer();
gameLoop();
}
private void initAlienTimer() {
alienScrollTimer = new Timer(25, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for(AlienShip as : enemies) {
as.scrollShip();
}
repaint();
}
});
alienScrollTimer.start();
}
private void setPlayer() {
player = new PlayerShip();
add(player);
addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseMoved(MouseEvent e) {
player.followMouse(e.getX(), e.getY());
//checkCollision();
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
}
});
}
private void checkCollision() {
for(AlienShip as : enemies) {
if(player.getBounds().intersects(as.getBounds()))
player.setVisible(false);
}
}
private Thread alienGenerator() {
for(int i = 0; i < 3; i++) { //these two are being drawn
alien = new AlienShip();
add(alien);
enemies.add(alien);
}
return new Thread(new Runnable() {
#Override
public void run() {
int sleepTime = 2000;
while(true) {
try {
Thread.sleep(sleepTime);
} catch(InterruptedException e) {
System.out.println(e);
}
alien = new AlienShip();
add(alien);
enemies.add(alien);
System.out.println("Enemies: " + enemies.size());
}
}
});
}
private void gameLoop() {
alienGenerator().start();
mainTimer = new Timer(REFRESH_TIME, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
checkCollision();
repaint();
}
});
mainTimer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
This is the AlienShip class:
package asteroidblaster;
import java.util.Random;
import java.awt.*;
import javax.swing.*;
public class AlienShip extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private final String ALIEN_SHIP_FILE = "images/alienShip.jpg";
private final int PANEL_WIDTH = 224, PANEL_HEIGHT = 250;
private int panelX, panelY;
private Image alienShipImage;
public AlienShip() {
initAlienShip();
}
private void loadImage() {
alienShipImage = Toolkit.getDefaultToolkit().getImage(ALIEN_SHIP_FILE);
}
public int getX() {
return panelX;
}
public int getY() {
return panelY;
}
private void setY(int yCoord) {
panelY = yCoord;
}
private int setX() {
Random r = new Random();
int rand = r.nextInt(14) + 1;
return panelX = rand * 100;
}
private void initAlienShip() {
panelX = setX();
panelY = 0;
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setBackground(Color.BLUE);
loadImage();
}
#Override
public Rectangle getBounds() {
return new Rectangle(panelX, panelY, PANEL_WIDTH, PANEL_HEIGHT);
}
public void scrollShip() {
setY(getY() + 1);
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(alienShipImage, 0, 0, null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
I am writing a game for a snake in Java Swing using the MVC pattern.
The code of Controller and View are shown below. I am trying to implement a button that will help player choose a difficulty level.
The difficulty level is controlled by a timer in the Controller class. I am beginner in Java and help is appreciated.
Code of Controller class:
public class Controller implements KeyListener, ActionListener{
private Renderer renderer;
private Timer mainTimer;
private Snake snake;
public Controller() {
snake = new Snake();
renderer = new Renderer(this);
this.renderer.addKeyListener(this);
this.mainTimer = new Timer(150, this);
mainTimer.start();
}
public void stopGame(){
mainTimer.stop();
}
public void startGame(){
mainTimer.start();
}
public void keyPressed(KeyEvent e) {
snake.onMove(e.getKeyCode());
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void actionPerformed(ActionEvent arg0) {
renderer.moveForward();
}
public Snake getSnake(){
return snake;
}
View class:
class Renderer extends JFrame {
private final int WIDTH = 500;
private final int HEIGHT = 300;
private Snake snake;
public int LevelConst;
private Controller controller;
public JPanel pamel1, panel2;
public JButton[] ButtonBody = new JButton[200];
public JButton bonusfood;
public JTextArea textArea;
public Fruit fruit;
public int score;
public Random random = new Random();
public JMenuBar mybar;
public JMenu game, help, levels;
public void initializeValues() {
score = 0;
}
Renderer(Controller controller) {
super("Snake: Demo");
this.controller = controller;
snake = controller.getSnake();
fruit = new Fruit();
setBounds(200, 200, 506, 380);
creatbar();
initializeValues();
// GUI
pamel1 = new JPanel();
panel2 = new JPanel();
// Scoreboard
setResizable(false);
textArea = new JTextArea("Счет : " + score);
textArea.setEnabled(false);
textArea.setBounds(400, 400, 100, 100);
textArea.setBackground(Color.GRAY);
// Eating and growing up
bonusfood = new JButton();
bonusfood.setEnabled(false);
//
createFirstSnake();
pamel1.setLayout(null);
panel2.setLayout(new GridLayout(0, 1));
pamel1.setBounds(0, 0, WIDTH, HEIGHT);
pamel1.setBackground(Color.GRAY);
panel2.setBounds(0, HEIGHT, WIDTH, 30);
panel2.setBackground(Color.black);
panel2.add(textArea); // will contain score board
// end of UI design
getContentPane().setLayout(null);
getContentPane().add(pamel1);
getContentPane().add(panel2);
show();
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void createFirstSnake() {
for (int i = 0; i < 3; i++) {
ButtonBody[i] = new JButton(" " + i);
ButtonBody[i].setEnabled(false);
pamel1.add(ButtonBody[i]);
ButtonBody[i].setBounds(snake.x[i], snake.y[i], 10, 10);
snake.x[i + 1] = snake.x[i] - 10;
snake.y[i + 1] = snake.y[i];
}
}
// Creating of menu bar
public void creatbar() {
mybar = new JMenuBar();
game = new JMenu("Game");
JMenuItem newgame = new JMenuItem("New Game");
JMenuItem exit = new JMenuItem("Exit");
newgame.addActionListener(e -> reset());
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
game.add(newgame);
game.addSeparator();
game.add(exit);
mybar.add(game);
levels = new JMenu("Level");
JMenuItem easy = new JMenuItem("Easy");
easy.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
LevelConst = 0;
}
});
JMenuItem middle = new JMenuItem("Medium");
middle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
LevelConst = 1;
}
});
JMenuItem hard = new JMenuItem("Hard");
hard.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
LevelConst = 2;
}
});
levels.add(easy);
levels.addSeparator();
levels.add(middle);
levels.addSeparator();
levels.add(hard);
mybar.add(levels);
help = new JMenu("Help");
JMenuItem creator = new JMenuItem("There must be a button");
creator.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(pamel1, "Random text");
}
});
help.add(creator);
mybar.add(help);
setJMenuBar(mybar);
}
void reset() {
initializeValues();
pamel1.removeAll();
controller.stopGame();
createFirstSnake();
textArea.setText("Score: " + score);
controller.startGame();
}
void growup() {
ButtonBody[snake.getLength()] = new JButton(" " + snake.getLength());
ButtonBody[snake.getLength()].setEnabled(false);
pamel1.add(ButtonBody[snake.getLength()]);
ButtonBody[snake.getLength()].setBounds(snake.getPointBody()[snake.getLength() - 1].x, snake.getPointBody()[snake.getLength() - 1].y, 10, 10);
snake.setLength(snake.getLength() + 1);
}
void moveForward() {
for (int i = 0; i < snake.getLength(); i++) {
snake.getPointBody()[i] = ButtonBody[i].getLocation();
}
snake.x[0] += snake.getDirectionX();
snake.y[0] += snake.getDirectionY();
ButtonBody[0].setBounds(snake.x[0], snake.y[0], 10, 10);
for (int i = 1; i < snake.getLength(); i++) {
ButtonBody[i].setLocation(snake.getPointBody()[i - 1]);
}
if (snake.x[0] == WIDTH) {
controller.stopGame();
} else if (snake.x[0] == 0) {
controller.stopGame();
} else if (snake.y[0] == HEIGHT) {
controller.stopGame();
} else if (snake.y[0] == 0) {
controller.stopGame();
}
createFruit();
collisionFruit();
pamel1.repaint();
}
private void collisionFruit() {
if (fruit.isFood()) {
if (fruit.getPoint().x == snake.x[0] && fruit.getPoint().y == snake.y[0]) {
pamel1.remove(bonusfood);
score += 1;
growup();
textArea.setText("Score: " + score);
fruit.setFood(false);
}
}
}
private void createFruit() {
if (!fruit.isFood()) {
pamel1.add(bonusfood);
bonusfood.setBounds((10 * random.nextInt(50)), (10 * random.nextInt(25)), 10,
10);
fruit.setPoint(bonusfood.getLocation());
fruit.setFood(true);
}
}
Class Model: Fruit:
public class Fruit {
private Point point;
private boolean food;
public Fruit() {
point = new Point();
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public boolean isFood() {
return food;
}
public void setFood(boolean food) {
this.food = food;
}
Class Model: Snake:
public class Snake {
private Point[] pointBody = new Point[300];
private int length;
private boolean isLeft;
private boolean isRight;
private boolean isUp;
private boolean isDown;
private int directionX;
private int directionY;
public int[] x = new int[300];
public int[] y = new int[300];
public Snake() {
isLeft = false;
isRight = true;
isUp = true;
isDown = true;
setDirectionX(10);
setDirectionY(0);
length = 3;
y[0] = 100;
x[0] = 150;
}
public void onMove(int side) {
switch (side) {
case KeyEvent.VK_LEFT:
if (isLeft) {
setDirectionX(-10);
setDirectionY(0);
isRight = false;
isUp = true;
isDown = true;
}
break;
case KeyEvent.VK_UP:
if (isUp) {
setDirectionX(0);
setDirectionY(-10);
isDown = false;
isRight = true;
isLeft = true;
}
break;
case KeyEvent.VK_DOWN:
if (isDown) {
setDirectionX(0);
setDirectionY(+10);
isUp = false;
isRight = true;
isLeft = true;
}
break;
case KeyEvent.VK_RIGHT:
if (isRight) {
setDirectionX(+10);
setDirectionY(0);
isLeft = false;
isUp = true;
isDown = true;
}
break;
default:
break;
}
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public Point[] getPointBody() {
return pointBody;
}
public void setPointBody(Point[] pointBody) {
this.pointBody = pointBody;
}
public int getDirectionX() {
return directionX;
}
public void setDirectionX(int directionX) {
this.directionX = directionX;
}
public int getDirectionY() {
return directionY;
}
public void setDirectionY(int directionY) {
this.directionY = directionY;
}
Main:
public class Main {
public static void main(String[] args) {
new Controller();
}
}
Make a property change listener in Controller:
public PropertyChangeListener getViewListener() {
return new ViewListener();
}
private class ViewListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("Level is "+ evt.getNewValue());
//use level
}
}
Invoke createbar by: creatbar(controller.getViewListener());
And use listener :
public void creatbar(PropertyChangeListener listener) {
mybar = new JMenuBar();
mybar.addPropertyChangeListener(listener);//add listener to menu bar
game = new JMenu("Game");
JMenuItem newgame = new JMenuItem("New Game");
JMenuItem exit = new JMenuItem("Exit");
newgame.addActionListener(e -> reset());
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
game.add(newgame);
game.addSeparator();
game.add(exit);
mybar.add(game);
levels = new JMenu("Level");
JMenuItem easy = new JMenuItem("Easy");
easy.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mybar.firePropertyChange("Level", LevelConst, 0); //use listener
LevelConst = 0;
}
});
JMenuItem middle = new JMenuItem("Medium");
middle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mybar.firePropertyChange("Level", LevelConst, 1);
LevelConst = 1;
}
});
JMenuItem hard = new JMenuItem("Hard");
hard.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mybar.firePropertyChange("Level", LevelConst, 2);
LevelConst = 2;
}
});
levels.add(easy);
levels.addSeparator();
levels.add(middle);
levels.addSeparator();
levels.add(hard);
mybar.add(levels);
help = new JMenu("Help");
JMenuItem creator = new JMenuItem("There must be a button");
creator.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(pamel1, "Random text");
}
});
help.add(creator);
mybar.add(help);
setJMenuBar(mybar);
}
I have recently started Java and wondered if it was possible to make Animations whilst using GridBag Layout.
Are these possible and how? Any tutorials, help and such would be greatly appreciated :)
In order to perform any kind of animation of this nature, you're going to need some kind of proxy layout manager.
It needs to determine the current position of all the components, the position that the layout manager would like them to have and then move them into position.
The following example demonstrates the basic idea. The animation engine use is VERY basic and does not include features like slow-in and slow-out fundamentals, but uses a linear approach.
public class TestAnimatedLayout {
public static void main(String[] args) {
new TestAnimatedLayout();
}
public TestAnimatedLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestAnimatedLayoutPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestAnimatedLayoutPane extends JPanel {
public TestAnimatedLayoutPane() {
setLayout(new AnimatedLayout(new GridBagLayout()));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(new JLabel("Value:"), gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
add(new JComboBox(), gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridwidth = 2;
add(new JScrollPane(new JTextArea()), gbc);
gbc.gridwidth = 0;
gbc.gridy++;
gbc.gridx++;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.EAST;
add(new JButton("Click"), gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class AnimatedLayout implements LayoutManager2 {
private LayoutManager2 proxy;
private Map<Component, Rectangle> mapStart;
private Map<Component, Rectangle> mapTarget;
private Map<Container, Timer> mapTrips;
private Map<Container, Animator> mapAnimators;
public AnimatedLayout(LayoutManager2 proxy) {
this.proxy = proxy;
mapTrips = new WeakHashMap<>(5);
mapAnimators = new WeakHashMap<>(5);
}
#Override
public void addLayoutComponent(String name, Component comp) {
proxy.addLayoutComponent(name, comp);
}
#Override
public void removeLayoutComponent(Component comp) {
proxy.removeLayoutComponent(comp);
}
#Override
public Dimension preferredLayoutSize(Container parent) {
return proxy.preferredLayoutSize(parent);
}
#Override
public Dimension minimumLayoutSize(Container parent) {
return proxy.minimumLayoutSize(parent);
}
#Override
public void layoutContainer(Container parent) {
Timer timer = mapTrips.get(parent);
if (timer == null) {
System.out.println("...create new trip");
timer = new Timer(125, new TripAction(parent));
timer.setRepeats(false);
timer.setCoalesce(false);
mapTrips.put(parent, timer);
}
System.out.println("trip...");
timer.restart();
}
protected void doLayout(Container parent) {
System.out.println("doLayout...");
mapStart = new HashMap<>(parent.getComponentCount());
for (Component comp : parent.getComponents()) {
mapStart.put(comp, (Rectangle) comp.getBounds().clone());
}
proxy.layoutContainer(parent);
LayoutConstraints constraints = new LayoutConstraints();
for (Component comp : parent.getComponents()) {
Rectangle bounds = comp.getBounds();
Rectangle startBounds = mapStart.get(comp);
if (!mapStart.get(comp).equals(bounds)) {
comp.setBounds(startBounds);
constraints.add(comp, startBounds, bounds);
}
}
System.out.println("Items to layout " + constraints.size());
if (constraints.size() > 0) {
Animator animator = mapAnimators.get(parent);
if (animator == null) {
animator = new Animator(parent, constraints);
mapAnimators.put(parent, animator);
} else {
animator.setConstraints(constraints);
}
animator.restart();
} else {
if (mapAnimators.containsKey(parent)) {
Animator animator = mapAnimators.get(parent);
animator.stop();
mapAnimators.remove(parent);
}
}
}
#Override
public void addLayoutComponent(Component comp, Object constraints) {
proxy.addLayoutComponent(comp, constraints);
}
#Override
public Dimension maximumLayoutSize(Container target) {
return proxy.maximumLayoutSize(target);
}
#Override
public float getLayoutAlignmentX(Container target) {
return proxy.getLayoutAlignmentX(target);
}
#Override
public float getLayoutAlignmentY(Container target) {
return proxy.getLayoutAlignmentY(target);
}
#Override
public void invalidateLayout(Container target) {
proxy.invalidateLayout(target);
}
protected class TripAction implements ActionListener {
private Container container;
public TripAction(Container container) {
this.container = container;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("...trip");
mapTrips.remove(container);
doLayout(container);
}
}
}
public class LayoutConstraints {
private List<AnimationBounds> animationBounds;
public LayoutConstraints() {
animationBounds = new ArrayList<AnimationBounds>(25);
}
public void add(Component comp, Rectangle startBounds, Rectangle targetBounds) {
add(new AnimationBounds(comp, startBounds, targetBounds));
}
public void add(AnimationBounds bounds) {
animationBounds.add(bounds);
}
public int size() {
return animationBounds.size();
}
public AnimationBounds[] getAnimationBounds() {
return animationBounds.toArray(new AnimationBounds[animationBounds.size()]);
}
}
public class AnimationBounds {
private Component component;
private Rectangle startBounds;
private Rectangle targetBounds;
public AnimationBounds(Component component, Rectangle startBounds, Rectangle targetBounds) {
this.component = component;
this.startBounds = startBounds;
this.targetBounds = targetBounds;
}
public Rectangle getStartBounds() {
return startBounds;
}
public Rectangle getTargetBounds() {
return targetBounds;
}
public Component getComponent() {
return component;
}
public Rectangle getBounds(float progress) {
return calculateProgress(getStartBounds(), getTargetBounds(), progress);
}
}
public static Rectangle calculateProgress(Rectangle startBounds, Rectangle targetBounds, float progress) {
Rectangle bounds = new Rectangle();
if (startBounds != null && targetBounds != null) {
bounds.setLocation(calculateProgress(startBounds.getLocation(), targetBounds.getLocation(), progress));
bounds.setSize(calculateProgress(startBounds.getSize(), targetBounds.getSize(), progress));
}
return bounds;
}
public static Point calculateProgress(Point startPoint, Point targetPoint, float progress) {
Point point = new Point();
if (startPoint != null && targetPoint != null) {
point.x = calculateProgress(startPoint.x, targetPoint.x, progress);
point.y = calculateProgress(startPoint.y, targetPoint.y, progress);
}
return point;
}
public static Dimension calculateProgress(Dimension startSize, Dimension targetSize, float progress) {
Dimension size = new Dimension();
if (startSize != null && targetSize != null) {
size.width = calculateProgress(startSize.width, targetSize.width, progress);
size.height = calculateProgress(startSize.height, targetSize.height, progress);
}
return size;
}
public static int calculateProgress(int startValue, int endValue, float fraction) {
int value = 0;
int distance = endValue - startValue;
value = (int) ((float) distance * fraction);
value += startValue;
return value;
}
public class Animator implements ActionListener {
private Timer timer;
private LayoutConstraints constraints;
private int tick;
private Container parent;
public Animator(Container parent, LayoutConstraints constraints) {
setConstraints(constraints);
timer = new Timer(16, this);
timer.setRepeats(true);
timer.setCoalesce(true);
this.parent = parent;
}
private void setConstraints(LayoutConstraints constraints) {
this.constraints = constraints;
}
public void restart() {
tick = 0;
timer.restart();
}
protected void stop() {
timer.stop();
tick = 0;
}
#Override
public void actionPerformed(ActionEvent e) {
tick += 16;
float progress = (float)tick / (float)1000;
if (progress >= 1f) {
progress = 1f;
timer.stop();
}
for (AnimationBounds ab : constraints.getAnimationBounds()) {
Rectangle bounds = ab.getBounds(progress);
Component comp = ab.getComponent();
comp.setBounds(bounds);
comp.invalidate();
comp.repaint();
}
parent.repaint();
}
}
}
Update
You could also take a look at AurelianRibbon/Sliding-Layout
This is the program which i did long time back when i just started my Java classes.I did simple animations on different tabs on JTabbedPane (change the path of images/sound file as required),hope this helps:
UPDATE:
Sorry about not following concurrency in Swing.
Here is updated answer:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ClassTestHello extends JApplet {
private static JPanel j1;
private JLabel jl;
private JPanel j2;
private Timer timer;
private int i = 0;
private int[] a = new int[10];
#Override
public void init() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
start();
paint();
}
});
}
public void paint() {
jl = new JLabel("hiii");
j1.add(jl);
a[0] = 1000;
a[1] = 800;
a[2] = 900;
a[3] = 2000;
a[4] = 500;
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
if(i % 2 == 0)
jl.setText("hiii");
else
jl.setText("byee");
i++;
if(i > 4)
i=0;
timer.setDelay(a[i]);
}
};
timer = new Timer(a[i], actionListener);
timer.setInitialDelay(0);
timer.start();
}
#Override
public void start() {
j1 = new JPanel();
j2 = new JPanel();
JTabbedPane jt1 = new JTabbedPane();
ImageIcon ic = new ImageIcon("e:/guitar.gif");
JLabel jLabel3 = new JLabel(ic);
j2.add(jLabel3);
jt1.add("one", j1);
jt1.addTab("hii", j2);
getContentPane().add(jt1);
}
}
Before showing the GUI, if i have a code block like this:
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("GTK+".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {}
Here for example, i am using theme GTK+ in ubunut. Other options like Nimbus etc can be used. Now once i launch the app, it loads and show this theme. But is there anyway i can change the theme in real time. Because if i change it i have to close the GUI and load it again with new theme?
Is possible change Look and Feel on Runtime by invoke SwingUtilities#updateComponentTreeUI, for example
import java.awt.event.*;
import java.awt.Color;
import java.awt.AlphaComposite;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class ButtonTest {
private JFrame frame;
private JButton opaqueButton1;
private JButton opaqueButton2;
private SoftJButton softButton1;
private SoftJButton softButton2;
private Timer alphaChanger;
public void createAndShowGUI() {
opaqueButton1 = new JButton("Opaque Button");
opaqueButton2 = new JButton("Opaque Button");
softButton1 = new SoftJButton("Transparent Button");
softButton2 = new SoftJButton("Transparent Button");
opaqueButton1.setBackground(Color.GREEN);
softButton1.setBackground(Color.GREEN);
frame = new JFrame();
frame.getContentPane().setLayout(new java.awt.GridLayout(2, 2, 10, 10));
frame.add(opaqueButton1);
frame.add(softButton1);
frame.add(opaqueButton2);
frame.add(softButton2);
frame.setSize(700, 300);
frame.setLocation(150, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
alphaChanger = new Timer(30, new ActionListener() {
private float incrementer = -.03f;
#Override
public void actionPerformed(ActionEvent e) {
float newAlpha = softButton1.getAlpha() + incrementer;
if (newAlpha < 0) {
newAlpha = 0;
incrementer = -incrementer;
} else if (newAlpha > 1f) {
newAlpha = 1f;
incrementer = -incrementer;
}
softButton1.setAlpha(newAlpha);
softButton2.setAlpha(newAlpha);
}
});
alphaChanger.start();
Timer uiChanger = new Timer(3500, new ActionListener() {
private final LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
private int index = 1;
#Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(laf[index].getClassName());
SwingUtilities.updateComponentTreeUI(frame);
opaqueButton1.setText(laf[index].getClassName());
softButton1.setText(laf[index].getClassName());
} catch (Exception exc) {
exc.printStackTrace();
}
index = (index + 1) % laf.length;
}
});
uiChanger.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest().createAndShowGUI();
}
});
}
private static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
SoftJButton() {
this(null, null);
}
SoftJButton(String text) {
this(text, null);
}
SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}