zoom in/out graph using AWT on Applet - java

I am newbie to the java....working on a piece of applet code...............as I am still going through the OOPs concepts and java understanding and need to develop below mentioned functionality.
The piece of code I have works like this :
First it reads all parameters from HTML tags and stores in global variables. Then it sends query to CGI to read graph data. Then it converts data for plotting and draws graph. There is a option for user to select 1-24 hours. Based on the selection graph will be plotted by plotting only selected data. Every 30 sec it sends query to CGI for collecting data.
The code uses following library and uses java 1.5 environment and i cannot change it due to embeded requirements :
I need to enchance it by implementing zoom in zoom out feature with x-y axis granuality changing with zoom in .
My worry is how to do that?I know its Frustrating question ...but i am here to get suggestion from the java experts so that I can quickly learn and implement this stuff.
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;
/******************************************************************************
*
* Class - Graph
*
* This is the entry point.
* This class extends Applet class and implements Runnable.
*
*****************************************************************************/
public class GraphPerf extends Applet implements Runnable,ItemListener,MouseMotionListener
{
//Global variables
int MAX_DATA_X ;
int SIZE_X= 480;
int SIZE_Y= 250;
int SIZE_Y1= 240;
int MIN_ERROR = -1;
int MAX_LOG10_ERROR_COUNT = 1001;
int MAX_ERROR_COUNT = 101;
int SIZE_Y_EXTENDED_BOTTOM = 20;
int MAX_DISP_PARMS = 16;
int MAX_NUM_INTERVELL_PER_DAY = 96;
int MAX_DISP_PARMS_STD = 7;
int refreshTime;
String serverAddress,hostAddr;
Color plotColor1,plotColor8;
float graphData[][];
float graph_data_rf_east,graph_data_rf_west;
int xOffset = 50;
int yOffset = 40;
int Y1_MAX_VALUE = 100;
int Y2_MAX_VALUE = 3;
float RANGE2;
Thread graphThread;
Image Buffer;
Graphics plot;
Choice timeChoice, modeChoice, seloptChoice;
int duration=1, viewMode=1, line_type = 0,viewOpt = 1;
Label valueLabel1, valueLabel2,valueLabel3,valueLabel4,valueLabel5;
boolean GraphBottomExtendFlag=true;
/******************************************************************************
*
* method - init
*
* This is the method called first after applet loaded in to browser.
* This function reads configurable parameters from HTML tag and updates
* global variables.
*****************************************************************************/
public void init()
{
MAX_DATA_X = 672;//Integer.parseInt(getParameter("max_data_x"));
//refreshTime = 30;//Integer.parseInt(getParameter("refresh_sec"));
/*URL url = getDocumentBase();
String host = url.getHost();
try
{
InetAddress addr = InetAddress.getByName(host);
hostAddr=addr.getHostAddress();
}catch (UnknownHostException ex) {
ex.printStackTrace();
}
*/
//serverAddress = new String ( getParameter("access_str")+ hostAddr + getParameter("data_server"));
graphData = new float[MAX_DISP_PARMS][MAX_DATA_X+1];
/*initialize the array with -1 not with 0(0 also valid for graph data) */
int i =0,j = 0;
for( j=0; j<MAX_DISP_PARMS; j++)
{
for( i=0; i<MAX_DATA_X+1; i++)
{
graphData[j][i] = -1;
}
}
graph_data_rf_east = -1;
graph_data_rf_west = -1;
plotColor1 = Color.orange;
plotColor2 = Color.black;
plotColor8 = Color.red;
plotColor9 = Color.green;
setBackground(Color.white);
setLayout(null);
timeChoice = new Choice();
timeChoice.add("1");
timeChoice.add("2");
timeChoice.add("3");
timeChoice.add("4");
timeChoice.add("5");
timeChoice.add("6");
timeChoice.add("7");
add(timeChoice);
timeChoice.setBounds(190,340,40,23);
timeChoice.addItemListener(this);
Label timeLabel1 = new Label("View graph for last");
Label timeLabel2 = new Label("day(s)");
add(timeLabel1);
timeLabel1.setBounds(xOffset+30,340,160,23);
add(timeLabel2);
timeLabel2.setBounds(240,340,50,23);
valueLabel1 = new Label();
add(valueLabel1);
valueLabel1.setBounds(300,340,50,23);
valueLabel2 = new Label();
add(valueLabel2);
valueLabel2.setBounds(370,340,70,23);
valueLabel3 = new Label();
add(valueLabel3);
valueLabel3.setBounds(440,340,70,23);
valueLabel4 = new Label();
add(valueLabel4);
valueLabel4.setBounds(500,340,70,23);
valueLabel5 = new Label();
add(valueLabel5);
valueLabel5.setBounds(370,370,80,25);
modeChoice = new Choice();
modeChoice.add("East");
modeChoice.add("West");
/* Display this only for Protected and East-West Mode */
if(2/*Integer.parseInt(getParameter("mode"))*/ == 2)
{
add(modeChoice);
}
else
{
viewOpt = 1;
}
modeChoice.setBounds(xOffset+SIZE_X-55, 0, 60, 25);
modeChoice.addItemListener(this);
addMouseMotionListener(this);
}
public void start()
{
graphThread = new Thread(this);
graphThread.start();
}
public void stop()
{
graphThread = null;
}
/******************************************************************************
*
* This method will be called after starting the thread. This is a
* infinite loop which will call query method for every 30 sec to read data
* from CGI. Then it plots graph by calling plotGraph method
* the thread.
*****************************************************************************/
public void run()
{
/*while (false)
{
try
{//getData(serverAddress);
int sizeY = SIZE_Y;
if(GraphBottomExtendFlag)
{
sizeY += SIZE_Y_EXTENDED_BOTTOM;
}
repaint(xOffset+1,yOffset+1,SIZE_X-1,sizeY-1);
//graphThread.sleep(refreshTime*1000);
}catch (Exception e) { System.out.println(e); }
}*/
}
/******************************************************************************
*
* method - paint
*
* This method displays the graph plotted by plotGraph method
* in the screen. Then it draws axis for the graph
*
*****************************************************************************/
public void paint(Graphics g1)
{
int sizeY = SIZE_Y;
/*If Graph Bottom is to be Etended
*soo that zero is displayed properly
*/
if(GraphBottomExtendFlag)
{
sizeY += SIZE_Y_EXTENDED_BOTTOM;
}
if( duration <= 5 )
{
Buffer = createImage(SIZE_X, sizeY);
plot = Buffer.getGraphics();
plotGraph(plot);
g1.drawImage (Buffer,xOffset,yOffset,this);
}
else
{
Buffer = createImage(MAX_DATA_X*duration/7,sizeY);
plot = Buffer.getGraphics();
plotGraph(plot);
g1.drawImage (Buffer,xOffset,yOffset,SIZE_X,sizeY,this);
}
g1.setColor(Color.black);
g1.drawRect(70,150,270,80);
/*Dram Graph boarder */
g1.drawRect(xOffset,yOffset,SIZE_X,sizeY);
g1.drawRect(xOffset-1,yOffset-1,SIZE_X+2,sizeY+2);
/*Plot X axis*/
int max_x_marks = 8;
int temp = 1,cnt_graph = 0;
int float_temp,float_temp2;
/*max 8 plots on x axis*/
for(int x=max_x_marks; x>0; x--)
{
float_temp = (int)((MAX_NUM_INTERVELL_PER_DAY*duration)/max_x_marks)*((max_x_marks+1)-x);
float_temp2 = SIZE_X-(60*cnt_graph);
g1.drawString(String.valueOf(float_temp),(float_temp2-20) ,SIZE_Y+yOffset+35);
cnt_graph++;
}
/*Plot Y1 AXIS*/
temp = Y1_MAX_VALUE;
for(int x = 0; x <= SIZE_Y; x+= 25)
{
g1.drawString(String.valueOf(temp), 25, x + yOffset+10);
temp -= (Y1_MAX_VALUE - 0)/10;
}
temp = 1000;
/*Plot Y2 AXIS*/
int index_log = 1;
for(int x = 0; x <= SIZE_Y1; x+= 80)
{
if(x== 240)
index_log--;
if(temp>=1)
{
g1.drawString(String.valueOf(temp), 550, x+yOffset+8-index_log);
g1.drawLine(530,x+yOffset+5-index_log, 540, x+yOffset+5-index_log);
}
temp = temp/10;
}
Font thisFont = new Font("Times New Roman", Font.BOLD, 14);
g1.setFont(thisFont);
g1.drawString("Y2", 550, 160);
g1.drawString("Y1",5, 160);
}
/******************************************************************************
*
* method - plotGraph
*
* Depending on the mode, "East", "West" or "Combined", it plots
* single or two graphs in the same applet.
*
* Inputs :
* g - Graphics object
*****************************************************************************/
public void plotGraph(Graphics g)
{
g.setColor(new Color(255,255,220));
/*If Error-Sec-Count Graph
*Then extend the lower portion
*soo that zero is displayed properly
*/
if(GraphBottomExtendFlag)
{
g.fillRect(0,0,MAX_DATA_X,SIZE_Y + SIZE_Y_EXTENDED_BOTTOM);
}
else
{
g.fillRect(0,0,MAX_DATA_X,SIZE_Y);
}
switch(viewMode)
{
case 1 :
plot1(g);
plot_timeelapsed_east(g);
break;
case 2 :
plot8(g);
plot_timeelapsed_west(g);
break;
}
}
/******************************************************************************
*
* method - plot1
*
* This method uses graphData[0][] global variable and plots series of lines
* in the applet
*
* Inputs :
* g - Graphics object
*****************************************************************************/
void plot1(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
localPlotBuffer = new int[2];
g.setColor(plotColor1);
if(duration > 5)
{
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY); x > 0 ; x--)
{
/*if data is valid data then plot else ignore*/
if((graphData[0][end]>MIN_ERROR)&&(graphData[0][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[0][end-1]>MIN_ERROR)&&(graphData[0][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end-1] == 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine(x-1,(localPlotBuffer[0]+5), x-2,(localPlotBuffer[1]+5));
g.drawLine(x,(localPlotBuffer[0]+5), x-1,(localPlotBuffer[1]+5));
}
end--;
}
}
else
{
float temp = SIZE_X;
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY) ; x > 0 ; x--)
{
float LocalTemp1 = temp;
float LocalTemp2 = (int)(temp-(double)5/(double)duration);
/*Normalise the pixcel positions */
/*Normalise the pixcel positions */
if(duration == 1)
{
if(LocalTemp1>(SIZE_X-3))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-3))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 2)
{
if(LocalTemp1>(SIZE_X-2))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-2))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 3)
{
if(LocalTemp1>(SIZE_X-1))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-1))
LocalTemp2 = SIZE_X;
}
/*if data is valid data then plot else ignore*/
if((graphData[0][end]>MIN_ERROR)&&(graphData[0][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[0][end-1]>MIN_ERROR)&&(graphData[0][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[0][end-1] == 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[0][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[0][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine((int)LocalTemp1,(localPlotBuffer[0]+5), (int)LocalTemp2,(localPlotBuffer[1]+5));
}
temp-=(double)5/(double)duration;
end--;
}
}
}
/******************************************************************************
*
* method - plot8
*
* This method uses graphData[7][] global variable and plots series of lines
* in the applet
*
* Inputs :
* g - Graphics object
*****************************************************************************/
void plot8(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
localPlotBuffer = new int[2];
g.setColor(plotColor1);
if(duration > 5)
{
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY); x > 0 ;x-- )
{
/*if data is valid data then plot else ignore*/
if((graphData[8][end]>MIN_ERROR)&&(graphData[8][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[8][end-1]>MIN_ERROR)&&(graphData[8][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end-1]== 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine(x-1,(localPlotBuffer[0]+5), x-2,(localPlotBuffer[1]+5));
g.drawLine(x,(localPlotBuffer[0]+5), x-1,(localPlotBuffer[1]+5));
}
end--;
}
}
else
{
float temp = SIZE_X;
for(int x=(duration*MAX_NUM_INTERVELL_PER_DAY) ; x > 0 ; x--)
{
float LocalTemp1 = temp;
float LocalTemp2 = (int)(temp-(double)5/(double)duration);
/*Normalise the pixcel positions */
if(duration == 1)
{
if(LocalTemp1>(SIZE_X-3))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-3))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 2)
{
if(LocalTemp1>(SIZE_X-2))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-2))
LocalTemp2 = SIZE_X;
}
/*Normalise the pixcel positions */
else if(duration == 3)
{
if(LocalTemp1>(SIZE_X-1))
LocalTemp1 = SIZE_X;
if(LocalTemp2>(SIZE_X-1))
LocalTemp2 = SIZE_X;
}
/*if data is valid data then plot else ignore*/
if((graphData[8][end]>MIN_ERROR)&&(graphData[8][end-1]<MAX_LOG10_ERROR_COUNT)&&(graphData[8][end-1]>MIN_ERROR)&&(graphData[8][end]<MAX_LOG10_ERROR_COUNT))
{
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end] == 0)
{
localPlotBuffer[0] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end])/(float)Y2_MAX_VALUE));
}
/*if data present is 0, log10(0) is not define so then plot this graph in normal scale */
if(graphData[8][end-1]== 0)
{
localPlotBuffer[1] = (int)((float)(SIZE_Y )*(float)(1 - (float)graphData[8][end-1]/(float)Y1_MAX_VALUE)) ;
}
else
{
localPlotBuffer[1] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graphData[8][end-1])/(float)Y2_MAX_VALUE));
}
g.drawLine((int)LocalTemp1,(localPlotBuffer[0]+5), (int)LocalTemp2,(localPlotBuffer[1]+5));
}
temp-=(double)5/(double)duration;
end--;
}
}
}
/******************************************************************************
*
* method - plot_timeelapsed_east
*
* This method uses graph_data_rf_east global variable and plots series of lines
* in the applet
*****************************************************************************/
void plot_timeelapsed_east(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
int x= 0;
localPlotBuffer = new int[2];
x= (duration*MAX_NUM_INTERVELL_PER_DAY);
g.setColor(plotColor9);
/*if data is valid data then plot else ignore*/
if((graph_data_rf_east>0)&&(graph_data_rf_east<MAX_LOG10_ERROR_COUNT))
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graph_data_rf_east)/(float)Y2_MAX_VALUE));
if(duration>5)
g.drawLine(x-1,SIZE_Y+5, x-2,(localPlotBuffer[0]+5));
else
g.drawLine(SIZE_X,SIZE_Y+5, 474+duration,(localPlotBuffer[0]+5));
}
}/*End for plot_timeelapsed_east() */
/******************************************************************************
*
* method - plot_timeelapsed_west
*
* This method uses graph_data_rf_east global variable and plots series of lines
* in the applet
*****************************************************************************/
void plot_timeelapsed_west(Graphics g)
{
int end = MAX_DATA_X;
int localPlotBuffer[];
int x= 0;
localPlotBuffer = new int[2];
x= (duration*MAX_NUM_INTERVELL_PER_DAY);
g.setColor(plotColor9);
/*if data is valid data then plot else ignore*/
if((graph_data_rf_east>MIN_ERROR)&&(graph_data_rf_east<MAX_LOG10_ERROR_COUNT))
{
localPlotBuffer[0] = (int)((float)(SIZE_Y1 )*(float)(1 - (float)Math.log10(graph_data_rf_west)/(float)Y2_MAX_VALUE));
if(duration>5)
g.drawLine(x-1,SIZE_Y+5, x-2,(localPlotBuffer[0]+5));
else
g.drawLine(SIZE_X,SIZE_Y+5, 474+duration,(localPlotBuffer[0]+5));
}
}
/******************************************************************************
*
* method - getData
*
* This method sends query to CGI to collect data. Then it converts the
* data for applet area then updates global variable.
*
* Inputs :
* serverAddress - server CGI path
*****************************************************************************/
public void getData(String serverAddress)
{
URL addr;
BufferedReader in;
String inputLine;
int count = 0;
int i=0,j = 0;
try
{
addr = new URL(serverAddress);
URLConnection connection = addr.openConnection();
in = new BufferedReader(new InputStreamReader(addr.openStream()));
/*Read data for first link */
for( j=0; j<MAX_DISP_PARMS_STD; j++)
{
for( i=0; i<MAX_DATA_X+1; i++)
{
inputLine = in.readLine();
graphData[j][i] = Integer.parseInt(inputLine);
}
}
for( i=0; i<MAX_DATA_X; i++)
{
inputLine = in.readLine();
graphData[7][i] = Integer.parseInt(inputLine);
if(graphData[7][i] == 1)
graphData[7][i] = 10;
}
inputLine = in.readLine();
graph_data_rf_east = Integer.parseInt(inputLine);
/*Reading data for second link */
if(Integer.parseInt(getParameter("mode")) == 2)
{
for( j=8; j<15; j++)
{
for( i=0; i<MAX_DATA_X+1; i++)
{
inputLine = in.readLine();
graphData[j][i] = Integer.parseInt(inputLine);
}
}
for( i=0; i<MAX_DATA_X; i++)
{
inputLine = in.readLine();
graphData[15][i] = Integer.parseInt(inputLine);
if(graphData[15][i] == 1)
graphData[15][i] = 10;
}
inputLine = in.readLine();
graph_data_rf_west = Integer.parseInt(inputLine);
}
in.close();
}catch (Exception e) { System.out.println("Server Data Read Error:"+e); }
}
/******************************************************************************
*
* method - itemStateChanged
*
* This method will be called whenever event occured on this choice.
* it read the current status and changes scale accordingly.
* *****************************************************************************/
public void itemStateChanged(ItemEvent evt)
{
if( evt.getSource() == timeChoice )
duration = Integer.parseInt(timeChoice.getSelectedItem());
else
viewMode = modeChoice.getSelectedIndex()+1;
repaint();
}
/******************************************************************************
*
* method - mouseMoved
*
* This method will be called whenever mouse cursor is moved over the
* applet. Depending on the cursor position, it will display Actual
* X and Y values of the graph.
*****************************************************************************/
public void mouseMoved(MouseEvent evt)
{
int x = evt.getX()-xOffset;
int y = evt.getY()-yOffset-5;
int a = evt.getX();
int b = evt.getY();
int duration = Integer.parseInt(timeChoice.getSelectedItem());
if( (x>=0) && (x<=SIZE_X) && (y>=0) && (y<=SIZE_Y) )
{
valueLabel1.setText("X ");
valueLabel2.setText("Y1 ");
valueLabel3.setText("Y2 ");
try
{
int x_max_value = ((SIZE_X*duration)/5);
int x1 = (int)((float)((float)((float)(SIZE_X*duration))/5) * ((float)((float)(SIZE_X - x))/((float)SIZE_X)));
/*For Durations less than 16 scale starts with 1*/
int y1 = (int)((float)Y1_MAX_VALUE * (((float)SIZE_Y - (float)y)/((float)SIZE_Y)));
int y2 = (int) Math.pow(10,((float)(3 * ((float)(1 - (float)y/((float)SIZE_Y1))))));
valueLabel1.setText("X="+x1);
valueLabel2.setText("X pix="+a);
valueLabel3.setText("Y="+y1);
valueLabel4.setText("Y pix="+b);
valueLabel5.setText("Y2="+y2);
}
catch(Exception e) {System.out.println("Mouse Moved Error" + e);}
}
else
{
valueLabel1.setText(" ");
valueLabel2.setText(" ");
valueLabel3.setText(" ");
}
}
public void mouseDragged(MouseEvent evt) { }
}

