Program won't work on all operation systems
hey there,
some of you might have seen my latest post in which i've asked for hep with my pong project.
Well I've finished it and its working all right, but the problem is that its running corectly only on windows XP.
The first window works fine on all the operation systems, but the main window just shows the background and sometimes I see the rackets and the ball blink on the screen.
I have a feeling that on other operation systems except windows xp the paint method cleans the screen too fast or something.
Here is the code:
Main:
Code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pongnew;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.logging.*;
import javax.swing.*;
/**
*
* @author User
*/
public class Main extends JFrame implements Runnable{
JPanel p = new JPanel();;
Racket p1,p2;
Ball ball;
private int speed;
Thread t,pc;
ScoreBoard sb;
public Main(){
//Form info
super("Pong - made by Alex.");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400,300);
setResizable(false);
//JPanel
p.setBackground(new Color(0,155,0));
this.add(p);
//Thread
t = new Thread(this);
//score board
sb = new ScoreBoard();
}
public void paint(Graphics g){
super.paint(g);
//draw Players
p1.drawMe(g);
p2.drawMe(g);
//draw ball
ball.drawMe(g);
//draw board
sb.drawMe(100, this.getWidth()-100, 50, 50, g);
}
public void run() {
while(!ball.didLose()){
try { t.sleep(50);}
catch (InterruptedException ex) {}
ball.move();
p1.updateBallLocation(ball.getX(), ball.getY());
p2.updateBallLocation(ball.getX(), ball.getY());
if(ball.getX() + ball.getDiameter()<0 || ball.getX() > this.getWidth()){
this.getContentPane().getGraphics().setColor(p.getBackground());
this.getContentPane().getGraphics().fillRect(0, 0, WIDTH, HEIGHT);
p1.restart();
p2.restart();
ball.restart();
ball.setLost(true);
if(ball.getX() + ball.getDiameter()<0)
sb.setP1(sb.getP1()+1);
else
sb.setP2(sb.getP2()+1);
try { t.sleep(3000);}
catch (InterruptedException ex) {}
ball.setLost(false);
}
}
}
public void setSpeed(int speed){
this.speed = speed;
}
public int getSpeed()
{
return speed;
}
public void createObjects(){
//Players
p1 = new Racket(20, this.getHeight()/3, 20, 100, this.getHeight(), false,this);
p2 = new Racket(this.getWidth()-40, this.getHeight()/3, 20, 100, this.getHeight(), true,this);
//Ball
ball = new Ball(this.getWidth()/2-25, this.getHeight()/2, 30, speed, this.getHeight(), this.getWidth(), this, p1, p2);
//Send ball to Racket
p1.setBall(ball);
p2.setBall(ball);
//KeyListeners
this.addKeyListener(p1);
this.addKeyListener(p2);
//Thread
pc = new Thread(p2);
t.start();
pc.start();
//show frame
setVisible(true);
}
}
Racket:
Code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pongnew;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author User
*/
public class Racket implements KeyListener,Runnable{
private int x,y,width,height;
private int formHeight;
private int defaultX, defaultY;
private int ballX,ballY;
boolean auto;
Main m;
Ball ball;
public Racket(int x, int y, int width, int height, int formHeight, boolean auto, Main m) {
this.x = x;
this.y = y;
defaultX = x;
defaultY = y;
this.width = width;
this.height = height;
this.formHeight = formHeight;
this.auto = auto;
this.m = m;
}
public void setBall(Ball b){
ball = b;
}
public boolean isAuto() {
return auto;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth(){
return width;
}
public int getHeight(){
return height;
}
public void moveUp(int speed){
if(y-speed>=30){
this.y -= speed;
} else
this.y = 30;
}
public void moveDown(int speed){
if(y+speed+height <= formHeight){
this.y += speed;
} else
this.y = formHeight-height;
}
public void drawMe(Graphics g){
g.setColor(Color.green);
g.fillRect(x, y, width, height);
g.setColor(Color.BLACK);
g.drawLine(x, y+height/2
, x+width, y+height/2);
}
public void restart(){
this.x = defaultX;
this.y = defaultY;
m.repaint();
}
public void updateBallLocation(int x,int y){
this.ballX = x;
this.ballY = y;
}
public void think(){
if(ballX>=m.getWidth()/2-50){
if(ball.getDirectionY()==1 && ballY+ball.getDiameter() < y+30+m.getSpeed()){
moveUp(5);
try {m.pc.sleep(30- m.getSpeed());}
catch(Exception e) {}
}
else if (ball.getDirectionY()==2 && ballY > y+height - 30 - m.getSpeed()){
moveDown(5);
try {m.pc.sleep(30 - m.getSpeed());}
catch(Exception e) {}
}
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if(!isAuto()){
if(e.getKeyCode() == KeyEvent.VK_UP){
if(m.getSpeed()>5)
moveUp(m.getSpeed());
else
moveUp(5);
m.repaint();
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
if(m.getSpeed()>5)
moveDown(m.getSpeed());
else
moveDown(5);;
m.repaint();
}
}
}
public void keyReleased(KeyEvent e) {
}
public void run() {
while(!ball.didLose()){
if(isAuto()){
think();
if(ball.didLose()){
try { m.pc.sleep(3000);}
catch (InterruptedException ex) {}
ball.setLost(false);
}
}
}
}
}
Ball:
Code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pongnew;
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author User
*/
public class Ball {
private int x,y,d,speed;
private int formHeight,formWidth;
private int defaultX, defaultY;
private int directionX, directionY;
private int ranX,ranY;
boolean lost;
Main m;
Racket p1,p2;
public Ball(int x, int y, int d,int speed, int formHeight, int formWidth, Main m, Racket p1, Racket p2) {
this.x = x;
this.y = y;
this.defaultX = x;
this.defaultY = y;
this.d = d;
this.speed = speed;
this.formHeight = formHeight;
this.formWidth = formWidth;
this.m = m;
this.p1 = p1;
this.p2 = p2;
lost = false;
ranX = speed;
ranY = (int)(Math.random()*((speed+3)-speed+1)+speed);
ranDirection();
}
public void ranDirection(){
setDirectionX((int)(Math.random()*(2-1+1)+1));
setDirectionY((int)(Math.random()*(2-1+1)+1));
}
public void addSpeed(int s){
speed += s;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setLost(boolean b){
lost = b;
}
public boolean didLose(){
return lost;
}
public void setDirectionX(int directionX) {//1-right, 2-left
this.directionX = directionX;
}
public void setDirectionY(int directionY) {//1-up, 2-down
this.directionY = directionY;
}
public int getDirectionX() {
return directionX;
}
public int getDirectionY() {
return directionY;
}
public int getDiameter(){
return d;
}
public boolean inField(){
return this.x-(d/2) >= p1.getX() + p1.getWidth() && x+(d/2)<=p2.getX();
}
public boolean hitLeft(){
return x <= p1.getX() + p1.getWidth() && x>=p1.getX() && y>=p1.getY() && y<=p1.getY()+p1.getHeight();
}
public boolean hitRight(){
return x+d>= p2.getX() && x+d <=p2.getX()+p2.getWidth() && y+d>=p2.getY() && y+d<=p2.getY()+p2.getHeight();
}
public void move(){
if(y<=30 && inField())
directionY=2;
if(y+d>=formHeight && inField())
directionY=1;
if(hitLeft()){
if(y>=p1.getY() && y<p1.getY() + p1.getHeight()/2)
directionY = 1;
else if(y>=p1.getY() && y>p1.getY() + p1.getHeight()/2)
directionY=2;
directionX=1;
}
if(hitRight()){
if(y>=p2.getY() && y<p2.getY() + p2.getHeight()/2)
directionY = 1;
else if(y>=p2.getY() && y>p2.getY() + p2.getHeight()/2)
directionY=2;
directionX=2;
}
if(directionX==1)
x+=ranX;
else
x-=ranX;
if(directionY==1)
y-=ranY;
else
y+=ranY;
if(y+d>formHeight){
y-=d;
directionY = 1;
} else if (y<0){
y+=y;
directionY=2;
}
m.repaint();
}
public int getRanX(){
return ranX;
}
public int getRanY(){
return ranY;
}
public void setRanX(int ranX){
this.ranX = ranX;
}
public void setRanY(int ranY){
this.ranY = ranY;
}
public void drawMe(Graphics g){
g.setColor(Color.red);
g.fillOval(x,y, d, d);
}
public void restart(){
this.x = defaultX;
this.y = defaultY;
ranDirection();
m.repaint();
}
}
Selection:
Code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/*
* Selection.java
*
* Created on 18/07/2011, 20:02:28
*/
package pongnew;
/**
*
* @author User
*/
public class Selection extends javax.swing.JFrame {
/** Creates new form Selection */
public Selection() {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jComboBox1 = new javax.swing.JComboBox();
jRadioButton1 = new javax.swing.JRadioButton();
buttonGroup1 = new javax.swing.ButtonGroup();
jPanel1 = new javax.swing.JPanel();
start = new javax.swing.JButton();
speedLbl = new javax.swing.JLabel();
speedBox = new javax.swing.JComboBox();
jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
jRadioButton1.setText("jRadioButton1");
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Pong - Made by Alex.");
setResizable(false);
jPanel1.setBackground(new java.awt.Color(0, 102, 51));
start.setText("Start");
start.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startActionPerformed(evt);
}
});
speedLbl.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
speedLbl.setForeground(new java.awt.Color(255, 255, 255));
speedLbl.setText("Choose ball speed");
speedBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "4", "5", "6", "7" }));
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(25, 25, 25)
.addComponent(speedLbl)
.addGap(18, 18, 18)
.addComponent(speedBox, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(196, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap(320, Short.MAX_VALUE)
.addComponent(start)
.addGap(23, 23, 23))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(speedLbl)
.addComponent(speedBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(46, 46, 46)
.addComponent(start)
.addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
private void startActionPerformed(java.awt.event.ActionEvent evt) {
Main m = new Main();
m.setSpeed(Integer.parseInt(speedBox.getSelectedItem().toString().trim()));
m.createObjects();
this.setVisible(false);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Selection().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JComboBox jComboBox1;
private javax.swing.JPanel jPanel1;
private javax.swing.JRadioButton jRadioButton1;
private javax.swing.JComboBox speedBox;
private javax.swing.JLabel speedLbl;
private javax.swing.JButton start;
// End of variables declaration
}
ScoreBoard:
Code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pongnew;
import java.awt.Color;
import java.awt.Graphics;
/**
*
* @author User
*/
public class ScoreBoard {
private int p1,p2;
public ScoreBoard(){
p1=0;
p2=0;
}
public int getP1() {
return p1;
}
public int getP2() {
return p2;
}
public void setP1(int s){
p1 = s;
}
public void setP2(int s){
p2 = s;
}
public void drawMe(int x1,int x2,int y1,int y2,Graphics g){
g.setColor(Color.WHITE);
g.drawString(" "+p1, x1, y1);
g.drawString("Player1", x1, y1+20);
g.drawString(" "+p2, x2, y2);
g.drawString("Player2", x2, y2+20);
}
}
Re: Program won't work on all operation systems
Some suggested code changes to make the drawing a bit smoother:
Code :
MyJPanel p = new MyJPanel(); // Use your own class
...
class MyJPanel extends JPanel { // Add this line before paint()
public void paintComponent(Graphics g){ //change to this vs paint
super.paintComponent(g);
.... your paint code here
} // end class MyJPanel
Re: Program won't work on all operation systems
So instead of extending JFrame in the Main class I should extend JPanel?
Or am I supposed to create a new class that extends JPanel?
and how am I supposed to call the paintComponent method? or is it evoked on its own when I add the panel to the frame?
And to repaint do I use MyJPanel Object.repaint()?
Re: Program won't work on all operation systems
The changes were to put the paint method in a JPanel class. That's all I did.
Replace the definition of p,
insert the class MyJPanel ... {
and the ending }
and change paint to paintComponent.
Re: Program won't work on all operation systems
Because I've already written the code using the Jframe's width and height, once I tried what you suggested it made border problems, and some bugs.
I do agree that it does make the painting better, and thus ill be using this on my other projects, but ill keep the code as is for this project.
And to my question.What could cause the problem that the program works fine only on windows xp?
EDIT:
I did the modifies as you said also on windows 7 and it suddenly worked fine.
Why is it working normally on other windowses than xp only when using the paintComponent method and not the paint method?
Re: Program won't work on all operation systems
I only have XP so you'll have to wait for someone with another OS.
I don't know how putting the paint method in a JPanel would cause you problems.
What do the problems look like? What works differently?
Re: Program won't work on all operation systems
I have both windows xp and windows 7.
Once I've put the JPanel then it didnt include the decoration in the windows height and width as with the JFrame.
I've written all my code including the decoration and all the calculations will now be different because the decoration with the JPanel is exluded and its a lot of work to find each line that is connected to the decoration and so on.
Thanks anyway, but in this project i'll stay without the JPanel.
Re: Program won't work on all operation systems
Quote:
its a lot of work to find each line that is connected to the decoration
That is something that a good design would isolate to one variable vs having hard coded magic numbers hidden in the code.
Is that what the 30 that I see here and there is used for?
Re: Program won't work on all operation systems
I haven't programmed using gui a long time so I was making this project to remember coding tricks and the best ways to make some things.
and yes the 30 is the decoration height which i included in some places.