How do I make a java action perform smoother? - java

I have created a simple program that fills a meter by how many times you press a button, eventually resulting into a "Mash the button to win" style game. I have it set up where every time the spacebar is pressed, the meter fills by 10/440, and if you reach the maximum, 440, you win. The issue I am having is how to make the increments added smoother, and less abrupt; as if you are pumping a bike tire up: continuous, less incrememntal.
Here is the problematic code:
import javax.swing.JOptionPane;
import javax.swing.*;
import java.util.*;
import static java.lang.System.*;
import static java.lang.Math.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*; //for files
public class MyClicker
{
public static void main(String args[])
{
new Clicker(); //Make a window
}
}
class Clicker extends Frame implements KeyListener, MouseListener
{
// global variables
private final static int SCHEIGHT=768,SCWIDTH=1024;
// direction constants
final static int N = 0,NE = 1,E = 2,SE = 3, S = 4, SW = 5, W = 6, NW =7,STILL = 8;
// movement change constants
final int X = 0,Y = 1,Z = 2;
final int TITLE = 30, STATUS = 40;
final static int size = 2;
Image myPic;
private boolean gameNotOver = true;
private boolean keyPressed = false;
private Image myScreen;
private int whichScreen;
private int timePassed;
private int numScreen;
private int maxAmt=450;
private int timer;
private int amt;
public Clicker()
{
setSize(SCWIDTH,SCHEIGHT);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
timer = -1;
this.setVisible(true);
out.println(amt);
this.addKeyListener(this);
gameLoop();
}
public void gameLoop()
{
do
{
if (keyPressed)
{
amt = amt + 50;
out.println(keyPressed + " " +gameNotOver+" "+ "Time "+timer);
this.repaint();
keyPressed = false;
}
if(amt >= 400)
gameNotOver = false;
pause(1000);
timer++;
this.setVisible(true);
//this.repaint();
pause(0);
if(amt > maxAmt - 10)
amt = maxAmt - 10;
}
while (gameNotOver);
if(!gameNotOver)
{
pause(5000);
System.exit(0);
}
}
public int getAmt()
{
return amt;
}
public void paint(Graphics pen)
{
if(whichScreen==0)
{
pen.drawImage(myPic,100,200,506,279,this); //Draws the image
pen.setFont(new Font("Timesroman", Font.ITALIC, 50));
pen.drawString("Welcome to the Clicker Test", 200, 75);
pen.setFont(new Font("Timesroman", Font.ITALIC, 40));
pen.drawString("Created by Cody Coulter",150,150);
pen.setFont(new Font("Timesroman", Font.ITALIC, 25));
pause(200); // 2000 final
whichScreen++;
doubleBuffer(pen);
}
else
{
myScreen =createImage(getSize().width,getSize().height);
Graphics o = myScreen.getGraphics();
doubleBuffer(o);
pen.drawImage(myScreen,0,0,this);
}
}
public void doubleBuffer(Graphics pen) // Draws the window
{
pause (500);
numScreen++;
if (numScreen > 0)
{
setBounds(0,0,SCWIDTH,SCHEIGHT);
Color HPRed = new Color(213, 0, 0);
pen.setColor(Color.BLACK);
setTitle("Clicker Test -- Cody Coulter."+
"To click, press the space bar");
pen.setFont(new Font("Timesroman",Font.PLAIN,48));
pen.drawString("Clicker Test ",350,75);
pen.setFont(new Font("TimesRoman",Font.BOLD,33));
pen.fillRect((SCWIDTH/4), (SCHEIGHT/3), 50, maxAmt);
pen.drawString(""+timer, 350, 150);
pen.setColor(HPRed);
pen.fillRect((SCWIDTH/4)+5, (SCHEIGHT/3)+5, 40, amt);
if(!gameNotOver)
{
if(amt >= maxAmt-10)
{
pen.setColor(HPRed);
pen.fillRect(SCWIDTH/4-75, SCHEIGHT/3, SCWIDTH/2+150, SCHEIGHT/3-60);
pen.setColor(Color.GRAY);
pen.fillRect(SCWIDTH/4-65, SCHEIGHT/3+10, SCWIDTH/2+130, SCHEIGHT/3-80);
pen.setColor(Color.YELLOW);
pen.setFont(new Font("Verdana", Font.BOLD, 40));
pen.drawString("You got it!", SCWIDTH/2-290, SCHEIGHT/2-20);
}
}
this.repaint();
}
}
public void keyPressed(KeyEvent e)
{
keyPressed = true;
setTitle(""+ KeyEvent.getKeyText(e.getKeyCode()));
System.out.println("hit + "+ KeyEvent.getKeyText(e.getKeyCode())+ " " + keyPressed);
switch(e.getKeyCode())
{
case KeyEvent.VK_SPACE: if(amt < maxAmt - 10)
amt= amt + 10;
break;
case KeyEvent.VK_A: if(amt < maxAmt - 10)
amt = amt + 10;
break;
}
}
public void mouseClicked(MouseEvent m)
{
}
public void mouseEntered(MouseEvent m)
{
}
public void mouseExited(MouseEvent m)
{
}
public void mousePressed(MouseEvent m)
{
}
public void mouseReleased(MouseEvent m)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
public void update(Graphics G)
{
paint(G);
}
public static void pause (long r)
{
try
{
Thread.sleep(r);
}
catch (Exception e)
{
out.println(" sleep error " + e);
}
}
} //end class
And here is the entirely up to date code:
import javax.swing.JOptionPane;
import javax.swing.*;
import java.util.*;
import static java.lang.System.*;
import static java.lang.Math.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*; //for files
public class MyClicker
{
public static void main(String args[])
{
new Clicker(); //Make a window
}
}
class Clicker extends Frame implements KeyListener, MouseListener
{
// global variables
private final static int SCHEIGHT=768,SCWIDTH=1024;
// direction constants
final static int N = 0,NE = 1,E = 2,SE = 3, S = 4, SW = 5, W = 6, NW =7,STILL = 8;
// movement change constants
final int X = 0,Y = 1,Z = 2;
final int TITLE = 30, STATUS = 40;
final static int size = 2;
Image myPic;
private boolean gameNotOver = true;
private boolean keyPressed = false;
private Image myScreen;
private int whichScreen;
private int timePassed;
private int numScreen;
private int maxAmt=450;
private int dispAmt;
private int actAmt;
private double timer;
public Clicker()
{
setSize(SCWIDTH,SCHEIGHT);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
timer = -1;
this.setVisible(true);
this.addKeyListener(this);
gameLoop();
}
public void gameLoop()
{
do
{
if (keyPressed)
{
out.println(keyPressed + " " +gameNotOver+" "+ "Time "+timer);
keyPressed = false;
}
if(dispAmt > maxAmt-10)
dispAmt = maxAmt;
if(actAmt >= maxAmt-10 || dispAmt >= maxAmt-10)
gameNotOver = false;
if(dispAmt < actAmt)
dispAmt++;
timer++;
this.setVisible(true);
// this.repaint();
// pause(0);
// if(actAmt > maxAmt - 10 || dispAmt > maxAmt - 10)
// actAmt = maxAmt - 10;
this.repaint();
}
while (gameNotOver);
if(!gameNotOver)
{
pause(5000);
System.exit(0);
}
}
public int getAmt()
{
return actAmt;
}
public void paint(Graphics pen)
{
if(whichScreen==0)
{
pen.drawImage(myPic,100,200,506,279,this); //Draws the image
pen.setFont(new Font("Timesroman", Font.ITALIC, 50));
pen.drawString("Welcome to the Clicker Test", 200, 75);
pen.setFont(new Font("Timesroman", Font.ITALIC, 40));
pen.drawString("Created by Cody Coulter",150,150);
pen.setFont(new Font("Timesroman", Font.ITALIC, 25));
pause(200); // 2000 final
whichScreen++;
doubleBuffer(pen);
}
else
{
myScreen =createImage(getSize().width,getSize().height);
Graphics o = myScreen.getGraphics();
doubleBuffer(o);
pen.drawImage(myScreen,0,0,this);
}
}
public void doubleBuffer(Graphics pen) // Draws the window
{
numScreen++;
if (numScreen > 0)
{
setBounds(0,0,SCWIDTH,SCHEIGHT);
Color HPRed = new Color(213, 0, 0);
pen.setColor(Color.BLACK);
setTitle("Clicker Test -- Cody Coulter."+
"To click, press the space bar");
pen.setFont(new Font("Timesroman",Font.PLAIN,48));
pen.drawString("Clicker Test ",350,75);
pen.setFont(new Font("TimesRoman",Font.BOLD,33));
pen.fillRect((SCWIDTH/4), (SCHEIGHT/3), 50, maxAmt);
pen.drawString(""+timer/1000, 350, 150);
pen.drawString(""+dispAmt+" / "+actAmt, 350, 200);
pen.setColor(HPRed);
pen.fillRect((SCWIDTH/4)+5, (SCHEIGHT/3)+5, 40, dispAmt);
if(!gameNotOver)
{
if(actAmt >= maxAmt-10)
{
pen.setColor(HPRed);
pen.fillRect(SCWIDTH/4-75, SCHEIGHT/3, SCWIDTH/2+150, SCHEIGHT/3-60);
pen.setColor(Color.GRAY);
pen.fillRect(SCWIDTH/4-65, SCHEIGHT/3+10, SCWIDTH/2+130, SCHEIGHT/3-80);
pen.setColor(Color.YELLOW);
pen.setFont(new Font("Verdana", Font.BOLD, 40));
pen.drawString("You got it!", SCWIDTH/2-290, SCHEIGHT/2-20);
}
}
this.repaint();
}
}
public void keyPressed(KeyEvent e)
{
keyPressed = true;
setTitle(""+ KeyEvent.getKeyText(e.getKeyCode()));
System.out.println("hit + "+ KeyEvent.getKeyText(e.getKeyCode())+ " " + keyPressed);
switch(e.getKeyCode())
{
case KeyEvent.VK_SPACE:actAmt = actAmt+10;
break;
case KeyEvent.VK_A: actAmt = actAmt+10;
break;
}
this.repaint();
}
public void mouseClicked(MouseEvent m)
{
}
public void mouseEntered(MouseEvent m)
{
}
public void mouseExited(MouseEvent m)
{
}
public void mousePressed(MouseEvent m)
{
}
public void mouseReleased(MouseEvent m)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
public void update(Graphics G)
{
paint(G);
}
public static void pause (long r)
{
try
{
Thread.sleep(r);
}
catch (Exception e)
{
out.println(" sleep error " + e);
}
}
} //end class

