Question

I know that there are lots of examples out there on this, but they all feel a little dated (even the sun docs) so I'm asking here to make sure what I'm doing is up to date. How would I go about talking to javascript from inside a java applet? Something simple like how to call alert() is all I'm looking for. Bonus points for a way to check if the browser has javascript enabled (this applet may be used in a school setting where having javascript turned off is a real possibility). All help is greatly appreciated, thanks in advance...

Code:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import netscape.javascript.JSObject;

public class TeamProject extends Applet implements ActionListener, MouseListener {
    char[][] charValues = new char[10][10];
    Table aTable;
    boolean allowUserInput = false;
    Button BtnStart;
    Button randomChangeBtn;
    boolean guessMode;
    JSObject jso;

    public void init() {
        //setup buttons
        BtnStart = new Button("add row/column");
        BtnStart.addActionListener((ActionListener)this);   //cast
        randomChangeBtn = new Button("change one value");
        randomChangeBtn.addActionListener((ActionListener)this);
        //add button
        this.add(BtnStart);
        //add image to Image objects
        Image imgO = getImage(getCodeBase(), "images/not.gif");
        Image imgX= getImage(getCodeBase(), "images/cross.gif");
        //setup table
        aTable = new Table(100, 100, 75, 55, 5, 5, imgX, imgO);
        //setBackground(Color.LIGHT_GRAY);
        super.resize(700, 700);
        //add mouse listener
        addMouseListener(this);
        //initially guessMode will be false
        guessMode = false;
        //to talk to javascript
        jso = JSObject.getWindow(this);
    }

    public void paint(Graphics g) {
        g.setColor(Color.black);
        aTable.draw(g);
    }

    //Mouse listener methods
    public void mousePressed (MouseEvent e) {
        if(!guessMode){
            if ((allowUserInput)) { //&&(aTable.isDrawable(e.getX(), e.getY())))
                aTable.swapSquareValue(e.getX(), e.getY());
                repaint();
            }
        } else {
            System.out.println("guessed row = " + e.getY() + " guessed col = " + e.getX());
            aTable.checkGuess(e.getX(), e.getY());
            //repaint();
        }
    }

    public void mouseClicked (MouseEvent e) {}
    public void mouseEntered (MouseEvent e) {}
    public void mouseReleased (MouseEvent e) {}
    public void mouseExited (MouseEvent e) {}

    //Button action listener
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == BtnStart) {
            aTable.addRow();
            aTable.addColumn();
            this.remove(BtnStart);
            this.add(randomChangeBtn);
            repaint();
        } else if (e.getSource() == randomChangeBtn) {
            //aTable.addRow();
            aTable.randomChangeFunc();
            repaint();
            guessMode = true;
        }
        allowUserInput = true;
        System.out.println(aTable.toString());
    }
}

and my Table class:

import java.awt.*;
import java.util.Random;

public class Table {
    private char[][]values = new char[10][10];  //probably better to use array of integer values(0 or 1)
    Image imgO;
    Image imgX;
    private int Rows;
    private int Columns;
    private int BoxWidth ;
    private int BoxHeight;
    public Point Pos = new Point();

    private int tableHeight;
    private int tableWidth;

    private int changedRow;
    private int changedCol;

    //constructor
    public Table(int x, int y, int width, int height, int col, int rows, Image X, Image O) {
        Rows = rows;
        Columns = col;
        BoxWidth = width;
        BoxHeight = height;
        Pos.x = x;
        Pos.y = y;

        imgX = X;
        imgO = O;

        tableHeight = Rows*BoxHeight;
        tableWidth = Columns*BoxWidth;
        this.setValues();
    }

    //draw table
    public void draw(Graphics g) {
        //draw vertical table lines
        for (int i = 0 ; i <= Columns ; i++)
            g.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++)
            g.drawLine(Pos.x, i*BoxHeight + Pos.y, tableWidth+Pos.x, i*BoxHeight + Pos.y);

