tags:

views:

282

answers:

3

Hello all, 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...

+1  A: 

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.

camickr
Thanks. working on it. The actual code uses 7 different classes so give me a minute to try to par all that down. ps: changing null to this didn't work :(
danwoods
yanked out as much code as I could. Hope that helps
danwoods
A: 

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.

camickr
changed extends Panel to extends JPanel in the Table class and public void paint(Graphics g) in example class to protected void paintComponent(Graphics g) as per the instructions in the link, now nothing gets painted/drawn... Will continue working with it
danwoods
Commenting out update() doesn't seem to help either
danwoods
changed calls to paint() to repaint() and compiler says it can't find symbol
danwoods
also, does updated() = update() in your post?
danwoods
I don't know what the above comment means. I said you need to get rid of the the paint() and update() methods completely. I suggest you go back to the Swing tutorial which has a section on "How to Make Applets". It has a simple example that shows you how to create an applet that does custom painting on a custom panel with aninmation, which is somewhat close to what you are trying to do. Learn the structure of building the applet and adding a JPanel to the applet. Then move on to your project.
camickr
Yes updated() should be update(); My above comment refers to your paint() comment.
camickr
sorry, thought the Painting in AWT and Swing link said to change paint() to paintComponet() for swing usage, guess not
danwoods
Custom painting is only done on Swing components (like JPanel, JLabel, JTree etc). JFrame and JDialog and JApplet are not really Swing components they are "Top Level Container" and are used to hold other Swing components. You do not do custom painting in a Top Level Container. Yu have already seen the tutorial on "Custom Painting". You did not do anything to the JFrame other than add your custom JPanel to it. JApplet is the same
camickr
Removed all paint()/paintComponet() and update() methods. Don't really see how it can draw or paint anything without some type of paint method though. Especially since those methods had several other function calls/coding in them...
danwoods
so should I be doing custom painting in my Table class? (the one that extends JPanel)
danwoods
Actually I tried adding paintComponet() to the Table class with no changes...
danwoods
Yes, the only place you have custom painting is in the Table class. But don't test it this way. Create a simple custom JPanel that has a simple drawSTring(...) and add it to you JApplet and get that working first. Its easier to debug 10 lines of code (which is all it will take to create a demo applet) then it is to debug your entire project.
camickr
Thanks. Heading out for a minute, I'll test and post the results when I get back...
danwoods
The thing is, the code I posted draws the grid, but not the images...
danwoods
A: 

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!

danwoods