Get rid of pause(1000) you can maybe make it pause(10) or something around that.
Call this.repaint() every time in your loop (outside of the if statement).
Split amt into two variables: the actual amount, and the displayed amount. Only draw the displayed amount, and have key presses only increase the actual amount.
Each frame, if displayed amount is less than actual amount increase it by 1.
Updated...
Remove pause(500) from the double buffer routine, and pause(200) from paint. In general, don't pause unless you need to do "nothing". Games never do "nothing", they almost always have a core loop that's at least rendering.

Related

How can i make my player jump in a java game

Good Morning, I was building when i find the problem that I don't know how to make my Player jump.
There are my classes:
GamePanel
package src;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class GamePanel extends JPanel implements Runnable{
public static final int WIDTH=300, HEIGHT=300, MIN_X_COORD=0, MIN_Y_COORD=0, MAX_X_COORD=19, MAX_Y_COORD=19;
private Thread thread;
private boolean playing, key=false;
private Random r;
int xCoord = 0, yCoord = 16, size = 15;
char direction;
private Player p;
private Victory v;
private ArrayList<Ground> grounds;
private ArrayList<Grass> grasses;
private ArrayList<Sky> sky;
Action jump=new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
yCoord--;
yCoord--;
yCoord++;
yCoord++;
}
};
Action right=new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(xCoord!=MAX_X_COORD)xCoord++;
direction='l';
}
};
Action left=new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(xCoord!=MIN_X_COORD)xCoord--;
direction='r';
}
};
public GamePanel() {
this.getInputMap().put(KeyStroke.getKeyStroke('d'),"right");
this.getInputMap().put(KeyStroke.getKeyStroke('a'),"left");
this.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"up");
this.getActionMap().put("right", right);
this.getActionMap().put("left", left);
this.getActionMap().put("up", jump);
setFocusable(true);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
grounds = new ArrayList<Ground>();
grasses=new ArrayList<Grass>();
r=new Random();
v=new Victory(16,19, size);
p=new Player(xCoord, yCoord, size);
sky=new ArrayList<Sky>();
start();
}
public void start() {
playing=true;
thread=new Thread(this);
thread.start();
}
#Override
public void run() {
while (playing) {
tick();
repaint();
}
}
public void stop() {
playing = false;
// now we create the Game Over Screen
JFrame f=new JFrame("Game Over Screen");
JButton b=new JButton("Press this to play again!");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setPreferredSize(new Dimension(500,500));
JButton close = new JButton("Quit!");
b.setBounds(130,200,250, 40);
f.add(b);
f.add(close);
f.setLayout(new FlowLayout());
f.pack();
f.setVisible(true);
f.setLocationRelativeTo(null);
Main.returnFrame().dispatchEvent(new WindowEvent(Main.returnFrame(), WindowEvent.WINDOW_CLOSING));
Main.returnFrame().dispose();
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
Main.main(null);
}
});
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void tick() {
p=new Player(xCoord, yCoord, size);
if(grounds.size()==0) {
for(int y=MAX_Y_COORD;y>17;y--)
for(int x = 0;x<=MAX_X_COORD;x++)
grounds.add(new Ground(x,y,size));
}
if(grasses.size()==0)
for (int x=0;x<=MAX_X_COORD;x++)
grasses.add(new Grass(x, 17, size));
if (v.getxCoord()==p.getxCoord()&&v.getyCoord()==p.getyCoord()) {
win();
}
if (sky.size()==0)
for (int x=MIN_X_COORD;x<=MAX_X_COORD;x++)
for (int y=MIN_Y_COORD;y<17;y++)
sky.add(new Sky(x, y, size));
for(int i = 0;i< grounds.size();i++)
if(p.getxCoord() == grounds.get(i).getX_COORD() && p.getyCoord() ==grounds.get(i).getY_COORD())
back();
for(int i = 0;i< grasses.size();i++)
if(p.getxCoord() == grasses.get(i).getX_COORD() && p.getyCoord() ==grasses.get(i).getY_COORD())
back();
}
#Override
public void paint(Graphics g) {
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0;i<WIDTH/10;i++) { // draws lines
g.drawLine(i*10, 0, i*10, HEIGHT);
}
for(int i = 0;i<HEIGHT/10;i++) {
g.drawLine(0, i*10, HEIGHT, i*10);
}
for(int i = 0;i<grounds.size();i++) {
grounds.get(i).draw(g);
}
for (Grass grass : grasses) {
grass.draw(g);
}
for (Sky s:sky)
s.draw(g);
v.draw(g);
p.draw(g);
}
public void win() {
JOptionPane.showMessageDialog(null, "Hai Vinto");
stop();
}
public void die() {
JOptionPane.showMessageDialog(null, "Sei morto");
stop();
}
public void back() {
switch (direction) {
case 'l': xCoord++;break;
case 'r': xCoord--;break;
}
}
}
Player
import java.awt.Color;
import java.awt.Graphics;
public class Player {
int xCoord, yCoord, width, height;
public Player(int xCoord, int yCoord, int size) {
this.xCoord=xCoord;
this.yCoord=yCoord;
width=size;
height=size;
}
public void draw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(xCoord*width, yCoord*height, width, height);
}
public void setxCoord(int xCoord) {
this.xCoord = xCoord;
}
public int getxCoord() {
return xCoord;
}
public int getyCoord() {
return yCoord;
}
public void setyCoord(int yCoord) {
this.yCoord = yCoord;
}
}
I need that the action jump make the player character jump of two squares and return down.
I thought that i had to increase the yCoord and to repaint but it doesn't affect

