How to make a shape move by pressing key once in Java? - java

I have a task in university to draw an ellipse and make it move step by step on the screen pressing the button only once. Here is my code:
public class Window extends JPanel {
private static Ellipse2D.Double Ellipse;
private JFrame frame;
public Window() {
super();
int width = 20;
int height = 30;
Ellipse = new Ellipse2D.Double(width, height, 100, 50);
}
public Dimension getPreferredSize()
{
return (new Dimension(frame.getWidth(), frame.getHeight()));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D brush = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g.clearRect(0, 0, width, height);
brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
brush.draw(Ellipse);
}
public class MoveCircle implements KeyListener, ActionListener {
#Override
public void keyPressed(KeyEvent e) {
System.out.println("Working on top!");
double newX = 0; double newY = 0;
if (e.getKeyCode() == Event.ENTER) {
for (int i = 0; i < 26; i ++)
{
System.out.println("Working on bottom!");
newX = Ellipse.x + 10;
Ellipse.x = newX;
newY = Ellipse.y + 10;
Ellipse.y = newY;
repaint();
}
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
private void createAndDisplayGUI(Window window)
{
frame = new JFrame();
Container container = frame.getContentPane();
container.add(window);
window.addKeyListener(new MoveCircle());
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
window.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Window window = new Window();
window.createAndDisplayGUI(window);
}
});
}
}
Although I call the function repaint() in cycle each time still the ellipse just moves radically from the original point to the point defined in the last iteration without drawing position of the ellipse in each iteration.
Is it possible to use a Swing Timer to make it repaint the ellipse in each iteration? I will be very glad to get help in this.

You have two problems: The first is that your loop is being run on the UI thread. The second is your misunderstanding in how repaint works. All repaint does is adds a request to the UI thread to do a repaining. It doesn't perform a repaint in and of itself. So if you are running operations on the UI thread, calling it multiple times will have no effect. As you suggested, you can fix this with a Swing Timer, as I've put together below
ActionListener al = new ActionListener() {
int iterations = 0;
public void actionPerformed(ActionEvent ae) {
if (iterations == 25) {
timer.stop();
}
interations++;
System.out.println("Working on bottom!");
newX = Ellipse.x + 10;
Ellipse.x = newX;
newY = Ellipse.y + 10;
Ellipse.y = newY;
repaint();
}
};
final timer = new javax.swing.Timer(delay, al);
timer.start();

Related

Repaint() not being called if i use ImageIO.read()