There are many ways to do this. Here are two:
You can simply scale the values: Multiply every coordinate with the zoom factor.
Use Java2D and AffineTransform:
AffineTransform transformer = new AffineTransform();
transformer.scale(zoom, zoom);
Graphics2D g2d = (Graphics2D)g;
g2d.setTransform(transformer);
// draw to g2d.
[EDIT] If you want to do everything yourself, see this page for a refresh of basic linear algebra: 2D Transformations
Don't mind the 3D example at the top; the rest of the page is about 2D.

I used JCC kit for my target platform and it's less than 100kb library. You need to understand the library and after that you can play without worrying about size. :)
Good library to use in embedded systems whether size is always the issue. it has inbuilt function o transform coordinates into screen coordinates and vice-verse.

Related

Grid line collision checking

Lately I've been working on a grid line detection system, I know that there was an algorithm out there that did excactly what I wanted it to do, but I'm that kind of person who wants to make stuff themselves. ;)
So I've had some succes when checking with 1 line, but now that I use a grid of 20x20 to check the lines it doesn't work anymore.
The problem is found somewhere in the collision class I made for this system.
Somehow the numbers get out of the grid array and I don't know why
here is the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
*
* beschrijving
*
* #version 1.0 van 22-6-2016
* #author
*/
public class gridline extends JApplet {
// Begin variabelen
int[][] grid = new int[20][20];
int[] light = new int[2];
int[][] line = new int[2][2];
// Einde variabelen
public void init() {
Container cp = getContentPane();
cp.setLayout(null);
cp.setBounds(0, 0, 600, 600);
// Begin componenten
for (int a=0; a<20; a++) {
for (int b=0; b<20; b++) {
grid[a][b] = (int) (Math.random()*10);
} // end of for
} // end of for
line[0][0] = (int) (Math.random()*20);
line[0][1] = (int) (Math.random()*20);
line[1][0] = (int) (Math.random()*20);
line[1][1] = (int) (Math.random()*20);
light[0] = (int) (Math.random()*20);
light[1] = (int) (Math.random()*20);
// Einde componenten
} // end of init
//Custom classes
private boolean collide(int x1, int y1,int x2, int y2) {
boolean collide = true;
int tempx = x1 - x2;
int tempy = y1 - y2;
int sx = 0;
int sy = 0;
int x = 0;
int y = 0;
if (tempx == 0) {
tempx = 1;
sx = 1;
} // end of if
if (tempy == 0) {
tempy = 1;
sy = 1;
} // end of if
if (sx == 0) {
x = tempx + tempx/Math.abs(tempx);
} // end of if
else {
x = tempx;
} // end of if-else
if (sy == 0) {
y = tempy + tempy/Math.abs(tempy);
} // end of if
else {
y = tempy;
} // end of if-else
int absx = Math.abs(x);
int absy = Math.abs(y);
int nex = x/absx;
int ney = y/absy;
int off = 0;
float count = 0;
float step = 0;
if (absx != absy) {
if (absx == Math.min(absx,absy)) {
step = (float) absx/absy;
calc1: for (int a=0; a<absy; a++) {
count += step;
if (count > 1 && x1+off != x2) {
count -= 1;
off += nex;
} // end of if
if (grid[x1+off][y1+a*ney] == 9) {
collide = false;
break calc1;
} // end of if
} // end of for
} // end of if
else{
step = (float) absy/absx;
calc2: for (int a=0; a<absx; a++) {
count += step;
if (count > 1 && y1+off != y2) {
count -= 1;
off += ney;
} // end of if
if (grid[x1+a*nex][y1+off] == 9) {
collide = false;
break calc2;
} // end of if
} // end of for
}
} // end of if
else {
calc3: for (int a=0; a<absx; a++) {
if (grid[x1+a*nex][y1+a*ney] == 9) {
collide = false;
break calc3;
} // end of if
} // end of for
} // end of if-else
return collide;
}
private int length(int x1, int y1, int x2, int y2) {
double distance = Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
return (int) distance;
}
// Begin eventmethoden
public void paint (Graphics g){
boolean draw = true;
Color col;
for (int a=0; a<20; a++) {
for (int b=0; b<20; b++) {
draw = collide(a,b,light[0],light[1]);
if (draw) {
int len = Math.max(255-length(a*30+15,b*30+15,light[0]*30+15,light[1]*30+15),0);
col = new Color(len,len,len);
g.setColor(col);
g.fillRect(a*30,b*30,30,30);
} // end of if
else{
col = new Color(0,0,0);
g.setColor(col);
g.fillRect(a*30,b*30,30,30);
}
} // end of for
} // end of for
}
// Einde eventmethoden
} // end of class gridline
I'll understand it if nobody wants to look through a code as big as this, but it could be helpful for your own projects and I'm completely okay with it if you copy and paste my code for your projects.
Many thanks in advace.