Spritesheet Animation in JFrame

I am trying to get an animation using a spritesheet in JFrame. The problem is the once loaded, the image doesn't change. It only shows the first image.
I have searched a lot and tried almost all the advice but can't get it to work.
By the way, getSprite has a return type of Image.
When I do everything in JFrame, only one image is shown. When I do it in separate class extending JPanel, I get only a white Window.
Update 1: Thanks to andrew, got JFrame working. Fixed my old part too. Here's the working code at ideone
Update 2:
Here's my version with timer.
class TestSpriteSheet extends JFrame{
//same old variables
public TestSpriteSheet(){
//same old stuff goes here before this
add(new PanelSprite(this, ss));
this.setVisible(true);
}
}
class PanelSprite extends JPanel{
private long runningTime = 0;
private int fps = 3;
private boolean stop = false;
private SpriteSheetManager ss;
private TestSpriteSheet temp;
public PanelSprite(TestSpriteSheet test, SpriteSheetManager sm){
ss = sm;
temp = test;
setSize(180,180);
setLayout(new BorderLayout()); init();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000;
animate_with_gfx(g, time);
}
public void init(){
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
}
public void animate_with_gfx(Graphics g, long time){
if(runningTime <= time){
try {
System.out.println(runningTime); //Checking if this part works
int x = 0; int y = 0;
g.drawImage(ss.getSprite(x, y), 40, 40, null);
x++; y++; runningTime+=(1000/fps);
}catch (Exception ex) {
ex.printStackTrace();
}
}
else{
stop = true;
}
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000; int fps = 3;
boolean stop = false;
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
animate_with_gfx(g, time, fps, stop);
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
System.exit(0);
}
This part is entirely wrong, since the paintComponent() method is called whenever the JRE thinks the view needs repainting. So definitely remove the System.exit(0);!
Then the Timer needs a single instance, to be started once. That would best be done in the constructor or an init() type method.
It might look something like this:
private int fps = 3;
private boolean stop = false;
public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000;
animate_with_gfx(g, time, fps, stop);
}
/** Called from constructor.. */
public void init(){
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
}
Update
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
class SpriteSheetManager {
private BufferedImage spriteSheet;
int cols;
int rows;
public SpriteSheetManager() {
setSpriteSheet();
}
public void setSpriteSheet() {
try {
spriteSheet = ImageIO.read(
new URL("http://s8.postimg.org/vso6oed91/spritesheet.png"));
setColsAndRows(3, 3);
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage getSpriteSheet() {
return spriteSheet;
}
public void setColsAndRows(int cols, int rows) {
this.cols = cols;
this.rows = rows;
}
public Image getSprite(int x, int y) {
Image sprite = null;
try {
sprite = spriteSheet.getSubimage(
x * spriteSheet.getWidth() / cols,
y * spriteSheet.getHeight() / rows,
spriteSheet.getWidth() / cols,
spriteSheet.getHeight() / rows);
} catch (Exception e) {
e.printStackTrace();
}
return sprite;
}
}
class Ideone {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestSpriteSheet();
}
});
}
}
class TestSpriteSheet extends JFrame {
private static final long serialVersionUID = 1L;
private SpriteSheetManager ss;
public TestSpriteSheet() {
super("Testing SpriteSheets");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLayout(new BorderLayout());
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});
ss = new SpriteSheetManager();
add(new PanelSprite(this, ss));
pack();
setSize(200, 200);
this.setVisible(true);
}
}
class PanelSprite extends JPanel {
private long runningTime = 0;
private int fps = 10;
private boolean stop = false;
private SpriteSheetManager ss;
private TestSpriteSheet temp;
private Timer t;
int count = 0;
long time = 50000;
public PanelSprite(TestSpriteSheet test, SpriteSheetManager sm) {
ss = sm;
temp = test;
init();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
animate_with_gfx(g);
}
public void init() {
t = new Timer((int) (1000 / fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!stop) {
repaint();
} else {
((Timer) e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int) (1000 / fps));
t.start();
}
public void animate_with_gfx(Graphics g) {
if (runningTime <= time) {
Image img = ss.getSprite((count % 9) % 3, (count % 9) / 3);
g.drawImage(img, 40, 40, this);
count++;
runningTime += (1000 / fps);
} else {
stop = true;
}
}
}

Java Massive Multiple Frame Instances Issue

sigh OK guys... There is going to be a painstaking amount of code here, but i'm going to do it anyway.
So basically, I have a custom made (well it's actually just a HEAVILY customized version of a JFrame) and am having major issues.
I have a background. (Fair enough, that's fine) THEN I have a Terminal frame that pops up and spits stuff out. This Terminal frame is based off another class named CustomFrame. I also have ANOTHER class called Notification, which is ALSO a frame class like Terminal ALSO based off Custom Frame.
In the beginning, background loads fine. Terminal loads fine. Calls method to show Notification window. And thats where the problem rises. The notification window won't show.
I have tried frame.setVisible(); frame.setSize(); frame.setLocation(); I have tried, EVERYTHING.
And if I don't show Terminal at all, it seems to spit it's code onto Notification instead, almost like there can only be ONE instance of the CustomFrame open AT ALL TIMES.
I hope you understand my problems... So here is the code!
Game.java
public class Game implements KeyListener {
int BACK_WIDTH = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
int BACK_HEIGHT = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
JFrame back_frame = new JFrame();
JPanel window = new JPanel();
JLabel title = new JLabel(Variables.TITLE);
Terminal login = new Terminal();
public static void main(String[] args) {
new Game();
}
public Game() {
try {
back_frame.setSize(BACK_WIDTH, BACK_HEIGHT);
back_frame.setLocation(0, 0);
back_frame.getContentPane().setBackground(Color.BLACK);
back_frame.setUndecorated(true);
back_frame.setVisible(true);
back_frame.add(window);
window.setBackground(Color.BLACK);
window.setLayout(null);
window.add(title);
title.setBounds((BACK_WIDTH / 2) - (550 / 2), (BACK_HEIGHT / 2) - (50 / 2), 550, 50);
title.setForeground(Color.WHITE);
back_frame.addKeyListener(this);
login.addKeyListener(this);
login.setLocationRelativeTo(null);
login.setVariables(Types.LOGINTERMINAL);
waitForStart();
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
int index;
public void waitForStart() {
Timer timer = new Timer(2000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index < 1 && index >= 0) {
index++;
} else {
((Timer)e.getSource()).stop();
login.setVisible(true);
login.slowPrint("Please login to continue...\n"
+ "Type 'help' for more information.\n");
}
}
});
timer.start();
}
public void keyPressed(KeyEvent e) {
int i = e.getKeyCode();
if(i == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
CustomFrame.java
public class CustomFrame implements MouseListener {
static JFrame frame = new JFrame();
public static Paint window = new Paint();
public void addKeyListener(KeyListener listener) {
frame.addKeyListener(listener);
}
private Point initialClick;
private boolean inBounds = false;
public int getWidth() {
return frame.getWidth();
}
public int getHeight() {
return frame.getHeight();
}
public void add(JComponent component) {
window.add(component);
}
public void setLocation(int x, int y) {
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c) {
frame.setLocationRelativeTo(c);
}
private void setFrameType(Types type) {
switch(type) {
case TERMINAL:
frame.setSize(600, 400);
break;
case LOGINTERMINAL:
frame.setSize(600, 400);
break;
case NOTIFICATION:
frame.setSize(300, 150);
break;
default:
frame.setSize(600, 400);
break;
}
}
int index = 0;
public void slowPrint(final String text, final JTextArea field) {
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index < text.length() && index >= 0) {
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
} else {
field.append("\n");
index = 0;
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
public void slowPrintAndClear(final String text, final JTextArea field, final boolean andQuit) {
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (index < text.length() && index >= 0) {
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
} else {
field.append("\n");
if(andQuit == false) {
field.setText(null);
} else {
System.exit(0);
}
index = 0;
((Timer)e.getSource()).stop();
}
}
});
timer.start();
}
public CustomFrame(Types type) {
frame.setAlwaysOnTop(true);
frame.addMouseListener(this);
frame.setResizable(false);
frame.setUndecorated(true);
setFrameType(type);
frame.add(window);
window.setLayout(null);
frame.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
initialClick = e.getPoint();
frame.getComponentAt(initialClick);
}
});
frame.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if(e.getX() >= 0 && e.getX()<= frame.getWidth() &&
e.getY() >= 0 && e.getY() <= 20) {
inBounds = true;
}
if(inBounds == true) {
int thisX = frame.getLocation().x;
int thisY = frame.getLocation().y;
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
int x = thisX + xMoved;
int y = thisY + yMoved;
frame.setLocation(x, y);
}
}
});
}
public JFrame setVisible(boolean bool) {
frame.setVisible(bool);
return null;
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if(x >= CustomFrame.frame.getWidth() - 20 && x <= CustomFrame.frame.getWidth() - 6 &&
y >= 3 && y <= 14) {
frame.dispose();
}
}
public void mouseReleased(MouseEvent e) {
inBounds = false;
}
}
class Paint extends JPanel {
private static final long serialVersionUID = 1L;
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, CustomFrame.frame.getWidth(), CustomFrame.frame.getHeight());
Color LIGHT_BLUE = new Color(36, 171, 255);
//g2d.setColor(Color.BLUE);
GradientPaint topFill = new GradientPaint(0, 0, LIGHT_BLUE, CustomFrame.frame.getWidth(), 20, Color.BLUE);
g2d.setPaint(topFill);
g2d.fillRect(0, 0, CustomFrame.frame.getWidth(), 20);
g2d.setColor(Color.WHITE);
g2d.drawRect(0, 0, CustomFrame.frame.getWidth() - 1, CustomFrame.frame.getHeight() - 1);
g2d.drawLine(0, 20, CustomFrame.frame.getWidth(), 20);
g2d.fillRect(CustomFrame.frame.getWidth() - 20, 3, 14, 14);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
Terminal.java
public class Terminal implements KeyListener {
static CustomFrame frame = new CustomFrame(Types.TERMINAL);
JTextArea log = new JTextArea();
JTextField field = new JTextField();
public void setVisible(boolean bool) {
frame.setVisible(bool);
}
public void addKeyListener(KeyListener listener) {
frame.addKeyListener(listener);
}
public void setLogText(String str) {
log.setText(log.getText() + str + "\n");
}
public void setLocation(int x, int y) {
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c) {
frame.setLocationRelativeTo(c);
}
int index = 0;
public void slowPrint(final String text) {
frame.slowPrint(text, log);
}
public void slowPrintAndClear(final String text, boolean andQuit) {
frame.slowPrintAndClear(text, log, andQuit);
}
public Terminal() {
try {
JScrollPane pane = new JScrollPane();
JScrollBar scrollBar = pane.getVerticalScrollBar();
scrollBar.setUI(new ScrollBarUI());
pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
pane.setViewportView(log);
frame.add(field);
frame.add(pane);
log.setBackground(Color.BLACK);
log.setForeground(Color.WHITE);
log.setWrapStyleWord(true);
log.setLineWrap(true);
pane.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
pane.setBorder(null);
log.setEditable(false);
log.setCaretColor(Color.BLACK);
field.setBackground(Color.BLACK);
field.setForeground(Color.WHITE);
field.setBounds(2, frame.getHeight() - 23, frame.getWidth() - 5, 20);
field.setHighlighter(null);
field.setCaretColor(Color.BLACK);
field.addKeyListener(this);
field.setText(" > ");
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void dumpToLog() {
log.setText(log.getText() + field.getText() + "\n");
field.setText(" > ");
}
public void setVariables(Types type) {
switch(type) {
case TERMINAL:
this.type = Types.TERMINAL;
break;
case LOGINTERMINAL:
this.type = Types.LOGINTERMINAL;
break;
default:
this.type = Types.TERMINAL;
break;
}
}
Types type;
public void keyPressed(KeyEvent e) {
int i = e.getKeyCode();
String text1 = " > ";
String text2 = field.getText().replaceFirst(text1, "");
String text2_1 = text2.trim();
String text = text1 + text2_1;
if (type == Types.TERMINAL) {
} else if (type == Types.LOGINTERMINAL) {
if(i == KeyEvent.VK_ENTER && field.isFocusOwner()) {
if(text.startsWith(" > register") || text.startsWith(" > REGISTER")) {
if(!(text.length() == 13)) {
dumpToLog();
slowPrint("Registry not available at this current given time.\n");
//TODO: Create registry system.
new Notification("test");
} else {
dumpToLog();
slowPrint("\nInformation:\n"
+ "Registers a new account.\n\n"
+ "Usage:\n"
+ "register <username>\n");
}
} else {
System.out.println("start |" + text + "| end");
dumpToLog();
slowPrint("Unknown command.\n");
}
}
} else {
// SETUP CODE FOR NOTIFICATION ERROR AGAIN
}
if(field.isFocusOwner() && i == KeyEvent.VK_LEFT || i == KeyEvent.VK_RIGHT) {
e.consume();
}
if(!field.getText().startsWith(" > ")) {
field.setText(" > ");
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
Notification.java
public class Notification {
static CustomFrame frame = new CustomFrame(Types.NOTIFICATION);
JTextArea display = new JTextArea();
public Notification(String notification) {
try {
frame.setLocationRelativeTo(null);
frame.add(display);
display.setBackground(Color.BLACK);
display.setForeground(Color.WHITE);
display.setWrapStyleWord(true);
display.setLineWrap(true);
display.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
display.setBorder(null);
display.setEditable(false);
display.setCaretColor(Color.BLACK);
frame.slowPrint(notification, display);
frame.setVisible(true);
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Types.java
public enum Types {
TERMINAL, LOGINTERMINAL,
NOTIFICATION;
}
ScrollBarUI.java
public class ScrollBarUI extends MetalScrollBarUI {
private Image thumb, track;
private JButton blankButton() {
JButton b = new JButton();
b.setPreferredSize(new Dimension(0, 0));
b.setMaximumSize(new Dimension(0, 0));
b.setMinimumSize(new Dimension(0, 0));
return b;
}
public ScrollBarUI() {
thumb = FauxImage.create(32, 32, true);
track = FauxImage.create(32, 32, false);
}
protected void paintThumb(Graphics g, JComponent component, Rectangle rectangle) {
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.BLUE);
g2d.drawImage(thumb, rectangle.x, rectangle.y, rectangle.width, rectangle.height, null);
g2d.setPaint(Color.WHITE);
g2d.drawRect(rectangle.x, rectangle.y, rectangle.width - 1, rectangle.height-1);
}
protected void paintTrack(Graphics g, JComponent component, Rectangle rectangle) {
((Graphics2D) g).drawImage(track, rectangle.x, rectangle.y, rectangle.width, rectangle.height, null);
}
protected JButton createIncreaseButton(int orientation) {
return blankButton();
}
protected JButton createDecreaseButton(int orientation) {
return blankButton();
}
private static class FauxImage {
static public Image create(int width, int height, boolean thumb) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
if (thumb == true) {
Color LIGHT_BLUE = new Color(0, 140, 255);
//g2d.setPaint(Color.BLUE);
GradientPaint topFill = new GradientPaint(5, 25, Color.BLUE, 2, 2, LIGHT_BLUE);
g2d.setPaint(topFill);
g2d.fillRect(0, 0, width, height);
g2d.dispose();
} else {
g2d.setPaint(Color.BLACK);
g2d.fillRect(0, 0, width, height);
g2d.dispose();
}
return bi;
}
}
}
On a serious note though, if anyone is able to help me with such a sizeable post, I will SERIOUSLY be eternally grateful.
Cheers and thankyou... ALOT.
Edit:
Did have the time to fix up fonts. Extremely sorry, now it has been done.
Edit:
Here is where the Notification frame is called and doesn't end up showing:
if(!(text.length() == 13)) {
dumpToLog();
slowPrint("Registry not available at this current given time.\n");
//TODO: Create registry system.
new Notification("test");
}
As #Andrew Thompson, #trashgod pointed, it is a bad practice to use multiple frames.
If you still need to fix your problem, here goes:
The issue is with your static instance of the CustomFrame for your Game application and then modifying that frame instance using methods like setUndecorated(...).
In your Terminal class, you have
static CustomFrame frame = new CustomFrame(Types.TERMINAL);
and in your Notification class, you have
static CustomFrame frame = new CustomFrame(Types.NOTIFICATION);
but you are getting the same instance of the frame
static JFrame frame = new JFrame(); (in your CustomFrame class)
So what this means :
When the Game application loads, the Terminal is visible. And when you register a user, you are displying a Notification, with modified frame size and then by calling the setVisible() method of the CustomFrame.
Which is causing the issue. The setUndecorated() and setVisible() is invoked for the same static instance. YOU CANNOT MODIFY A FRAME WHICH IS VISIBLE. Meaning, YOU CAN ONLY MODIFY A FRAME BEFORE IT IS VISIBLE. Here your frame is already visible (for Terminal) and when displaying the Notification you are trying to change the size and display. WHICH IS WRONG.
As you said I want DIFFERENT JFrames, as in my code, I use Types.java as an enum to pick my different TYPES of frames. The frame is completely different each time due to the use of different components and sizing, to achieve this, you need multiple instances for each type of frame.
Changes/Fixes to your code :
Game1.java
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game1 implements KeyListener
{
int BACK_WIDTH = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
int BACK_HEIGHT = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
JFrame back_frame = new JFrame();
JPanel window = new JPanel();
JLabel title = new JLabel("Title");
Terminal1 login = new Terminal1();
public static void main(String[] args)
{
new Game1();
}
public Game1()
{
try
{
back_frame.setSize(BACK_WIDTH, BACK_HEIGHT);
back_frame.setLocation(0, 0);
back_frame.getContentPane().setBackground(Color.BLACK);
back_frame.setUndecorated(true);
back_frame.setVisible(true);
back_frame.add(window);
window.setBackground(Color.BLACK);
window.setLayout(null);
window.add(title);
title.setBounds((BACK_WIDTH / 2) - (550 / 2), (BACK_HEIGHT / 2) - (50 / 2), 550, 50);
title.setForeground(Color.WHITE);
back_frame.addKeyListener(this);
login.addKeyListener(this);
login.setLocationRelativeTo(null);
login.setVariables(Types.LOGINTERMINAL);
waitForStart();
}
catch (Exception e)
{
e.printStackTrace();
}
}
int index;
public void waitForStart()
{
Timer timer = new Timer(2000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (index < 1 && index >= 0)
{
index++;
}
else
{
((Timer) e.getSource()).stop();
login.setVisible(true);
login.slowPrint("Please login to continue...\n" + "Type 'help' for more information.\n");
}
}
});
timer.start();
}
public void keyPressed(KeyEvent e)
{
int i = e.getKeyCode();
if (i == KeyEvent.VK_ESCAPE)
{
System.exit(0);
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
CustomFrame1.java
import java.awt.Color;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Timer;
public class CustomFrame1 implements MouseListener
{
JFrame frame = new JFrame();
public static Paint window = null;
public void addKeyListener(KeyListener listener)
{
frame.addKeyListener(listener);
}
private Point initialClick;
private boolean inBounds = false;
public int getWidth()
{
return frame.getWidth();
}
public int getHeight()
{
return frame.getHeight();
}
public void add(JComponent component)
{
window.add(component);
}
public void setLocation(int x, int y)
{
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c)
{
frame.setLocationRelativeTo(c);
}
private void setFrameType(Types type)
{
switch (type)
{
case TERMINAL:
frame.setSize(600, 400);
break;
case LOGINTERMINAL:
frame.setSize(600, 400);
break;
case NOTIFICATION:
frame.setSize(300, 150);
break;
default:
frame.setSize(600, 400);
break;
}
}
int index = 0;
public void slowPrint(final String text, final JTextArea field)
{
Timer timer = new Timer(40, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (index < text.length() && index >= 0)
{
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
}
else
{
field.append("\n");
index = 0;
((Timer) e.getSource()).stop();
}
}
});
timer.start();
}
public void slowPrintAndClear(final String text, final JTextArea field, final boolean andQuit)
{
Timer timer = new Timer(40, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (index < text.length() && index >= 0)
{
String newChar = Character.toString(text.charAt(index));
field.append(newChar);
index++;
}
else
{
field.append("\n");
if (andQuit == false)
{
field.setText(null);
}
else
{
System.exit(0);
}
index = 0;
((Timer) e.getSource()).stop();
}
}
});
timer.start();
}
public CustomFrame1(Types type)
{
window = new Paint(frame);
frame.setAlwaysOnTop(true);
frame.addMouseListener(this);
frame.setResizable(false);
frame.setUndecorated(true);
setFrameType(type);
frame.add(window);
window.setLayout(null);
frame.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
initialClick = e.getPoint();
frame.getComponentAt(initialClick);
}
});
frame.addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
if (e.getX() >= 0 && e.getX() <= frame.getWidth() && e.getY() >= 0 && e.getY() <= 20)
{
inBounds = true;
}
if (inBounds == true)
{
int thisX = frame.getLocation().x;
int thisY = frame.getLocation().y;
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
int x = thisX + xMoved;
int y = thisY + yMoved;
frame.setLocation(x, y);
}
}
});
}
public void dispose()
{
frame.dispose();
}
public JFrame setVisible(boolean bool)
{
frame.setVisible(bool);
return null;
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
if (x >= frame.getWidth() - 20 && x <= frame.getWidth() - 6 && y >= 3 && y <= 14)
{
frame.dispose();
}
}
public void mouseReleased(MouseEvent e)
{
inBounds = false;
}
}
class Paint extends JPanel
{
private static final long serialVersionUID = 1L;
private JFrame frame;
public Paint(JFrame frame)
{
this.frame = frame;
}
private void doDrawing(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());
Color LIGHT_BLUE = new Color(36, 171, 255);
// g2d.setColor(Color.BLUE);
GradientPaint topFill = new GradientPaint(0, 0, LIGHT_BLUE, frame.getWidth(), 20, Color.BLUE);
g2d.setPaint(topFill);
g2d.fillRect(0, 0, frame.getWidth(), 20);
g2d.setColor(Color.WHITE);
g2d.drawRect(0, 0, frame.getWidth() - 1, frame.getHeight() - 1);
g2d.drawLine(0, 20, frame.getWidth(), 20);
g2d.fillRect(frame.getWidth() - 20, 3, 14, 14);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
doDrawing(g);
}
}
Terminal1.java
import java.awt.Color;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
public class Terminal1 implements KeyListener
{
static CustomFrame1 frame = new CustomFrame1(Types.TERMINAL);
JTextArea log = new JTextArea();
JTextField field = new JTextField();
public void setVisible(boolean bool)
{
frame.setVisible(bool);
}
public void addKeyListener(KeyListener listener)
{
frame.addKeyListener(listener);
}
public void setLogText(String str)
{
log.setText(log.getText() + str + "\n");
}
public void setLocation(int x, int y)
{
frame.setLocation(x, y);
}
public void setLocationRelativeTo(Component c)
{
frame.setLocationRelativeTo(c);
}
int index = 0;
public void slowPrint(final String text)
{
frame.slowPrint(text, log);
}
public void slowPrintAndClear(final String text, boolean andQuit)
{
frame.slowPrintAndClear(text, log, andQuit);
}
public Terminal1()
{
try
{
JScrollPane pane = new JScrollPane();
JScrollBar scrollBar = pane.getVerticalScrollBar();
scrollBar.setUI(new ScrollBarUI());
pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
pane.setViewportView(log);
frame.add(field);
frame.add(pane);
log.setBackground(Color.BLACK);
log.setForeground(Color.WHITE);
log.setWrapStyleWord(true);
log.setLineWrap(true);
pane.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
pane.setBorder(null);
log.setEditable(false);
log.setCaretColor(Color.BLACK);
field.setBackground(Color.BLACK);
field.setForeground(Color.WHITE);
field.setBounds(2, frame.getHeight() - 23, frame.getWidth() - 5, 20);
field.setHighlighter(null);
field.setCaretColor(Color.BLACK);
field.addKeyListener(this);
field.setText(" > ");
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void dumpToLog()
{
log.setText(log.getText() + field.getText() + "\n");
field.setText(" > ");
}
public void setVariables(Types type)
{
switch (type)
{
case TERMINAL:
this.type = Types.TERMINAL;
break;
case LOGINTERMINAL:
this.type = Types.LOGINTERMINAL;
break;
default:
this.type = Types.TERMINAL;
break;
}
}
Types type;
public void keyPressed(KeyEvent e)
{
int i = e.getKeyCode();
String text1 = " > ";
String text2 = field.getText().replaceFirst(text1, "");
String text2_1 = text2.trim();
String text = text1 + text2_1;
if (type == Types.TERMINAL)
{
}
else if (type == Types.LOGINTERMINAL)
{
if (i == KeyEvent.VK_ENTER && field.isFocusOwner())
{
if (text.startsWith(" > register") || text.startsWith(" > REGISTER"))
{
if (!(text.length() == 13))
{
dumpToLog();
slowPrint("Registry not available at this current given time.\n");
// TODO: Create registry system.
new Notification1("test");
}
else
{
dumpToLog();
slowPrint("\nInformation:\n" + "Registers a new account.\n\n" + "Usage:\n" + "register <username>\n");
}
}
else
{
System.out.println("start |" + text + "| end");
dumpToLog();
slowPrint("Unknown command.\n");
}
}
}
else
{
// SETUP CODE FOR NOTIFICATION ERROR AGAIN
}
if (field.isFocusOwner() && i == KeyEvent.VK_LEFT || i == KeyEvent.VK_RIGHT)
{
e.consume();
}
if (!field.getText().startsWith(" > "))
{
field.setText(" > ");
}
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
Notification1.java
import java.awt.Color;
import javax.swing.JTextArea;
public class Notification1
{
static CustomFrame1 frame = new CustomFrame1(Types.NOTIFICATION);
JTextArea display = new JTextArea();
public Notification1(String notification)
{
try
{
frame.setLocationRelativeTo(null);
frame.add(display);
display.setBackground(Color.BLACK);
display.setForeground(Color.WHITE);
display.setWrapStyleWord(true);
display.setLineWrap(true);
display.setBounds(4, 20 + 4, frame.getWidth() - 8, frame.getHeight() - 50);
display.setBorder(null);
display.setEditable(false);
display.setCaretColor(Color.BLACK);
frame.slowPrint(notification, display);
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Lag spike when moving player

The player is a panel, and it is getting removed, its position changed, and then re-added to another panel (which is what contains this method) which is drawn to the main frame. There are also a lot of other small panels containing a grass sprite being drawn to the primary panel as terrain tiles. I think the problem is that when I call revalidate(), it revalidates all those little panels as well. How can I solve this?
EDIT: I should mention that I am using RelativeLayout to position the players on the primary panel.
private class MainKeyAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent evt) {
// TODO add your handling code here:
if(AttentionedPlayer != null)
{
if (evt.getKeyCode() == KeyEvent.VK_UP) {
AttentionedPlayer.Ypos -= 16;
}
if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
AttentionedPlayer.Ypos += 16;
}
if (evt.getKeyCode() == KeyEvent.VK_LEFT) {
AttentionedPlayer.Xpos -= 16;
}
if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
AttentionedPlayer.Xpos += 16;
}
remove(AttentionedPlayer);
AttentionedPlayer.movePlayer();
System.out.println("!!!!"+AttentionedPlayer.constraints.toString());
add(AttentionedPlayer, AttentionedPlayer.constraints, AttentionedPlayer.Zpos);
AttentionedPlayer.revalidate();
}
}
}
AttentionedPlayer.movePlayer(); seems to be an intensive operation, and you execute it from within EDT (the GUI thread). Instead, execute it from within a new thread or a SwingWorker.
Read this answer to know more about SwingWorker.
#Eng.Fouad had a good point +1 to him, though I personally have never needed this for that exact reason, but your move method might be very cpu intensive.
Just to show an example (expanding from my comments) using your JPanel game logic, if implemented correctly there would be no need for revalidate() on player move (via setLocation(..)) which IMO is what also could cause a great amount of lag especially if there are many components. As you will see my GamePanel extends JPanel and uses Null/Absolute Layout (but for good reason in gaming we want more control over the Layout).
Also used KeyBindings to show you their useage.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class GameLogic {
public GameLogic() {
initComponents();
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Entity entity = new Entity("Player", 100, 100, 50, 50);//starting location 100,100 and width/height 50x50
GamePanel gp = new GamePanel(300, 300);
gp.addEntity(entity);
setGamePanelKeyBindings(gp, entity);
frame.add(gp);
frame.pack();
frame.setVisible(true);
}
private void setGamePanelKeyBindings(GamePanel gp, final Entity entity) {
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "D pressed");
gp.getActionMap().put("D pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.RIGHT);
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "A pressed");
gp.getActionMap().put("A pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.LEFT);
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "W pressed");
gp.getActionMap().put("W pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.UP);
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "S pressed");
gp.getActionMap().put("S pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.move(Entity.DOWN);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GameLogic();
}
});
}
}
class Entity extends JPanel {
private int width = 50, height = 50;
private int speed = 5;
public static final int UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4;
public Entity(String text, int x, int y, int width, int height) {
this.width = width;
this.height = height;
add(new JLabel(text));
setBorder(new LineBorder(Color.BLACK));
setBounds(x, y, width, height);
}
public void move(int direction) {
switch (direction) {
case UP:
setLocation(getX(), getY() - speed);
break;
case DOWN:
setLocation(getX(), getY() + speed);
break;
case LEFT:
setLocation(getX() - speed, getY());
break;
case RIGHT:
setLocation(getX() + speed, getY());
break;
}
}
#Override
public void setBounds(int x, int y, int w, int h) {
super.setBounds(x, y, width, height);
}
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.setColor(Color.CYAN);
grphcs.fillRect(0, 0, getWidth(), getHeight());
}
}
class GamePanel extends JPanel {
private int width, height;
GamePanel(int w, int h) {
setLayout(null);
width = w;
height = h;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
public void addEntity(Entity e) {
add(e);
}
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.setColor(Color.GREEN);
grphcs.fillRect(0, 0, getWidth(), getHeight());
}
}
Sorry I couldn't stop myself
if you are interested here is a bit of an advanced version with gameloop that can be paused, frame rate etc can be set, 2 keys (like W and D may be pressed simultaneously thus causing JPanel to move diagonally):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class GameLogic {
public GameLogic() {
initComponents();
}
final GamePanel gp = new GamePanel(500, 500);
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Entity entity = new Entity("Player", 100, 100, 100, 100);
gp.addEntity(entity);
setGamePanelKeyBindings(gp, entity);
frame.add(gp);
frame.pack();
frame.setVisible(true);
//start the game loop which will repaint the screen
runGameLoop();
}
//Starts a new thread and runs the game loop in it.
public void runGameLoop() {
Thread loop = new Thread(new Runnable() {
#Override
public void run() {
gp.running = true;
gp.gameLoop();
}
});
loop.start();
}
private void setGamePanelKeyBindings(GamePanel gp, final Entity entity) {
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("D"), "D pressed");
gp.getActionMap().put("D pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.RIGHT = true;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), "A pressed");
gp.getActionMap().put("A pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.LEFT = true;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("W"), "W pressed");
gp.getActionMap().put("W pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.UP = true;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "S pressed");
gp.getActionMap().put("S pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.DOWN = true;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released D"), "D released");
gp.getActionMap().put("D released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.RIGHT = false;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released A"), "A released");
gp.getActionMap().put("A released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.LEFT = false;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released W"), "W released");
gp.getActionMap().put("W released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.UP = false;
}
});
gp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released S"), "S released");
gp.getActionMap().put("S released", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent ae) {
entity.DOWN = false;
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GameLogic();
}
});
}
}
class Entity extends JPanel {
private int width = 50, height = 50;
private int speed = 5;
public boolean UP = false, DOWN = false, LEFT = false, RIGHT = false;
public Entity(String text, int x, int y, int width, int height) {
this.width = width;
this.height = height;
add(new JLabel(text));
setBorder(new LineBorder(Color.BLACK));
setBounds(x, y, width, height);
}
public void move() {
if (UP) {
setLocation(getX(), getY() - speed);
}
if (DOWN) {
setLocation(getX(), getY() + speed);
}
if (LEFT) {
setLocation(getX() - speed, getY());
}
if (RIGHT) {
setLocation(getX() + speed, getY());
}
}
#Override
public void setBounds(int x, int y, int w, int h) {
super.setBounds(x, y, width, height);
}
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.setColor(Color.CYAN);
grphcs.fillRect(0, 0, getWidth(), getHeight());
}
}
class GamePanel extends JPanel {
private int width, height;
private int frameCount = 0;
private int fps = 0;
public static boolean running = false, paused = false;
final ArrayList<Entity> entities = new ArrayList<>();
GamePanel(int w, int h) {
setLayout(null);
width = w;
height = h;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
public void addEntity(Entity e) {
add(e);
entities.add(e);
}
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.setColor(Color.GREEN);
grphcs.fillRect(0, 0, getWidth(), getHeight());
grphcs.setColor(Color.BLACK);
grphcs.drawString("FPS: " + fps, 5, 10);
frameCount++;
}
//Only run this in another Thread!
public void gameLoop() {
//This value would probably be stored elsewhere.
final double GAME_HERTZ = 30.0;
//Calculate how many ns each frame should take for our target game hertz.
final double TIME_BETWEEN_UPDATES = 1000000000 / GAME_HERTZ;
//At the very most we will update the game this many times before a new render.
//If you're worried about visual hitches more than perfect timing, set this to 1.
final int MAX_UPDATES_BEFORE_RENDER = 5;
//We will need the last update time.
double lastUpdateTime = System.nanoTime();
//Store the last time we rendered.
double lastRenderTime = System.nanoTime();
//If we are able to get as high as this FPS, don't render again.
final double TARGET_FPS = 60;
final double TARGET_TIME_BETWEEN_RENDERS = 1000000000 / TARGET_FPS;
//Simple way of finding FPS.
int lastSecondTime = (int) (lastUpdateTime / 1000000000);
while (running) {
double now = System.nanoTime();
int updateCount = 0;
if (!paused) {
//Do as many game updates as we need to, potentially playing catchup.
while (now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER) {
updateGame();
lastUpdateTime += TIME_BETWEEN_UPDATES;
updateCount++;
}
//If for some reason an update takes forever, we don't want to do an insane number of catchups.
//If you were doing some sort of game that needed to keep EXACT time, you would get rid of this.
if (now - lastUpdateTime > TIME_BETWEEN_UPDATES) {
lastUpdateTime = now - TIME_BETWEEN_UPDATES;
}
drawGame();
lastRenderTime = now;
//Update the frames we got.
int thisSecond = (int) (lastUpdateTime / 1000000000);
if (thisSecond > lastSecondTime) {
System.out.println("NEW SECOND " + thisSecond + " " + frameCount);
fps = frameCount;
frameCount = 0;
lastSecondTime = thisSecond;
}
//Yield until it has been at least the target time between renders. This saves the CPU from hogging.
while (now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES) {
//allow the threading system to play threads that are waiting to run.
Thread.yield();
//This stops the app from consuming all your CPU. It makes this slightly less accurate, but is worth it.
//You can remove this line and it will still work (better), your CPU just climbs on certain OSes.
//FYI on some OS's this can cause pretty bad stuttering. Scroll down and have a look at different peoples' solutions to this.
//On my OS it does not unpuase the game if i take this away
try {
Thread.sleep(1);
} catch (Exception e) {
}
now = System.nanoTime();
}
}
}
}
private void updateGame() {
for (Entity e : entities) {
e.move();
}
}
private void drawGame() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
repaint();
}
});
}
}