        //draw values
        drawValues(g);
    }

    public void swapSquareValue(int x, int y) {
        if (this.isDrawable(x, y)) {
            int col = this.getColumn(x)-1;
            int row = this.getRow(y)-1;

            if(values[row][col] == 'X')
                values[row][col] = 'O';
            else if(values[row][col] == 'O')
                values[row][col] = 'X';
            else
                System.out.println("ERROR SWAPPING SQUARE VALUE");
        } else
            System.out.println("says not drawable");
    }

    public char getValue(int col, int row) {
        return values[row][col];
    }

    //return true 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;
    }

    public void addRow() {
        Rows++;
        tableHeight = (Rows*BoxHeight);
        int numOfXs = 0;
        for (int c=0; c < Columns; c++) {
            numOfXs = 0;
            for(int r = 0; r < Rows - 1; r++) {
                if(values[r][c] == 'X'){
                    numOfXs++;
                    System.out.println("in column " + c + "new x found at " + r + " " + c + ", numOfXs = " + numOfXs);
                }
                if(numOfXs % 2 == 0) {
                    values[Rows - 1][c] = 'O';
                } else{
                    values[Rows - 1][c] = 'X';
                }
            }//end inner for
            System.out.println("end of column " + c);
        }//end outer for
    }// end function

    public void addColumn() {
        Columns++;
        tableWidth = (Columns*BoxWidth);
        int numOfXs = 0;

        for (int r=0; r < Rows; r++) {
            numOfXs = 0;
            for(int c = 0; c < Columns - 1; c++) {
                if(values[r][c] == 'X') {
                    numOfXs++;
                    System.out.println("in row " + r + "new x found at " + r + " " + c + ", numOfXs = " + numOfXs);
                }
                if(numOfXs % 2 == 0) {
                    values[r][Columns - 1] = 'O';
                }
                else {
                    values[r][Columns - 1] = 'X';
                }
            }//end inner for
            System.out.println("end of row " + r);
        }
    }

    //does not add or remove values
    public void setColumn(int col) {
        Columns = col;
        tableWidth = (Columns*BoxWidth);
    }

    //does not add or remove values
    public void setRows(int row) {
        Rows = row;
        tableHeight = (row*BoxHeight);
    }

    public String toString() {
        String ValueString = "Displaying charValues[" + Rows + "][" + Columns + "]\n";
        for (int r=0; r < Rows; r++) {
            for (int c=0; c < Columns; c++) {
                ValueString += (char)values[r][c];
            }
            ValueString += "\n";        //next line
        }
        return ValueString;
    }

    private void drawValues(Graphics g) {
        Point drawPoint = new Point();
        for (int r=0; r < Rows; r++)
            for (int c=0; c < Columns; c++) {
                drawPoint.x = Pos.x+BoxWidth*c;
                drawPoint.y = Pos.y+BoxHeight*r;
                //g.setColor(Color.white);
                //g.fillRect(drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1);
                if (values[r][c] == 'X') {
                    g.drawImage(imgX,drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1, null);
                } else {
                    g.drawImage(imgO,drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1, null);
                }
                //System.out.print((char)values[r][c]);
            }
        g.setColor(Color.black);
    }

    //fills array with random values
    private void setValues() {
        for (int r=0; r < Rows; r++)
            for (int c=0; c < Columns; c++) {
                values[r][c] = this.randomChar();
            }
    }

    //randomly return 'X' or 'O'
    private char randomChar() {
        char randomValue;
        Random RandomGen = new Random();

        if (RandomGen.nextInt(2)==0)
            randomValue = 'O';
        else
            randomValue ='X';
        return randomValue;
    }

    private int getColumn(int x) {
        int offsetx=0;
        for (int i = 0 ; i < Columns ; i++) {
            offsetx = i*BoxWidth;
            if((x>Pos.x+offsetx)&& (x<Pos.x+offsetx+BoxWidth))
                return i+1;
        }
        return -1;
    }

    private int getRow(int y) {
        int offsety=0;
        for (int i = 0 ; i < Rows ; i++) {
            offsety = i*BoxHeight;
            if((y>Pos.y+offsety)&& (y<Pos.x+offsety+BoxHeight))
                return i+1;
        }
        return -1;
    }

    public void randomChangeFunc() {
        //get random row and column
        Random rand=new Random();

        int randRow = rand.nextInt(Rows);
        int randCol = rand.nextInt(Columns);

        System.out.println("randRow = " + randRow + " randCol = " + randCol);
        /*THIS SHOULD BE HANDLED BY swapSquareValue(randCol,randRow)
        /*BUT GETTING ERRORS (notDrawable). THE FOLLOWING CODE IS A WORK-AROUND
        */
        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");
        //set globals
        changedRow = randRow;
        changedCol = randCol;
    }

    public void checkGuess(int guessCol, int guessRow){
        int gCol = this.getColumn(guessCol)-1;
        int gRow = this.getRow(guessRow)-1;
        System.out.println("gCol = " + gCol + " gRow = " + gRow);
        if(gCol == changedCol && gRow == changedRow) {
            System.out.println("CORRECT!!!");
        } else
            System.out.println("incorrect :(");
    }
}

Changing my javac command to:

javac -classpath /usr/lib/Java6u1/jre/lib/plugin.jar TeamProject.java

ignores my "Table" class and I get errors where I mention that. Any ideas?

Was it helpful?

Solution

Look at this article. If you try calling JS from applet on this page it definitely works, because there are js exception after update action from applet :)

import netscape.javascript.JSObject

public void init() { jso = JSObject.getWindow(this); }

 public void actionPerformed(ActionEvent e) {
     if(jso != null )
         try {
                jso.call("updateWebPage", new String[] {txt.getText()});
             }
             catch (Exception ex) {
                 ex.printStackTrace();
             }
 }

EDIT: For the classpath problem you need to add plugin.jar to your classpath which is located in %JAVA_HOME%\jre\lib\plugin.jar

EDIT2:
I think that your problem is that a class Table isn't compiled too:

try javac -classpath /usr/lib/Java6u1/jre/lib/plugin.jar TeamProject.java Table.java or use wildcards like *.java.

Maybe you should consider use IDE like Eclipse or Netbeans to compile and run project instead of struggling with command line tools.

OTHER TIPS

As requested a sample which calls alert on the page it is embedded in (tested in Opera 10.01, FF 3.5.4, IE6).

Note the MAYSCRIPT in the applet tag, this MUST be present to enable java-javascript communication. As per default access to JSObject is disabled due to security reasons.

HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Test</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
  <applet code="HelloWWW.class" width="300px" height="100px"  MAYSCRIPT></applet>
</body>
</html>

Java (compile with javac -cp .;[pathtojre]/jre/lib/plugin.jar HelloWWW.java)

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import netscape.javascript.*;

public class HelloWWW extends Applet implements ActionListener {
  Button runButton;
  public void init() {
    runButton = new Button("Run: alert(\"Hello WWW\")");
    add(runButton);
    runButton.addActionListener(this);
  }
  public void actionPerformed(ActionEvent evt) {
    if (evt.getSource() == runButton) {
      try {
        //get JSOBject
        JSObject jso = JSObject.getWindow(this);
        //call alert with parameter passed as Object array
        jso.call("alert", new Object[]{"Hello WWW"});
      } catch (JSException e) {
        e.printStackTrace();
      }
      runButton.setLabel("Did it!");
      repaint();
    }
  } 
}

Also check Java-to-Javascript Communication and Mozilla Dev: JSObject for further info.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top