Poser Mesh with openGL 1.0, 50 % of Triangles seem to miss

I generated a 3D model with Poser to use it with openGL 1.0 in a Android Application. When I render the mesh I can see the 3D Model as generated in Poser 8, but unfortunately only half of the triangles are rendered - it look like I have to draw some kind of squares instead. Is there any method to mirror the existing triangles so I can draw the missing ones?
My mesh is generated from a wavefront object. Therefor I use a class called Mesh
public final class Mesh {
public enum PrimitiveType {
Points,
Lines,
Triangles,
LineStrip,
TriangleStrip,
TriangleFan
}
// gl instance
private GL10 gl;
// vertex position buffer, array
private float vertices[];
private int vertexHandle;
private FloatBuffer vertexBuffer;
// color buffer, array
private float colors[];
private int colorHandle;
private FloatBuffer colorBuffer;
// texture coordinate buffer, array
private float texCoords[];
private int texHandle;
private FloatBuffer texBuffer;
// normal (for illumination) buffer, array
private float normals[];
private int normalHandle;
private FloatBuffer normalBuffer;
// index where next vertices will be inserted
private int index = 0;
// number vertices for mesh
private int numVertices = 0;
// renderer support vbos
private boolean globalVBO = true;
// is mesh dirty
private boolean dirty = true;
// last mesh
private static Mesh lastMesh;
// mesh count
public static int numMeshes = 0;
/**
* after calling constructor first set attribute (color, texture, normal), then fix the vertex by calling vertex(...)
*
* #param gl GL10
* #param numVertices number vertices of mesh
* #param hasColors using colors?
* #param hasTextureCoordinates using textures coordinates
* #param hasNormals using normals?
*/
public Mesh(GL10 gl, int numVertices, boolean hasColors, boolean hasTextureCoordinates, boolean hasNormals) {
this.gl = gl;
vertices = new float[numVertices * 3];
int[] buffer = new int[1];
if (!globalVBO) {
vertexBuffer = allocateBuffer(numVertices * 3);
} else {
((GL11) gl).glGenBuffers(1, buffer, 0);
vertexHandle = buffer[0];
vertexBuffer = FloatBuffer.wrap(vertices);
}
if (hasColors) {
colors = new float[numVertices * 4];
if (!globalVBO) {
colorBuffer = allocateBuffer(numVertices * 3);
} else {
((GL11) gl).glGenBuffers(1, buffer, 0);
colorHandle = buffer[0];
colorBuffer = FloatBuffer.wrap(colors);
}
}
if (hasTextureCoordinates) {
texCoords = new float[numVertices * 2];
if (!globalVBO) {
texBuffer = allocateBuffer(numVertices * 3);
} else {
((GL11) gl).glGenBuffers(1, buffer, 0);
texHandle = buffer[0];
texBuffer = FloatBuffer.wrap(texCoords);
}
}
if (hasNormals) {
normals = new float[numVertices * 3];
if (!globalVBO) {
normalBuffer = allocateBuffer(numVertices * 3);
} else {
((GL11) gl).glGenBuffers(1, buffer, 0);
normalHandle = buffer[0];
normalBuffer = FloatBuffer.wrap(normals);
}
}
}
/**
* allocates FloatBuffer of size
*
* #param size size number of floats
* #return FloatBuffer
*/
private FloatBuffer allocateBuffer(int size) {
ByteBuffer buffer = ByteBuffer.allocateDirect(size * 4);
buffer.order(ByteOrder.nativeOrder());
return buffer.asFloatBuffer();
}
/**
* renders mesh given type, starts at offset wirh numVertices vertices
*
* #param type PrimitiveType (see above)
* #param offset offset in number of vertices
* #param numVertices number of vertices to use
*/
public void render(PrimitiveType type, int offset, int numVertices) {
boolean wasDirty = dirty;
if (dirty) {
update();
}
if (this == lastMesh && !wasDirty) {
gl.glDrawArrays(getPrimitiveType(type), offset, numVertices);
return;
} else {
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
if (globalVBO) {
((GL11) gl).glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexHandle);
((GL11) gl).glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
} else {
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
}
if (colors != null) {
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
if (globalVBO) {
((GL11) gl).glBindBuffer(GL11.GL_ARRAY_BUFFER, colorHandle);
((GL11) gl).glColorPointer(4, GL10.GL_FLOAT, 0, 0);
} else
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
}
if (texCoords != null) {
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
if (globalVBO) {
((GL11) gl).glBindBuffer(GL11.GL_ARRAY_BUFFER, texHandle);
((GL11) gl).glTexCoordPointer(2, GL10.GL_FLOAT, 0, 0);
} else
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer);
}
if (normals != null) {
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
if (globalVBO) {
((GL11) gl).glBindBuffer(GL11.GL_ARRAY_BUFFER, normalHandle);
((GL11) gl).glNormalPointer(GL10.GL_FLOAT, 0, 0);
} else
gl.glNormalPointer(GL10.GL_FLOAT, 0, normalBuffer);
}
gl.glDrawArrays(getPrimitiveType(type), offset, numVertices);
lastMesh = this;
}
/**
* renders mesh as given type with numVertices from calling vertex()
*
* #param type PrimitveType
*/
public void render(PrimitiveType type) {
render(type, 0, numVertices);
}
/**
* returns openGL constant of PrimitiveType
*
* #param type PrimitiveType (enum above)
* #return openGL constant
*/
private int getPrimitiveType(PrimitiveType type) {
if (type == PrimitiveType.Lines) {
return GL10.GL_LINES;
} else if (type == PrimitiveType.Triangles) {
return GL10.GL_TRIANGLES;
} else if (type == PrimitiveType.LineStrip) {
return GL10.GL_LINE_STRIP;
} else if (type == PrimitiveType.TriangleStrip) {
return GL10.GL_TRIANGLE_STRIP;
} else if (type == PrimitiveType.Points) {
return GL10.GL_POINTS;
} else {
return GL10.GL_TRIANGLE_FAN;
}
}
/**
* updates the direct buffers in case the user
*/
private void update() {
if (!globalVBO) {
vertexBuffer.put(vertices);
vertexBuffer.position(0);
if (colors != null) {
colorBuffer.put(colors);
colorBuffer.position(0);
}
if (texCoords != null) {
texBuffer.put(texCoords);
texBuffer.position(0);
}
if (normals != null) {
normalBuffer.put(normals);
normalBuffer.position(0);
}
} else {
GL11 gl = (GL11) this.gl;
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, vertexHandle);
gl.glBufferData(GL11.GL_ARRAY_BUFFER, vertices.length * 4, vertexBuffer, GL11.GL_DYNAMIC_DRAW);
if (colors != null) {
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, colorHandle);
gl.glBufferData(GL11.GL_ARRAY_BUFFER, colors.length * 4, colorBuffer, GL11.GL_DYNAMIC_DRAW);
}
if (normals != null) {
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, normalHandle);
gl.glBufferData(GL11.GL_ARRAY_BUFFER, normals.length * 4, normalBuffer, GL11.GL_DYNAMIC_DRAW);
}
if (texCoords != null) {
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, texHandle);
gl.glBufferData(GL11.GL_ARRAY_BUFFER, texCoords.length * 4, texBuffer, GL11.GL_DYNAMIC_DRAW);
}
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
}
numVertices = index;
index = 0;
dirty = false;
}
/**
* defines position of current vertex, before calling call method like color, normal or texCoord
*
* #param x x coordinate
* #param y y coordinate
* #param z z coordinate
*/
public void vertex(float x, float y, float z) {
dirty = true;
int offset = index * 3;
vertices[offset] = x;
vertices[offset + 1] = y;
vertices[offset + 2] = z;
index++;
}
/**
* sets color of current vertex
*
* #param r red
* #param g green
* #param b blue
* #param a alpha
*/
public void color(float r, float g, float b, float a) {
dirty = true;
int offset = index * 4;
colors[offset] = r;
colors[offset + 1] = g;
colors[offset + 2] = b;
colors[offset + 3] = a;
}
/**
* sets the normal of current vertex
*
* #param x x components
* #param y y components
* #param z z components
*/
public void normal(float x, float y, float z) {
dirty = true;
int offset = index * 3;
normals[offset] = x;
normals[offset + 1] = y;
normals[offset + 2] = z;
}
/**
* sets texture coordinates of current vertex
*
* #param s s coordinate (correlates x)
* #param t t coordinate (correlates y)
*/
public void texCoord(float s, float t) {
dirty = true;
int offset = index * 2;
texCoords[offset] = s;
texCoords[offset + 1] = t;
}
/**
* deletes all buffers, sets all attributes to null
*/
public void dispose() {
if (globalVBO) {
GL11 gl = (GL11) this.gl;
if (vertexHandle != -1)
gl.glDeleteBuffers(1, new int[]{vertexHandle}, 0);
if (colorHandle != -1)
gl.glDeleteBuffers(1, new int[]{colorHandle}, 0);
if (normalHandle != -1)
gl.glDeleteBuffers(1, new int[]{normalHandle}, 0);
if (texHandle != -1)
gl.glDeleteBuffers(1, new int[]{texHandle}, 0);
}
vertices = null;
vertexBuffer = null;
colors = null;
colorBuffer = null;
normals = null;
normalBuffer = null;
texCoords = null;
texBuffer = null;
numMeshes--;
}
/**
* #return number of vertices
*/
public int getMaximumVertices() {
return vertices.length / 3;
}
/**
* resets index
*/
public void reset() {
dirty = true;
index = 0;
}
}
and a class called MeshLoader
public class MeshLoader {
/**
*
* Loads a mesh from the given InputStream
* #param gl GL10 instance
* #return The mesh
*/
public static Mesh loadObj( GL10 gl, InputStream in )
{
String line = "";
try
{
BufferedReader reader = new BufferedReader( new InputStreamReader(in) );
StringBuffer b = new StringBuffer();
String l = reader.readLine();
while( l != null )
{
b.append( l );
b.append( "\n" );
l = reader.readLine();
}
line = b.toString();
reader.close();
}
catch( Exception ex )
{
throw new RuntimeException(ex.getMessage() + " " +
"couldn't load file mesh from input stream" );
}
return loadObjFromString( gl, line );
}
/**
* Loads a mesh from the given string in obj format
*
* #param obj The string
* #return The Mesh
*/
public static Mesh loadObjFromString( GL10 gl, String obj )
{
String[] lines = obj.split( "\n" );
float[] vertices = new float[lines.length * 3];
float[] normals = new float[lines.length * 3];
float[] uv = new float[lines.length * 3];
int numVertices = 0;
int numNormals = 0;
int numUV = 0;
int numFaces = 0;
int[] facesVerts = new int[lines.length * 3];
int[] facesNormals = new int[lines.length * 3];
int[] facesUV = new int[lines.length * 3];
int vertexIndex = 0;
int normalIndex = 0;
int uvIndex = 0;
int faceIndex = 0;
for( int i = 0; i < lines.length; i++ )
{
String line = lines[i];
if( line.startsWith( "v " ) )
{
String[] tokens = line.split( " " );
vertices[vertexIndex] = Float.parseFloat(tokens[1]);
vertices[vertexIndex+1] = Float.parseFloat(tokens[2]);
vertices[vertexIndex+2] = Float.parseFloat(tokens[3]);
vertexIndex += 3;
numVertices++;
continue;
}
if( line.startsWith( "vn " ) )
{
String[] tokens = line.split( " " );
normals[normalIndex] = Float.parseFloat(tokens[1]);
normals[normalIndex+1] = Float.parseFloat(tokens[2]);
normals[normalIndex+2] = Float.parseFloat(tokens[3]);
normalIndex += 3;
numNormals++;
continue;
}
// coords of each texture point
if( line.startsWith( "vt" ) )
{
String[] tokens = line.split( " " );
uv[uvIndex] = Float.parseFloat(tokens[1]);
uv[uvIndex+1] = Float.parseFloat(tokens[2]);
uvIndex += 2;
numUV++;
continue;
}
if( line.startsWith( "f " ) )
{
String[] tokens = line.split( " " );
String[] parts = tokens[1].split("/");
facesVerts[faceIndex] = getIndex(parts[0], numVertices);
facesNormals[faceIndex] = getIndex(parts[2], numNormals);
facesUV[faceIndex] = getIndex(parts[1], numUV);
faceIndex++;
parts = tokens[2].split("/");
facesVerts[faceIndex] = getIndex(parts[0], numVertices);
facesNormals[faceIndex] = getIndex(parts[2], numNormals);
facesUV[faceIndex] = getIndex(parts[1], numUV);
faceIndex++;
parts = tokens[3].split("/");
facesVerts[faceIndex] = getIndex(parts[0], numVertices);
facesNormals[faceIndex] = getIndex(parts[2], numNormals);
facesUV[faceIndex] = getIndex(parts[1], numUV);
faceIndex++;
numFaces++;
continue;
}
}
Mesh mesh = new Mesh(gl, numFaces * 3, false ,numUV > 0, numNormals > 0 );
for( int i = 0; i < numFaces*3; i++ )
{
if( numNormals > 0 )
{
int normalIdx = facesNormals[i] * 3;
mesh.normal( normals[normalIdx], normals[normalIdx+1], normals[normalIdx+2] );
}
if( numUV > 0 )
{
int uvIdx = facesUV[i] * 2;
mesh.texCoord( uv[uvIdx], uv[uvIdx+1]);
}
int vertexIdx = facesVerts[i] *3;
mesh.vertex( vertices[vertexIdx], vertices[vertexIdx+1], vertices[vertexIdx+2] );
}
return mesh;
}
private static int getIndex( String index, int size )
{
if( index == null || index.length() == 0 )
return 0;
int idx = Integer.parseInt( index );
if( idx < 0 )
return size + idx;
else
return idx - 1;
}
}
every 3D Object is a Mesh and will be generated by the MeshLoader.loadObject Method.
This works perfectly with simple Objects. But not with 3D Models generated by Poser 8.
Does anyone have an idea, how to solve this problem?
I solved it.
I triangulated the Mesh and reduced the number of vertices under 32.000. Therefor I exported the Mesh from Poser as Collada-File and imported it to Blender (because there are more tutorials :D).