When i try to set value to BufferedImage called dinoImage in Dino.java in a constructor i just get a blank screen every time (second picture) because repaint() is not being called, but if i set it to null it is working just fine but without this image (first picture).
No exceptions, everything seems fine in this code, this problem appears when i try to set value to this field using static method getImage of Resource.java which uses this line of code ImageIO.read(new File(path)) and it causes that repaint() is not being called, i guess this line causes such weird behavior but i dont know how to solve it.
Main.java
public class Main {
public static void main(String[] args) {
GameWindow gameWindow = new GameWindow();
gameWindow.startGame();
}
}
GameWindow.java
public class GameWindow extends JFrame {
private GameScreen gameScreen;
public GameWindow() {
super("Runner");
setSize(1000, 500);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameScreen = new GameScreen();
add(gameScreen);
}
public void startGame() {
gameScreen.startThread();
}
}
GameScreen.java
public class GameScreen extends JPanel implements Runnable, KeyListener {
private Thread thread;
public static final double GRAVITY = 0.1;
public static final int GROUND_Y = 300;
private Dino dino;
public GameScreen() {
thread = new Thread(this);
dino = new Dino();
}
public void startThread() {
thread.start();
}
#Override
public void run() {
while(true) {
try {
Thread.sleep(20);
dino.updatePosition();
repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// g.clearRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
g.drawLine(0, GROUND_Y, getWidth(), GROUND_Y);
dino.draw(g);
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("Key Pressed");
dino.jump();
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("Key Released");
}
}
Dino.java
public class Dino {
private double x = 100;
private double y = 100;
private double speedY = 0;
private BufferedImage dinoImage;
public Dino() {
dinoImage = getImage("data/dino.png");
}
public void updatePosition() {
if(y + speedY >= GROUND_Y - 100) {
speedY = 0;
y = GROUND_Y - 100;
} else {
speedY += GRAVITY;
y += speedY;
}
}
public void jump() {
if(y == GROUND_Y - 100) {
speedY = -5;
y += speedY;
}
}
public void draw(Graphics g) {
g.setColor(Color.BLACK);
g.drawRect((int)x, (int)y, 100, 100);
g.drawImage(dinoImage, (int)x, (int)y, null);
}
}
Resource.java
public class Resource {
public static BufferedImage getImage(String path) {
BufferedImage image = null;
try {
image = ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
}
setSize(1000, 500);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameScreen = new GameScreen();
add(gameScreen);
Swing components need to be added to the frame BEFORE the frame is made visible. Otherwise the panel has a size of (0, 0) and there is nothing to paint.
The code should be something like:
gameScreen = new GameScreen();
add(gameScreen);
setSize(1000, 500);
setVisible(true);

I am Strugling to create and understand a specific method for a simple shooter game program

These are the specific instruction but they are kind of confusing to me (are the instructions confusing/ambiguous or am I just not getting it?)
write a method public static void draw shooter(Graphics g, Color c);
call draw shooter using the shooter color as the last parameter in drawAll(?)
test the program you should see a red disk centered near the bottom of the screen(?)
import java.awt.*;
public class Project2{
public static final int PANEL_WIDTH = 300;
public static final int PANEL_HEIGHT = 300;
public static final int SLEEP_TIME = 50;
public static Color SHOOTER_COLOR = Color.RED;
public static Color BACKGROUND_COLOR = Color.WHITE;
public static final int SHOOTER_SIZE = 20; //diameter of the shooter
public static final int GUN_SIZE = 10; //length og the gun
public static final int SHOOTER_POSITION_Y = PANEL_HEIGHT - SHOOTER_SIZE;
public static final int SHOOTER_INITIAL_POSITION_X = 150;
int shooterPosition;
public static void initialize(){
int shooterPositionX = SHOOTER_INITIAL_POSITION_X;
}
public static void main(String[] args) {
DrawingPanel panel = new DrawingPanel(PANEL_WIDTH, PANEL_HEIGHT);
Graphics g = panel.getGraphics( );
initialize();
startGame(panel, g);
drawShooter(g, SHOOTER_COLOR);
}
public static void drawShooter(Graphics g, Color C){
g.setColor(Color);
g.fillOval(shooterPosition, SHOOTER_POSITION_Y, SHOOTER_SIZE, SHOOTER_SIZE);
}
public static void drawAll(Graphics g){
g.drawString("Project 2 by Jasmine Ramirez", 10, 15);
}
public static void startGame(DrawingPanel panel, Graphics g) {
for (int i = 0; i <= 10000; i++) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
}
}
this is my code I guessed that I needed to draw and color in a circle inside the method but I am getting errors with the g.setColor inside the method and I'm not sure what the second step means. Thanks just started learning to program.
Drawing Panel
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.ArrayList;
public class DrawingPanel implements ActionListener {
private static final String versionMessage =
"Drawing Panel version 1.1, January 25, 2015";
private static final int DELAY = 100; // delay between repaints in millis
private static final boolean PRETTY = false; // true to anti-alias
private static boolean showStatus = false;
private static final int MAX_KEY_BUF_SIZE = 10;
private int width, height; // dimensions of window frame
private JFrame frame; // overall window frame
private JPanel panel; // overall drawing surface
private BufferedImage image; // remembers drawing commands
private Graphics2D g2; // graphics context for painting
private JLabel statusBar; // status bar showing mouse position
private volatile MouseEvent click; // stores the last mouse click
private volatile boolean pressed; // true if the mouse is pressed
private volatile MouseEvent move; // stores the position of the mouse
private ArrayList<KeyInfo> keys;
// construct a drawing panel of given width and height enclosed in a window
public DrawingPanel(int width, int height) {
this.width = width;
this.height = height;
keys = new ArrayList<KeyInfo>();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
statusBar = new JLabel(" ");
statusBar.setBorder(BorderFactory.createLineBorder(Color.BLACK));
statusBar.setText(versionMessage);
panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
panel.setBackground(Color.WHITE);
panel.setPreferredSize(new Dimension(width, height));
panel.add(new JLabel(new ImageIcon(image)));
click = null;
move = null;
pressed = false;
// listen to mouse movement
MouseInputAdapter listener = new MouseInputAdapter() {
public void mouseMoved(MouseEvent e) {
pressed = false;
move = e;
if (showStatus)
statusBar.setText("moved (" + e.getX() + ", " + e.getY() + ")");
}
public void mousePressed(MouseEvent e) {
pressed = true;
move = e;
if (showStatus)
statusBar.setText("pressed (" + e.getX() + ", " + e.getY() + ")");
}
public void mouseDragged(MouseEvent e) {
pressed = true;
move = e;
if (showStatus)
statusBar.setText("dragged (" + e.getX() + ", " + e.getY() + ")");
}
public void mouseReleased(MouseEvent e) {
click = e;
pressed = false;
if (showStatus)
statusBar.setText("released (" + e.getX() + ", " + e.getY() + ")");
}
public void mouseEntered(MouseEvent e) {
// System.out.println("mouse entered");
panel.requestFocus();
}
};
panel.addMouseListener(listener);
panel.addMouseMotionListener(listener);
new DrawingPanelKeyListener();
g2 = (Graphics2D)image.getGraphics();
g2.setColor(Color.BLACK);
if (PRETTY) {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(1.1f));
}
frame = new JFrame("Drawing Panel");
frame.setResizable(false);
try {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // so that this works in an applet
} catch (Exception e) {}
frame.getContentPane().add(panel);
frame.getContentPane().add(statusBar, "South");
frame.pack();
frame.setVisible(true);
toFront();
frame.requestFocus();
// repaint timer so that the screen will update
new Timer(DELAY, this).start();
}
public void showMouseStatus(boolean f) {
showStatus = f;
}
public void addKeyListener(KeyListener listener) {
panel.addKeyListener(listener);
panel.requestFocus();
}
// used for an internal timer that keeps repainting
public void actionPerformed(ActionEvent e) {
panel.repaint();
}
// obtain the Graphics object to draw on the panel
public Graphics2D getGraphics() {
return g2;
}
// set the background color of the drawing panel
public void setBackground(Color c) {
panel.setBackground(c);
}
// show or hide the drawing panel on the screen
public void setVisible(boolean visible) {
frame.setVisible(visible);
}
// makes the program pause for the given amount of time,
// allowing for animation
public void sleep(int millis) {
panel.repaint();
try {
Thread.sleep(millis);
} catch (InterruptedException e) {}
}
// close the drawing panel
public void close() {
frame.dispose();
}
// makes drawing panel become the frontmost window on the screen
public void toFront() {
frame.toFront();
}
// return panel width
public int getWidth() {
return width;
}
// return panel height
public int getHeight() {
return height;
}
// return the X position of the mouse or -1
public int getMouseX() {
if (move == null) {
return -1;
} else {
return move.getX();
}
}
// return the Y position of the mouse or -1
public int getMouseY() {
if (move == null) {
return -1;
} else {
return move.getY();
}
}
// return the X position of the last click or -1
public int getClickX() {
if (click == null) {
return -1;
} else {
return click.getX();
}
}
// return the Y position of the last click or -1
public int getClickY() {
if (click == null) {
return -1;
} else {
return click.getY();
}
}
// return true if a mouse button is pressed
public boolean mousePressed() {
return pressed;
}
public synchronized int getKeyCode() {
if (keys.size() == 0)
return 0;
return keys.remove(0).keyCode;
}
public synchronized char getKeyChar() {
if (keys.size() == 0)
return 0;
return keys.remove(0).keyChar;
}
public synchronized int getKeysSize() {
return keys.size();
}
private synchronized void insertKeyData(char c, int code) {
keys.add(new KeyInfo(c,code));
if (keys.size() > MAX_KEY_BUF_SIZE) {
keys.remove(0);
// System.out.println("Dropped key");
}
}
private class KeyInfo {
public int keyCode;
public char keyChar;
public KeyInfo(char keyChar, int keyCode) {
this.keyCode = keyCode;
this.keyChar = keyChar;
}
}
private class DrawingPanelKeyListener implements KeyListener {
int repeatCount = 0;
public DrawingPanelKeyListener() {
panel.addKeyListener(this);
panel.requestFocus();
}
public void keyPressed(KeyEvent event) {
// System.out.println("key pressed");
repeatCount++;
if ((repeatCount == 1) || (getKeysSize() < 2))
insertKeyData(event.getKeyChar(),event.getKeyCode());
}
public void keyTyped(KeyEvent event) {
}
public void keyReleased(KeyEvent event) {
repeatCount = 0;
}
}
}
1st Error
In your drawShooter() method you do:
g.setColor(Color)
This is incorrect, since you need to pass an instance of the class Color not the class itself.
So instead use this:
g.setColor(C);
2nd Error
change the shooterPosition to static so that it can be accessed by a static method.
I assume that the method initialize() is also wrong because you are declaring a new shooterPosition int for no reason so do these changes:
int shooterPosition;
To:
public static int shooterPosition;
And
public static void initialize(){
int shooterPositionX = SHOOTER_INITIAL_POSITION_X;
}
To:
public static void initialize() {
shooterPosition = SHOOTER_INITIAL_POSITION_X;
}
3rd Error
In startGame() you are looping for 10000 times and each time you are waiting for a bit more than 1/20th of a second, which means that you will have to wait for almost 10 minutes until the red circle is drawn. So you have two options.
1st option: decrease the amount of iterations or even better remove the loop.
public static void startGame(DrawingPanel panel, Graphics g) {
for (int i = 0; i <= 10000; i++) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
}
To:
public static void startGame(DrawingPanel panel, Graphics g) {
for (int i = 0; i <= 1; i++) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
}
or
public static void startGame(DrawingPanel panel, Graphics g) {
panel.sleep(SLEEP_TIME);
drawAll(g);
}
2nd option: execute the drawShooter() method before the startGame() method or don't execute the startGame() at all.
startGame(panel, g); drawShooter(g, SHOOTER_COLOR);
To:
drawShooter(g, SHOOTER_COLOR);
startGame(panel, g);
or
drawShooter(g, SHOOTER_COLOR);
Didn't you ask this same question or something similar to it yesterday? And you're passing in the class name to g.setColor(Color) method and need to pass in the parameter which holds the object: g.setColor(C)
Your use of Graphics is not good, as you shouldn't use a Graphics obtained from a component via getGraphics(), but I'm guessing that it's because that's what your instructor told you to do. Same for use of a while (true) loop. Instead you should use a Swing Timer.
Like stated before g.setcolor(c) is required
check your error msgs since it allows you to gather that error and the shooterPosition error(its not public so cant be used inside a method)

Screen Keeps Flickering when Drawing Graphics on Canvas (Java)

I am a complete noob to Java Graphics.
I wrote a simple "game" in which you control a box with the arrow keys
Here is the source code:
package com.thundercrust.graphics;
public class Drawings extends Canvas implements KeyListener, Runnable {
public static Thread thread;
public static Drawings draw;
private static final long serialVersionUID = 1L;
public static boolean running = false;
public static int x = 640;
public static int y = 320;
public static int bulletX = 0;
public static int bulletY = 0;
public static int direction = 2;
public static boolean fired = false;
public static boolean show = false;
public static String colorCode;
public static final int WIDTH = 1366;
public static final int HEIGHT = WIDTH / 16 * 9;
public static final String title = "A Moving Box!";
JFrame frame = new JFrame();
public void paint(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(Color.black);
g2D.fillRect(0, 0, 1366, 768);
g2D.setColor(Color.pink);
g2D.fillRect(50, 50, 1266, 668);
if (colorCode.equals("red")) g2D.setColor(Color.red);
if (colorCode.equals("orange")) g2D.setColor(Color.orange);
if (colorCode.equals("yellow")) g2D.setColor(Color.yellow);
if (colorCode.equals("green")) g2D.setColor(Color.green);
if (colorCode.equals("blue")) g2D.setColor(Color.blue);
if (colorCode.equals("cyan")) g2D.setColor(Color.cyan);
if (colorCode.equals("gray")) g2D.setColor(Color.gray);
g2D.fillRect(x, y, 50, 50);
}
public Drawings() {
frame.addKeyListener(this);
frame.setTitle(title);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.add(this);
}
public void display() {
while (running = true) {
repaint();
try {
Thread.sleep(30);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
colorCode = JOptionPane.showInputDialog("Enter the color of the box: ");
running = true;
draw = new Drawings();
draw.start();
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP) { y-= 5; direction = 0; }
if (keyCode == KeyEvent.VK_DOWN) { y+= 5; direction = 2; }
if (keyCode == KeyEvent.VK_LEFT) {x-= 5; direction = 3;}
if (keyCode == KeyEvent.VK_RIGHT) {x+= 5; direction = 1;}
if (keyCode == KeyEvent.VK_Z) System.out.println("You pressed z");
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while (running = true) {
System.out.println("The Game is Running!");
repaint();
try {
Thread.sleep(60);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The reason why I am asking for help is because the application always flickers and it gets really annoying.
Is there any way to fix this?
Any help would be appreciated.
Canvas is not double buffered and I'd recommend not using it this way. Instead, consider using a JPanel and overriding it's paintComponent method, this will give you double buffering for free.
See Painting in AWT and Swing and Performing Custom Painting for some deatils
Alternatively, you could use BufferStrategy, which would allow you to define you own double buffering strategy as well as take complete control over the painting process, letting you control when the canvas was painted (AKA active painting)

ActionPerformed method not working from another class

Im trying to add an object of the RedSquare class in to the JFrame in CatchMeV2 class. What is the problem?
public class CatchMeV2 implements ActionListener{
int width = 400;
int height = 450;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setSize(400, 400);
frame.setTitle("CatchMe.V2");
RedSquare r = new RedSquare();
frame.add(r);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
public class RedSquare extends JPanel implements ActionListener {
int x = 20; int y = 20;
int velX = 4; int velY = 4;
public RedSquare(){
addActionListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.green);
g.fillRect(x, y, 50, 50);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
x += velX;
y += velY;
if (x < 0) {
velX = 0;
x = 0;
}
if (x > 400 - 50) {
velX = 0;
x = 400 - 50;
}
if (y < 0) {
velY = 0;
y = 0;
}
if (y > 400 - 40) {
velY = 0;
y = 400 - 40;
}
repaint();
}
}
The actionPerformed method doesn't do anything. Can anyone help? Or is there an easy way to do this?
Background: I was trying to make a game by using one class. I did it but the problem was i could only take 1 key input at a time and it was lagging. And my teacher said that if I divided it into different classes it wouldn't lag. Is it true?
You cannot add non visual component to JPanel so you need to extend RedSquare class from component, for example JPanel and override paintComponent() method.
public class CatchMeV2 {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setTitle("CatchMe.V2");
RedSquare r = new RedSquare();
frame.setContentPane(r);
frame.setVisible(true);
}
}
class RedSquare extends JPanel implements ActionListener {
public RedSquare() {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // don't forget to call super method
g.setColor(Color.green);
g.fillRect(20, 20, 50, 50);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
update>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
you can't use action performed for panel it's only for buttons or like that.if you want to do something with click on panel then you need to use implement mouselistner .and put action code inside mouseclick method .run this example
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;
public class CatchMeV2 {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setSize(400, 400);
frame.setTitle("CatchMe.V2");
RedSquare r = new RedSquare();
frame.add(r);
}
}
class RedSquare extends JPanel implements MouseListener {
int x = 20;
int y = 20;
int velX = 4;
int velY = 4;
public RedSquare() {
addMouseListener(this);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(x, y, 50, 50);
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("hi");
x += velX;
y += velY;
if (x < 0) {
velX = 0;
x = 0;
}
if (x > 400 - 50) {
velX = 0;
x = 400 - 50;
}
if (y < 0) {
velY = 0;
y = 0;
}
if (y > 400 - 40) {
velY = 0;
y = 400 - 40;
}
this.repaint();
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
}
at that time you only want to move square with mouse click so u can still use awt mouse event but when you use keys you have to use key binding

Text Banner applet reverses that displayes text

i'm working on applet that displays a moving banner horizontally and when this text banner
reaches the right boundary of the applet window it should be appear reversed from the start of the left boundary, i write the following class to do the work, the problem is that when the text banner reaches the right banner it crashes, the applet goes to infinite loop:
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
/*
<applet code="banner" width=300 height=50>
</applet>
*/
public class TextBanner extends Applet implements Runnable
{
String msg = "Islam Hamdy", temp="";
Thread t = null;
int state;
boolean stopFlag;
int x;
String[] revMsg;
int msgWidth;
boolean isReached;
public void init()
{
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
}
// Start thread
public void start()
{
t = new Thread(this);
stopFlag = false;
t.start();
}
// Entry point for the thread that runs the banner.
public void run()
{
// Display banner
while(true)
{
try
{
repaint();
Thread.sleep(550);
if(stopFlag)
break;
} catch(InterruptedException e) {}
}
}
// Pause the banner.
public void stop()
{
stopFlag = true;
t = null;
}
// Display the banner.
public void paint(Graphics g)
{
String temp2="";
System.out.println("Temp-->"+temp);
int result=x+msgWidth;
FontMetrics fm = g.getFontMetrics();
msgWidth=fm.stringWidth(msg);
g.setFont(new Font("ALGERIAN", Font.PLAIN, 30));
g.drawString(msg, x, 40);
x+=10;
if(x>bounds().width){
x=0;
}
if(result+130>bounds().width){
x=0;
while((x<=bounds().width)){
for(int i=msg.length()-1;i>0;i--){
temp2=Character.toString(msg.charAt(i));
temp=temp2+temp;
// it crashes here
System.out.println("Before draw");
g.drawString(temp, x, 40);
System.out.println("After draw");
repaint();
}
x++;
} // end while
} //end if
}
}
Let's start with...
Use Swing over AWT components (JApplet instead of Applet)
Don't override the paint methods of top level containers. There are lots of reasons, the major one that is going to effect you is top level containers are not double buffered.
DO NOT, EVER, update the UI from any thread other the Event Dispatching Thread, in fact, for what you are trying to do, a Thread is simply over kill.
DO NOT update animation states with the paint method. You've tried to perform ALL you animation within the paint method, this is not how paint works. Think of paint as a frame in film, it is up to (in your case) the thread to determine what frame where up to, and in fact, it should be preparing what should painted.
You do not control the paint system. repaint is a "request" to the paint sub system to perform an update. The repaint manager will decide when the actual repaint will occur. This makes performing updates a little tricky...
Updated with Example
public class Reverse extends JApplet {
// Set colors and initialize thread.
public void init() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
setLayout(new BorderLayout());
add(new TextPane());
}
});
}
// Start thread
public void start() {
}
// Pause the banner.
public void stop() {
}
public class TextPane extends JPanel {
int state;
boolean stopFlag;
char ch;
int xPos;
String masterMsg = "Islam Hamdy", temp = "";
String msg = masterMsg;
String revMsg;
int msgWidth;
private int direction = 10;
public TextPane() {
setOpaque(false);
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
setFont(new Font("ALGERIAN", Font.PLAIN, 30));
// This only needs to be done one...
StringBuilder sb = new StringBuilder(masterMsg.length());
for (int index = 0; index < masterMsg.length(); index++) {
sb.append(masterMsg.charAt((masterMsg.length() - index) - 1));
}
revMsg = sb.toString();
// Main animation engine. This is responsible for making
// the decisions on where the animation is up to and how
// to react to the edge cases...
Timer timer = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
FontMetrics fm = getFontMetrics(getFont());
if (xPos > getWidth()) { // this condition fires when the text banner reaches the right banner
direction *= -1;
msg = revMsg;
} else if (xPos < -fm.stringWidth(masterMsg)) {
direction *= -1;
msg = masterMsg;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(xPos);
FontMetrics fm = g.getFontMetrics();
msgWidth = fm.stringWidth(msg);
g.drawString(msg, xPos, 40);
}
}
}
Updated with additional example
Now, if you want to be a little extra clever...you could take advantage of a negative scaling process, which will reverse the graphics for you...
Updated timer...
Timer timer = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
FontMetrics fm = getFontMetrics(getFont());
System.out.println(xPos + "; " + scale);
if (scale > 0 && xPos > getWidth()) { // this condition fires when the text banner reaches the right banner
xPos = -(getWidth() + fm.stringWidth(msg));
scale = -1;
} else if (scale < 0 && xPos >= 0) {
xPos = -fm.stringWidth(msg);
scale = 1;
}
repaint();
}
});
And the updated paint method...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.scale(scale, 1);
FontMetrics fm = g2d.getFontMetrics();
msgWidth = fm.stringWidth(msg);
g2d.drawString(msg, xPos, 40);
g2d.dispose();
}
Updated with "bouncing"...
This replaces the TextPane from the previous example
As the text moves beyond the right boundary, it will "reverse" direction and move back to the left, until it passes beyond that boundary, where it will "reverse" again...
public class TextPane public class TextPane extends JPanel {
int state;
boolean stopFlag;
char ch;
int xPos;
String msg = "Islam Hamdy";
int msgWidth;
private int direction = 10;
public TextPane() {
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
setFont(new Font("ALGERIAN", Font.PLAIN, 30));
Timer timer = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
FontMetrics fm = getFontMetrics(getFont());
if (xPos > getWidth()) {
direction *= -1;
} else if (xPos < -fm.stringWidth(msg)) {
direction *= -1;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
msgWidth = fm.stringWidth(msg);
g2d.drawString(msg, xPos, 40);
g2d.dispose();
}
}
I now think you mean 'should jump back to the start', but this slides back. But as an aside, I would not consider an applet for this sort of thing, for two reasons.
Scrolling text sucks.
If the page 'must have' scrolling text, better to do it using HTML and JS (and CSS).
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/*
* <applet code="TextBanner" width=600 height=50> </applet>
*/
public class TextBanner extends JApplet {
private TextBannerPanel banner;
// Set colors and initialize thread.
#Override
public void init() {
banner = new TextBannerPanel("Islam Hamdy");
add(banner);
}
// Start animation
#Override
public void start() {
banner.start();
}
// Stop animation
#Override
public void stop() {
banner.stop();
}
}
class TextBannerPanel extends JPanel {
String msg;
int x;
int diff = 5;
Timer timer;
Font font = new Font("ALGERIAN", Font.PLAIN, 30);
public TextBannerPanel() {
new TextBannerPanel("Scrolling Text Banner");
}
public TextBannerPanel(String msg) {
this.msg = msg;
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
ActionListener animate = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
repaint();
}
};
timer = new Timer(100, animate);
}
// Display the banner.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
int w = (int) fm.getStringBounds(msg, g).getWidth();
g.drawString(msg, x, 40);
x += diff;
diff = x+w > getWidth() ? -5 : diff;
diff = x < 0 ? 5 : diff;
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
}
Old answer
..should .. appear reversed .. "Islam Hamdy"
See also JArabicInUnicode:
import javax.swing.*;
import java.awt.*;
/**
* "Peace Be Upon You", "Aslam Alykm' to which the common reply is "Wa alaykum
* as salaam", "And upon you, peace". Information obtained from the document
* http://www.unicode.org/charts/PDF/U0600.pdf Copyright © 1991-2003
* Unicode, Inc. All rights reserved. Arabic is written and read from right to
* left. This source is adapted from the original 'Peace' source written by
* mromarkhan ("Peace be unto you").
*
* #author Omar Khan
* #author Andrew Thompson
* #version 2004-05-31
*/
public class JArabicInUnicode extends JFrame {
/**
* Unicode constant used in this example.
*/
public final static String ALEF = "\u0627",
LAM = "\u0644",
SEEN = "\u0633",
MEEM = "\u0645",
AIN = "\u0639",
YEH = "\u064A",
KAF = "\u0643",
HEH = "\u0647";
/**
* An array of the letters that spell 'Aslam Alykm'.
*/
String text[] = {
ALEF, //a
LAM + SEEN, //s
LAM, //l
ALEF, //a
MEEM, //m
" ",
AIN, //a
LAM, //l
YEH, //y
KAF, //k
MEEM //m
};
/**
* Displays the letters of the phrase 'Aslam Alykm' as well as the words
* spelt out letter by letter.
*/
public JArabicInUnicode() {
super("Peace be upon you");
JTextArea textwod = new JTextArea(7, 10);
textwod.setEditable(false);
textwod.setFont(new Font("null", Font.PLAIN, 22));
String EOL = System.getProperty("line.separator");
// write the phrase to the text area
textwod.append(getCharacters() + EOL);
// now spell it, one letter at a time
for (int ii = 0; ii <= text.length; ii++) {
textwod.append(getCharacters(ii) + EOL);
}
textwod.setCaretPosition(0);
getContentPane().add(
new JScrollPane(textwod,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED),
BorderLayout.CENTER);
pack();
setMinimumSize(getPreferredSize());
try {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
} catch (Exception e) {
} // allows to run under 1.2
}
/**
* Get a string of the entire phrase.
*/
String getCharacters() {
return getCharacters(text.length);
}
/**
* Get a string of the 1st 'num' characters of the phrase.
*/
String getCharacters(int num) {
StringBuffer sb = new StringBuffer();
for (int ii = 1; ii < num; ii++) {
sb.append(text[ii]);
}
return sb.toString();
}
/**
* Instantiate an ArabicInUnicode frame.
*/
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new JArabicInUnicode().setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}

Categories