Layering multiple GlassPane's in a Root Container

Is it possible to add multiple GlassPanes for a single JFrame, or do I have to use the uncomfortable LayeredPane with the Opacity attribute.
I have attached some code that shows what I want to do (provided by #camickr).
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
public class MultiplayGlassPane {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame("frameTitle");
private JPanel fPanel = new JPanel();
private Random random = new Random();
private final static Border MESSAGE_BORDER = new EmptyBorder(10, 10, 10, 10);
private JLabel message = new JLabel();
private ArrayList<Star> stars = new ArrayList<Star>();
public MultiplayGlassPane() {
MyGlassPane glass = new MyGlassPane();
for (int i = 0; i < 35; i++) {
Star star = new Star(new Point(random.nextInt(580), random.nextInt(550)));
star.setColor(Color.orange);
star.setxIncr(-3 + random.nextInt(7));
star.setyIncr(-3 + random.nextInt(7));
glass.add(star);
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(glass, BorderLayout.CENTER);
frame.setLocation(20, 20);
frame.pack();
frame.setVisible(true);
DisabledGlassPane1 glassPane = new DisabledGlassPane1();
JRootPane rootPane = SwingUtilities.getRootPane(frame);
rootPane.setGlassPane(glassPane);
glassPane.activate("");
}
private class MyGlassPane extends JLabel {
private static final long serialVersionUID = 1L;
private ArrayList<Star> stars = new ArrayList<Star>();
private javax.swing.Timer timer = new javax.swing.Timer(20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Star star : stars) {
star.move();
}
repaint();
}
});
public void stopAnimation() {
if (timer.isRunning()) {
timer.stop();
}
}
public void startAnimation() {
if (!timer.isRunning()) {
timer.start();
}
}
#Override
public void addNotify() {
super.addNotify();
timer.start();
}
#Override
public void removeNotify() {
super.removeNotify();
timer.stop();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(new Dimension(620, 620));
}
public MyGlassPane() {
this.setPreferredSize(new Dimension(620, 620));
}
public void add(Star star) {
stars.add(star);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Star star : stars) {
g.setColor(star.getColor());
g.fillPolygon(star);
}
}
}
class DisabledGlassPane1 extends JComponent implements KeyListener {
private static final long serialVersionUID = 1L;
public DisabledGlassPane1() {
setOpaque(false);
Color base = UIManager.getColor("inactiveCaptionBorder");
Color background = new Color(base.getRed(), base.getGreen(), base.getBlue(), 128);
setBackground(background);
setLayout(new GridBagLayout());
add(message, new GridBagConstraints());
message.setOpaque(true);
message.setBorder(MESSAGE_BORDER);
addMouseListener(new MouseAdapter() {
});
addMouseMotionListener(new MouseMotionAdapter() {
});
addKeyListener(this);
setFocusTraversalKeysEnabled(false);
Random random = new Random();
for (int i = 0; i < 50; i++) {
Star star = new Star(new Point(random.nextInt(490), random.nextInt(490)));
star.setColor(Color.magenta);
star.setxIncr(-3 + random.nextInt(7));
star.setyIncr(-3 + random.nextInt(7));
add(star);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Star star : stars) {
g.setColor(star.getColor());
g.fillPolygon(star);
}
}
#Override
public void setBackground(Color background) {
super.setBackground(background);
Color messageBackground = new Color(background.getRGB());
message.setBackground(messageBackground);
}
public void keyPressed(KeyEvent e) {
e.consume();
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
e.consume();
}
public void activate(String text) {
if (text != null && text.length() > 0) {
message.setVisible(true);
message.setText(text);
message.setForeground(getForeground());
} else {
message.setVisible(false);
}
setVisible(true);
//setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
requestFocusInWindow();
}
public void deactivate() {
setCursor(null);
setVisible(false);
}
private javax.swing.Timer timer = new javax.swing.Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Star star : stars) {
star.move();
}
repaint();
}
});
public void stopAnimation() {
if (timer.isRunning()) {
timer.stop();
}
}
public void startAnimation() {
if (!timer.isRunning()) {
timer.start();
}
}
#Override
public void addNotify() {
super.addNotify();
timer.start();
}
#Override
public void removeNotify() {
super.removeNotify();
timer.stop();
}
public void add(Star star) {
stars.add(star);
}
}
private class Star extends Polygon {
private static final long serialVersionUID = 1L;
private Point location = null;
private Color color = Color.YELLOW;
private int xIncr, yIncr;
static final int WIDTH = 600, HEIGHT = 600;
Star(Point location) {
int x = location.x;
int y = location.y;
this.location = location;
this.addPoint(x, y + 8);
this.addPoint(x + 8, y + 8);
this.addPoint(x + 11, y);
this.addPoint(x + 14, y + 8);
this.addPoint(x + 22, y + 8);
this.addPoint(x + 17, y + 12);
this.addPoint(x + 21, y + 20);
this.addPoint(x + 11, y + 14);
this.addPoint(x + 3, y + 20);
this.addPoint(x + 6, y + 12);
}
public void setColor(Color color) {
this.color = color;
}
public void move() {
if (location.x < 0 || location.x > frame.getContentPane().getWidth() - 20) {
xIncr = -xIncr;
}
if (location.y < 0 || location.y > frame.getContentPane().getHeight() - 20) {
yIncr = -yIncr;
}
translate(xIncr, yIncr);
location.setLocation(location.x + xIncr, location.y + yIncr);
}
public void setxIncr(int xIncr) {
this.xIncr = xIncr;
}
public void setyIncr(int yIncr) {
this.yIncr = yIncr;
}
public Color getColor() {
return color;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MultiplayGlassPane Mpgp = new MultiplayGlassPane();
}
});
}
}
Look at http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html for an explanation on Root panes and what the Glass pane actually is.
The glass pane is just a convenient way to add a component which has the size of the Root Pane, and which blocks all input events. This allows you to catch any interaction with your components to create a "Please wait..." screen.
There is only a single glass pane per root container. You cannot layer glass panes.
You can replace the contents of the glass pane by something else if you want to layer something over the current glass pane. You can also set a JPanel as a glass pane, which allows you to layout multiple components in the glass pane.
Usually, you should only use the glass pane to block user input (and, if necessary, display some kind of "please wait" message). Can you provide a use case of why you want to put glass panes on top of one another?

Categories