AndEngine: Getting a NullPointerException on UpdateThread when adding a Sprite

Getting a NullPointerException on UpdateThread when adding a Sprite
I'm creating my first game in AndEngine and I am simply trying to add a Sprite to my GameScene class. I've been tinkering with it for hours now as my application kept crashing after my splash screen, which is supposed to load my GameScene afterwards. I've narrowed it down to these of code in my drawPanel() method:
selectPanel[0] = new Sprite(0, 0, resourceManager.ballTextureRegionArray[0], vbom) {
#Override
protected void preDraw(GLState pGLState, Camera pCamera) {
super.preDraw(pGLState, pCamera);
pGLState.enableDither();
}
};
selectPanel[0].setPosition(240, 400);
attachChild(selectPanel[0]);
Here is my ResourceManager class where I loaded the ball texture:
ballTexture = new BitmapTextureAtlas(act.getTextureManager(), 64, 576);
ballTextureRegionArray[0] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "red_ball.png", 0, 0);
ballTextureRegionArray[1] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "blue_ball.png", 0, 64);
ballTextureRegionArray[2] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "green_ball.png", 0, 128);
ballTextureRegionArray[3] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "purple_ball.png", 0, 192);
ballTextureRegionArray[4] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "yellow_ball.png", 0, 256);
ballTextureRegionArray[5] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "orange_ball.png", 0, 320);
ballTextureRegionArray[6] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "black_ball.png", 0, 384);
ballTextureRegionArray[7] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "white_ball.png", 0, 448);
ballTextureRegionArray[8] = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(ballTexture, act, "select_ball.png", 0, 512);
ballTexture.load(); // load ballTexture to the scene
... and of course the error.
11-28 17:44:44.750: E/AndroidRuntime(2119): FATAL EXCEPTION: UpdateThread
11-28 17:44:44.750: E/AndroidRuntime(2119): java.lang.NullPointerException
11-28 17:44:44.750: E/AndroidRuntime(2119): at com.eklypze.android.mastermdhd.GameScene.drawPanel(GameScene.java:188)
11-28 17:44:44.750: E/AndroidRuntime(2119): at com.eklypze.android.mastermdhd.GameScene.createScene(GameScene.java:68)
11-28 17:44:44.750: E/AndroidRuntime(2119): at com.eklypze.android.mastermdhd.BaseScene.<init>(BaseScene.java:38)
11-28 17:44:44.750: E/AndroidRuntime(2119): at com.eklypze.android.mastermdhd.GameScene.<init>(GameScene.java:28)
11-28 17:44:44.750: E/AndroidRuntime(2119): at com.eklypze.android.mastermdhd.SceneManager.createGameScene(SceneManager.java:120)
11-28 17:44:44.750: E/AndroidRuntime(2119): at com.eklypze.android.mastermdhd.BaseActivity$1.onTimePassed(BaseActivity.java:84)
11-28 17:44:44.750: E/AndroidRuntime(2119): at org.andengine.engine.handler.timer.TimerHandler.onUpdate(TimerHandler.java:94)
11-28 17:44:44.750: E/AndroidRuntime(2119): at org.andengine.engine.handler.UpdateHandlerList.onUpdate(UpdateHandlerList.java:47)
11-28 17:44:44.750: E/AndroidRuntime(2119): at org.andengine.engine.Engine.onUpdateUpdateHandlers(Engine.java:618)
11-28 17:44:44.750: E/AndroidRuntime(2119): at org.andengine.engine.Engine.onUpdate(Engine.java:605)
11-28 17:44:44.750: E/AndroidRuntime(2119): at org.andengine.engine.Engine.onTickUpdate(Engine.java:568)
11-28 17:44:44.750: E/AndroidRuntime(2119): at org.andengine.engine.Engine$UpdateThread.run(Engine.java:858)
Here is my GameScene.java class:
package com.eklypze.android.mastermdhd;
import java.util.Random;
import javax.microedition.khronos.opengles.GL10;
import org.andengine.engine.camera.Camera;
import org.andengine.entity.modifier.AlphaModifier;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.util.GLState;
import android.util.Log;
import com.eklypze.android.mastermdhd.SceneManager.SceneType;
public class GameScene extends BaseScene {
/*** DECLARATIONS ***/
/* Settings */
protected static final int CAMERA_WIDTH = 480;
protected static final int CAMERA_HEIGHT = 800;
/* Sprites */
Sprite[] selectPanel = new Sprite[8];
Sprite boardPieces[] = new Sprite[40];
Sprite bwPegs[] = new Sprite[10];
Sprite nextSpot; // "next spot" cursor
Sprite gameoverLose, gameoverWin; // REPLACE with scenes
/* Game Options */
private int turn = 0;
private int turnCounter = 0; // per line turn counter
private int currentX = 1;
private int currentY = 13;
private int[] code = new int[4]; // array to store generated code
private int[] codeCopy = new int[4]; // for black&white peg use
private int blackPegs = 0, whitePegs = 0;
// remember to take currentX-1 as the array indexes
private int[] currentXValues = new int[4];
// dummy variable when drawing selectPanel for touch *don't delete*
private int z = 0;
Boolean gameOver = false;
Boolean doublesAllowed = false;
/************************************
* ------------INHERITED------------
************************************/
#Override
/********************************
* createScene()
********************************/
public void createScene() {
// create scene with bgSprite background
setBackground(new SpriteBackground(resourceManager.bgSprite));
// STEP 1: Start a New Game
newGame();
// STEP 2: Draw selectPanel
drawPanel(); // debugging: game seems to work up until this point
}
#Override
/********************************
* onBackKeyPressed()
********************************/
public void onBackKeyPressed() {
System.exit(0);
}
#Override
/********************************
* getSceneType()
********************************/
public SceneType getSceneType() {
return SceneType.SCENE_GAME;
}
#Override
/********************************
* disposeScene()
********************************/
public void disposeScene() {
this.detachSelf();
this.dispose();
}
/************************************
* -----------GAME METHODS-----------
************************************/
/********************************
* newGame()
* Description: Initialize game
* settings for a new session.
********************************/
private void newGame() {
/* [START] Generate New Code Combination
for (int x = 0; x < 4; x++) {
Random r = new Random();
// if doubles is not allowed check if new generated number is
// a double, if yes, generate another number. NOTE: doubles are
// defaulted to 'OFF' until feature is added.
int randomNumber = r.nextInt(8); // why (7-0)+0?
Log.v("randomR", "Number generated is " + randomNumber);
code[x] = randomNumber;
// write to log (debugging)
Log.v("theCode", "Number generated for " + x + " is: " + code[x]
+ " (" + resourceManager.ballColours[randomNumber] + ")");
// if doubles is not allowed check if new generated number is
// a double, if yes, generate another number. NOTE: doubles are
// defaulted to 'OFF' until feature is added.
if (!doublesAllowed && x > 0) {
for (int y = x - 1; y >= 0; y--) {
// Log.v("theY", "y is "+y);
if (code[y] == randomNumber) {
x--;
}
}
}
} [END] Generate New Code Combination */
code = new int[] { 7, 1, 2, 3 };
Log.v("theCode", "The Code Is: " + code[0] + "," + code[1] + ","
+ code[2] + "," + code[3] + ".");
codeCopy = code.clone(); // copies code array for white/black peg use
}
/********************************
* drawPanel()
* Description: Draw the panels
* required for user selection.
********************************/
private void drawPanel() {
int column = 7; // constant?
int rowStart = 2;
/* [START] Draw Selection selectPanel
for (int i = 0; i < 8; i++) {
final int j = i;
selectPanel[i] = new Sprite(grid_xPixel(column),
grid_yPixel(rowStart),
resourceManager.ballTextureRegionArray[i], vbom) {
#Override
/* [START] Touch Detection
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
switch (pSceneTouchEvent.getAction()) {
// On Touch
case TouchEvent.ACTION_DOWN:
this.setScale(2.0f); // enlarge effect
z = j;
Log.v("thisIsZ", "Z: " + z);
break;
// On Move/Drag
case TouchEvent.ACTION_MOVE: {
/* to be implemented in the future
// this.setPosition(pSceneTouchEvent.getX() -
// this.getWidth()/2, pSceneTouchEvent.getY() -
// this.getHeight()/2);
break;
}
// On Release
case TouchEvent.ACTION_UP:
// z = j; // not needed
makeMove(z);
this.setScale(1.0f); // normal size
break;
}
return super.onAreaTouched(pSceneTouchEvent,
pTouchAreaLocalX, pTouchAreaLocalY);
}
[END] Touch Detection
}; */
// selectPanel[0] = new Sprite(200, 400,
// resourceManager.ballTextureRegionArray[0], vbom);
//attachChild(selectPanel[0]);
//registerTouchArea(selectPanel[i]);
selectPanel[0] = new Sprite(0, 0, resourceManager.ballTextureRegionArray[0], vbom) {
#Override
protected void preDraw(GLState pGLState, Camera pCamera) {
super.preDraw(pGLState, pCamera);
pGLState.enableDither();
}
};
selectPanel[0].setPosition(240, 400);
attachChild(selectPanel[0]);
//} /* [END] Draw Selection selectPanel */
// setTouchAreaBindingOnActionDownEnabled(true);
}
/********************************
* makeMove()
* Description: Allow the player
* to make their selection and
* display pegs as a result.
********************************/
private void makeMove(int inColor) {
boardPieces[turn] = new Sprite(grid_xPixel(currentX),
grid_yPixelBoard(currentY),
resourceManager.ballTextureRegionArray[inColor], vbom);
boardPieces[turn].setScale(0.75f); // set 75% size on board
// store current line, compare values to code and generate B/W pegs
currentXValues[currentX - 1] = inColor;
if (currentXValues[currentX - 1] == codeCopy[currentX - 1]) {
blackPegs++;
// dummy variable so this isn't counted again as a white peg
codeCopy[currentX - 1] = 999;
}
for (int i = 0; i < 4; i++) {
if ((currentXValues[currentX - 1] == codeCopy[i])) {
whitePegs++;
// dummy variable so this isn't counted again as a white peg
codeCopy[i] = 999;
}
}
/* log for debugging */
Log.v("pegs", "blackPegs: " + blackPegs);
Log.v("pegs", "whitePegs: " + whitePegs);
// Draw pieces to scene and advance to next turn & column
attachChild(boardPieces[turn]);
currentX++;
turn++;
// advance to next row, draw B/W pegs
if (currentX > 4) {
currentX = 1;
currentY--;
// Draw Pegs
drawBWPegs(blackPegs, whitePegs);
turnCounter++;
// Reset pegs for next line
blackPegs = 0;
whitePegs = 0;
// codeCopy is only used for counting black and white
// pegs per line to ensure all cases work
codeCopy = code.clone();
}
/* [START] Draw Blinking Cursor in Next Spot */
nextSpot = new Sprite(grid_xPixel(currentX),
grid_yPixelBoard(currentY),
resourceManager.ballTextureRegionArray[8], vbom);
nextSpot.setScale(0.75f);
nextSpot.setBlendFunction(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
nextSpot.registerEntityModifier(new LoopEntityModifier(
new AlphaModifier(2, 0f, 1.0f)));
attachChild(nextSpot);
/* [END] Draw Blinking Cursor in Next Spot */
/* *
* GAME OVER (LOSE)
* If player reaches turn 40 and still has not received
* correct code, go to Game Over (Lose) scene.
* */
if (turn == 40) {
// NOTE: I will replace this with a Game Over scene.
GameOverWin(false);
Log.v("Game Over", "You Lose");
gameoverLose = new Sprite(CAMERA_WIDTH / 2 - 256,
CAMERA_HEIGHT / 2 - 64, resourceManager.loseTextureRegion,
vbom);
attachChild(gameoverLose);
}
}
/********************************
* GameOverWin()
* Description: Display GameOver
* image as a result of the user
* winning the game.
********************************/
private void GameOverWin(boolean win) {
// clear game
detachChildren();
turn = 0;
}
/********************************
* drawBWPegs()
* Description: Draw the black
* and white pegs to the scene
* based on game results.
********************************/
private void drawBWPegs(int numBlack, int numWhite) {
/* [START] if */
// do not display if no pegs were counted
if (numBlack > 0 || numWhite > 0) {
int pegScore = 0;
// determine pegScore
if (numBlack == 1 && numWhite == 0) {
pegScore = 0;
} else if (numBlack == 1 && numWhite == 2) {
pegScore = 1;
} else if (numBlack == 1 && numWhite == 3) {
pegScore = 2;
} else if (numBlack == 0 && numWhite == 1) {
pegScore = 3;
} else if (numBlack == 2 && numWhite == 0) {
pegScore = 4;
} else if (numBlack == 2 && numWhite == 2) {
pegScore = 5;
} else if (numBlack == 0 && numWhite == 2) {
pegScore = 6;
} else if (numBlack == 3 && numWhite == 0) {
pegScore = 7;
} else if (numBlack == 3 && numWhite == 1) {
pegScore = 8;
} else if (numBlack == 0 && numWhite == 3) {
pegScore = 9;
} else if (numBlack == 4 && numWhite == 0) {
pegScore = 10;
} else if (numBlack == 0 && numWhite == 4) {
pegScore = 11;
} /* [END] if */
// use pegScore to display corresponding image
bwPegs[turnCounter] = new Sprite(grid_xPixel(5),
grid_yPixelBoard(currentY + 1),
resourceManager.pegTextureRegionArray[pegScore], vbom);
bwPegs[turnCounter].setScale(0.80f);
attachChild(bwPegs[turnCounter]);
}
}
/********************************
* ---------GRID SYSTEM---------
********************************/
/************************************
* grid_xPixel()
* Description: Converts grid
* coordinates to pixel coordinates
* based on a 480 by 800 resolution
* screen. Needs to be updated.
************************************/
private int grid_xPixel(int x) {
int pixel = 0;
pixel = x * (CAMERA_WIDTH / 8 + 2) - 32;
return pixel;
}
/************************************
* grid_yPixel()
* Description: Y-grid for user
* selection panel.
************************************/
private int grid_yPixel(int y) {
int pixel = 0;
pixel = y * (CAMERA_HEIGHT / 10) - 32;
return pixel;
}
/************************************
* grid_yPixelBoard()
* Description: Y-grid for the main
* game board.
************************************/
private int grid_yPixelBoard(int y) {
int pixel = 0;
pixel = y * (CAMERA_HEIGHT / 15) - 32;
return pixel;
}
}
I apologize as I'm also new to StackOverflow and don't quite know how to format code properly. Also, if I'm missing important areas of code that are relevant to the question please let me know as I have so many lines of code and don't quite know where to start.
Thanks in advance!
Looking at your code I'd say that ballTextureRegionArray[0] was the null pointer, probably because it wasn't loaded in your resourceManager initialisation.
If your .png files are resources i.e. in the "res" directory not the "asset" directory you need to load with .createFromResource not .createFromAsset.

Thread.sleep(x) doesnt do what it has to do [duplicate]

This question already has answers here:
java thread.sleep puts swing ui to sleep too
(3 answers)
Closed 9 years ago.
I programmed a code for a cube which can be turned on all pivots.
Now I tried to put in a loop with Thread.sleep but each time it repaints it just gives me the half cube or nothing (it's kinda flickering and faltering).
Maybe it doesn't work because my laptop is too slow but I don't think that this is the case.
Here's the code:
import java.awt.*;
import javax.swing.*;
public class Würfel1 extends JApplet {
Container container;
Dimension Screen = new Dimension(400,400);
double c[] = new double[8];
double wx = 90; double wy = 90; double wz = 90;
public Würfel1() {
init();
}
public void init() {
this.setSize(Screen);
container = this.getContentPane();
}
public void paint(Graphics g) {
super.paint(g);
drawcube(g);
wx = wx - 2;
wy = wy + 1;
wz = wz + 3;
try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}
repaint();
}
private void drawcube(Graphics g) {
/*
* Punkt links oben vorne
*/
int xStart = 100;
int yStart = 100;
/*
* Breite, Höhe und Länge des Körpers
*/
int b = 200;
int h = 200;
int l = 200;
/*
* Winkel der X-, Y- und Z-Achse des Körpers
*/
// int wx = 90;
// int wy = 90;
// int wz = 90;
/*
* Mittelpunkt des Körpers
*/
int x = xStart + b/2;
int y = yStart + h/2;
/*
* erzeugt die Grundwerte für den Winkel 90,90,90
*/
double xfield[] = {(-b/2),(b/2),(b/2),(-b/2),(-b/2),(b/2),(b/2),(-b/2)};
double yfield[] = {(-h/2),(-h/2),(h/2),(h/2),(-h/2),(-h/2),(h/2),(h/2)};
double zfield[] = {(l/2),(l/2),(l/2),(l/2),(-l/2),(-l/2),(-l/2),(-l/2)};
/*
* verändert die Werte unter Berücksichtigung der Winkel
*/
for (int i = 0; i < 8; i++)
{
double newx,newy,newz;
newy = yfield[i] * Math.cos(Math.PI*(90-wx)/180) - zfield[i] * Math.sin(Math.PI*(90-wx)/180);
newz = yfield[i] * Math.sin(Math.PI*(90-wx)/180) + zfield[i] * Math.cos(Math.PI*(90-wx)/180);
yfield[i] = newy;
zfield[i] = newz;
newx = xfield[i] * Math.cos(Math.PI*(90-wy)/180) - zfield[i] * Math.sin(Math.PI*(90-wy)/180);
newz = xfield[i] * Math.sin(Math.PI*(90-wy)/180) + zfield[i] * Math.cos(Math.PI*(90-wy)/180);
xfield[i] = newx;
zfield[i] = newz;
newx = xfield[i] * Math.cos(Math.PI*(90-wz)/180) - yfield[i] * Math.sin(Math.PI*(90-wz)/180);
newy = xfield[i] * Math.sin(Math.PI*(90-wz)/180) + yfield[i] * Math.cos(Math.PI*(90-wz)/180);
xfield[i] = newx;
yfield[i] = newy;
}
for (int i = 0; i < 8; i++) {
c[i] = 1;
}
/*
* Malt die Linien des Körpers
*/
DrawPolygon(0,1,2,3,xfield,yfield,x,y,g,1);
DrawPolygon(6,5,4,7,xfield,yfield,x,y,g,2);
DrawPolygon(5,1,0,4,xfield,yfield,x,y,g,3);
DrawPolygon(3,2,6,7,xfield,yfield,x,y,g,4);
DrawPolygon(2,1,5,6,xfield,yfield,x,y,g,5);
DrawPolygon(4,0,3,7,xfield,yfield,x,y,g,6);
}
public void DrawPolygon(int a, int s, int d, int f, double[] xfield, double yfield[],int b,int h,Graphics g,int c) {
if((xfield[a] - xfield[s]) * (yfield[d] - yfield[s])
- (yfield[a] - yfield[s]) * (xfield[d] - xfield[s]) > 0) {
// |j->i x j->k| > 0
int xCoords[] = {(int)(xfield[a])+b,(int)(xfield[s])+b,
(int)(xfield[d])+b,(int)(xfield[f])+b};
int yCoords[] = {(int)(yfield[a])+h,(int)(yfield[s])+h,
(int)(yfield[d])+h,(int)(yfield[f])+h};
Color color = new Color(0,0,0);
if (c == 1) color = new Color(255,0,0);
if (c == 2) color = new Color(255,255,0);
if (c == 3) color = new Color(0,255,0);
if (c == 4) color = new Color(0,255,255);
if (c == 5) color = new Color(0,0,255);
if (c == 6) color = new Color(255,0,255);
g.setColor(color);
g.fillPolygon(xCoords, yCoords, 4);
}
}
public static void main(String[] args) {
new Würfel1();
}
}
I used this Idea because I saw it in another code, but there the Polygon is drawed with an Image called buffer (i do not really know what this is)
I also use JApplet because its easier to use then a JFrame where i add my JPanel.
My latest try was to replace the try [...] catch [...] code with
ActionListener action = new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
};
new Timer(100,action).start();
but for some reason it just speeded up my applet and still had the problem i had.
I already read in other question that they got a similar problem but i didnt find a way to solve mine in using the answers to this problem.
I now changed the normal draw[...] and put my cube on an image:
... first is right on top in the drawcube method
// Double-Buffering
if (buffer==null) {
buffer=createImage(this.getSize().width, this.getSize().height);
gBuffer=(Graphics2D)buffer.getGraphics();
}
gBuffer.clearRect(0,0, this.getSize().width, this.getSize().height);
// Antialiasing
gBuffer.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
... the next quote is set in the end of drawcube
g.drawImage(buffer,0,0,this);
... i also had to change the fillPoly method (which is quite obvious)
gBuffer.setColor(color);
gBuffer.fillPolygon(xCoords, yCoords, 4);
... i put a timer in the init method - now its almost working fine
public void init() {
this.setSize(Screen);
ActionListener action = new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
};
new Timer(100,action).start();
}
Don't:
Use Thread.sleep() in a painting method. This will block the Event Dispatch Thread and prevent Swing from responding to events
Invoke repaint() from within a painting() method. This will cause an infinite loop
Override paint() for custom painting. Custom Painting is done by overriding the paintComponent(...) method of a JPanel (or JComponent). Then you add the panel to the applet.
Do:
Use a Swing Timer to schedule animation.

resize required to view images in java applet

I'm working with java images for the first time and having a problem viewing them when the applet loads. If I resize the window they display fine. I feel like this is a common first-timer error. Has anyone else encountered this? Any idea what the fix could be? What I believe to be the pertinent parts of the code are listed below. Thanks for any and all help with this...
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.*;
public class example extends JApplet implements Runnable
{
boolean updating;
Thread thread;
private int width, height;
Table aTable; //used to create and store values
private AudioClip[] sounds = new AudioClip[4]; //array to hold audio clips
private int counter = 0; //counter for audio clip array
private Image GameImage;
private Graphics GameGraphics;
public example() //set up applet gui
{
this.resize(new Dimension(600, 500));
//setup table
aTable = new Table(50, 50, 50, 50, 16, 16, getImage("images/FLY.gif", Color.white),
getImage("images/FlySwatter.gif", Color.white)); //Table must be square or flyswatter wont move straight
//add cordTxtFlds to bottom of screen
//this.add(cordTxtFlds, BorderLayout.SOUTH);
super.resize(800, 600);
repaint();
}
public void init()
{
width = getSize().width;
height = getSize().height;
GameImage = createImage(width, height);
GameGraphics = GameImage.getGraphics();
// Automatic in some systems, not in others
GameGraphics.setColor(Color.black);
repaint();
validate();
//show the greeting
ImageIcon icon = new ImageIcon("images/FLY.gif",
"a fly");
repaint();
validate();
}
/** Description of paint(Graphics g)
*
* Function draws table and sets the table color
* #param g graphics object used to draw table
* #return void
*/
public void paint(Graphics g)
{
GameGraphics.clearRect(0, 0, getWidth(), getHeight());
aTable.draw(GameGraphics);
g.drawImage(GameImage, 0, 0, this);
}
public void update(Graphics g)
{
paint(g);
validate();
}
public void start()
{
thread = new Thread(this);
thread.start();
}
public void stop()
{
updating = false;
}
public void run()
{
while(updating)
{
aTable.update();
}
}
//returns a transparent image.
//color is made transparent
private Image getImage(String imgPath, final Color color)
{
Image img = Toolkit.getDefaultToolkit().getImage(imgPath);
ImageFilter filter = new RGBImageFilter() {
// the color we are looking for... Alpha bits are set to opaque
public int markerRGB = color.getRGB() | 0xFFFFFF;
public final int filterRGB(int x, int y, int rgb) {
if ( ( rgb | 0xFF000000 ) == markerRGB ) {
// Mark the alpha bits as zero - transparent
return 0x00FFFFFF & rgb;
}
else {
// nothing to do
return rgb;
}
}
};
ImageProducer ip = new FilteredImageSource(img.getSource(), filter);
img = Toolkit.getDefaultToolkit().createImage(ip);
return img;
}
}
and the class which handles the drawing (in drawValues())
import java.awt.*;
import java.util.Random;
public class Table extends Panel
{
private char[][]values = new char[10][10]; //probably better to use array of integer values(0 or 1)
private Point[]coordLoc;// = new Point[100]; //stores the x & y coordinates of points on the grid
private boolean[]itemMarker; //stores the truth value of wether or not an item
// is located at the coresponding point in cordLoc array
private int [][]coords;// = new int [100][2];
Image itemImg; // stores the item image
private int Rows; // stores number of rows
private int Columns; // stores number of columns
private int BoxWidth ; // stores the width of a box
private int BoxHeight; // stores the height of a box
public Point Pos = new Point(); // creates a new point to draw from
private int tableHeight; // stores the height of the table
private int tableWidth; // stores the width of the table
private int numOfGridLocs;
/** Description of public Table( x, y, width, height, col, rows, X, O)
*
* Constructor function
* #param x contains an x-coordinate of the table
* #param y contains a y-coordinate of the table
* #param width contains the width of a box in the table
* #param height contains the height of a box in the table
* #param col contains the number of columns in the table
* #param rows contains the number of rows in the table
* #param itemImg contains the "target" image ie: ant, fly, ... unicorn
* #return none
*/
public Table(int x, int y, int width, int height, int col, int rows, Image itemImg, Image swatterImg)
{
/*set values*/
numOfGridLocs = (col - 1) * (rows - 1);
//initialize arrays
coordLoc = new Point[numOfGridLocs];
for(int i = 0; i < numOfGridLocs; i++)
coordLoc[i] = new Point();
Rows = rows;
Columns = col;
BoxWidth = width;
BoxHeight = height;
Pos.x = x;
Pos.y = y;
this.itemImg = itemImg;
tableHeight = Rows*BoxHeight;
tableWidth = Columns*BoxWidth;
itemMarker = new boolean[numOfGridLocs];
coords = new int [numOfGridLocs][2];
this.setValues();
mapGrid();
}
/** Description of draw(Graphics g)
*
* Function draws the lines used in the table
* #param g object used to draw the table
* #return none
*/
public void draw(Graphics g)
{
Graphics2D g2=(Graphics2D)g;
//draw flyswatter
drawValues(g2); //draw values
//draw vertical table lines
for (int i = 0 ; i <= Columns ; i++)
{
//make center line thicker
if(i == Rows/2)
g2.setStroke(new BasicStroke(2));
else
g2.setStroke(new BasicStroke(1));
g2.drawLine(i*BoxWidth + Pos.x, Pos.y, i*BoxWidth + Pos.x, tableHeight+Pos.y);
}
//draw horizontal table line
for(int i = 0 ; i <= Rows ; i++)
{
//make center line thicker
if(i == Rows/2)
g2.setStroke(new BasicStroke(2));
else
g2.setStroke(new BasicStroke(1));
g2.drawLine(Pos.x, i*BoxHeight + Pos.y, tableWidth+Pos.x, i*BoxHeight + Pos.y);
}
drawLables(g);
}
/** Description of drawLables(Graphics g)
*
* Function draws the Lables of the Table
* #param g object used to draw the table
* #return none
*/
private void drawLables(Graphics g)
{
String Lable;
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Font font = new Font("Serif", Font.PLAIN, 10);
g2.setFont(font);
int xLabel = this.Columns/2 * -1;
int yLabel = this.Rows/2;
//draw Row lables
for (int i = 0 ; i <= Rows ; i++)
{
Lable = "" + yLabel;
g2.drawString(Lable, Pos.x - 25, Pos.y + BoxHeight*i);
yLabel--;
}
//draw Column lables
for (int i = 0 ; i <= Columns ; i++)
{
Lable = "" + xLabel;
g2.drawString(Lable, Pos.x + BoxWidth*i - 5, Pos.y - 20 );
xLabel++;
}
}
/** Description of randomChangeFunc()
*
* Function randomly determines which table value to change
* #param none
* #return void
*/
public int getX(int XCordinate)
{
int x = XCordinate+Columns/2;
if(x < 0) x *= -1; //x must be positive
x *= BoxWidth;
x += Pos.x;
return x-BoxWidth/2;
}
//returns Position of Y-cordinate
public int getY(int YCordinate)
{
int y = YCordinate -Rows/2;
if (y < 0) y *= -1; //y must be positive
y *= BoxHeight;
y += Pos.y;
return y-BoxHeight/2;
}
/** Description of getValue( col, row )
*
* Function draws the lines used in the table
* #param col contains a column coordinate
* #param row contains a row coordinate
* #return returns table coordinates
*/
public char getValue(int col, int row)
{
return values[row][col];
}
/** Description of isDrawable( x, y )
*
* Function returns true if (x,y) is a point in the table
* #param x contains a table column
* #param y contains a table row
* #return boolean if (x,y) is a point in the table
*/
public boolean isDrawable(int x, int y)
{
if((this.getRow(y)!=-1)||(this.getColumn(x)!=-1))
return true;
else
return false;
}
private void drawValues(Graphics g)
{
for(int i = 0; i < numOfGridLocs; i++)
if(itemMarker[i])
g.drawImage(itemImg,coordLoc[i].x+1, coordLoc[i].y+1, BoxWidth-1, BoxHeight-1, null);
g.setColor(Color.black); // set color of table to black
}
//sets the randomized boolean values in itemMarker array
private void setValues()
{
double probOfItem = .25;
for(int count = 0; count < numOfGridLocs; count++){
itemMarker[count] = randomBool(probOfItem);
if(itemMarker[count])
System.out.println("true");
else
System.out.println("false");
}
}
//returns random boolean value, p is prob of 'true'
private boolean randomBool(double p)
{
return (Math.random() < p);
}
public int getColumn(int x)
{
x += (BoxWidth/2); //aTable.getX/Y returns in the middle of squares not at upper left point
int offsetx=0;
for (int i = 0 ; i < Columns*2 ; i++)
{
offsetx = i*BoxWidth;
if((x>=Pos.x+offsetx)&& (x<Pos.x+offsetx+BoxWidth))
return i-Columns;
}
return -100;
}
public int getRow(int y)
{
int offsety=0;
y += (BoxHeight/2); //aTable.getX/Y returns in the middle of squares not at upper left point
for (int i = 0 ; i < Rows*2 ; i++) {
offsety = i * BoxHeight;
if((y >= (offsety+Pos.y))&& (y < (offsety+BoxHeight+Pos.y)))
{
return ((i)*-1)+Rows;
}
}
return -100;
}
public boolean isValidGuess(int x, int y)
{
if ((x > Columns/2) || (x < Columns/2*-1) || (y > Rows/2) || (y < Rows/2*-1))
return false;
return true;
}
/** Description of randomChangeFunc()
*
* Function randomly determines which table value to change
* #param none
* #return void
*/
public void randomChangeFunc()
{
//get random row and column
Random rand=new Random();
int randRow = rand.nextInt(Rows); // gets and holds a random column
int randCol = rand.nextInt(Columns); // gets and holds a random column
System.out.println("randRow = " + randRow + " randCol = " + randCol);
if(values[randRow][randCol] == 'X')
values[randRow][randCol] = 'O';
else if(values[randRow][randCol] == 'O')
values[randRow][randCol] = 'X';
else
System.out.println("ERROR SWAPPING SQUARE VALUE"); // error message
}
private void mapGrid() //set values for coordLoc array
{
//set counter variables
int count = 0;
int index = 0;
//loop through all points, assigning them to the coordLoc array
for (int r=0; r < Rows-1; r++)
for (int c=0; c < Columns-1; c++) {
//the width/height / 2 places the points on grid line intersections, not the boxes they create
coordLoc[count].x = Pos.x + (BoxWidth) * c + (BoxWidth/2); // record x-point
coordLoc[count].y = Pos.y + (BoxHeight) * r + (BoxHeight/2); // record y-point
System.out.println(coordLoc[count].getX() + ", " + coordLoc[count].getY());
count++;
} //end inner for
//set positive x coord values for coords array
int y_axisBeginingIndex = (Rows - 2)/2;
for(int greaterIndex = 0; greaterIndex < ((Rows) / 2); greaterIndex++){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = y_axisBeginingIndex + greaterIndex + ((Rows - 1) * minorIndex);
coords[index][0] = greaterIndex;
}
}
//set negative x coord values for coords array
for(int greaterIndex = -1; greaterIndex > (0-((Rows) / 2)); greaterIndex--){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = y_axisBeginingIndex + greaterIndex + ((Rows - 1) * minorIndex);
coords[index][0] = greaterIndex;
}
}
//set positive y values for coords array
int x_axisBeginingIndex = (Rows - 1) * ((Rows / 2) - 1);
for(int greaterIndex = 0; greaterIndex < ((Rows) / 2); greaterIndex++){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = x_axisBeginingIndex + minorIndex;
coords[index][1] = greaterIndex;
}
x_axisBeginingIndex -= (Rows - 1);
}
//set negative y values for coords array
x_axisBeginingIndex = (Rows - 1) * ((Rows / 2) - 1) + (Rows - 1);
for(int greaterIndex = -1; greaterIndex > (0-((Rows) / 2)); greaterIndex--){
for(int minorIndex = 0; minorIndex < (Rows - 1); minorIndex++){
index = x_axisBeginingIndex + minorIndex;
coords[index][1] = greaterIndex;
}
x_axisBeginingIndex += (Rows - 1);
}
//print out the x and y coords
for(int i = 0; i < numOfGridLocs; i++){
System.out.println("[" + i + "] -> x = " + coords[i][0] + " y = " + coords[i][1]);
}
}
public boolean thereIsAnItemAt(int index){
return itemMarker[index];
}
public boolean bugsLeft(){
boolean thereAreBugsLeft = false;
for(int i = 0; i < numOfGridLocs; i++)
if(itemMarker[i])
thereAreBugsLeft = true;
return thereAreBugsLeft;
}
void update()
{
this.repaint();
}
}
Been stumped on this for weeks. Thanks again...
What I believe to be the pertinent
parts of the code are listed below.
By definition when you have a problem you don't know what part of the code is (or isn't) relevant. That is why you need to post a SSCCE that demonstrates the problem so we can see what you are doing.
The fact that is work "after" a resize means the problem is not with the painting. The problem could be that the images aren't loaded in which case you should be using:
drawImage(...., this);
The "this" instead of "null" notifies the panel to repaint the image when the image gets fully loaded.
Or maybe, you added the panel to the frame after the frame was visible and forgot to use
panel.revalidate().
By resizing the frame you force a revalidation.
The point is we are guessing. So save us time and post a SSCCE next time.
Sorry still too much code.
You need to read the article on Painting in AWT and Swing. Your code is a mixture of both.
Basically, as you where told in your last posting custom painting is done by overriding the paintComponent(...) method of JPanel. So you do the custom painting and then add the JPanel to the JApplet. I gave you a link to the Swing tutorial in your last posting and it also contains a section on how to write an Applet.
You should be extending JPanel, not Panel.
Also, you should NOT be overriding the paint() and upated() method of JApplet, this is old AWT code and should NOT be used with Swing.
Read the article and fix the problems first.
The answer is changing the draw() method in the class that extends JPanel to paintComponent() and switching the last parameter in the call to drawImage() to 'this' instead of 'null'. Worked instantly and perfectly!

Categories