accessing javascript from inside java - java

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?

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.

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.

Related

AWT-EventQueue-0 java.lang.ArrayIndexOutOfBoundsException: {value} (Program still runs)

So I looked this error up before posting and understand it has something to do with trying to refer to an array value outside of the bounds of an array, but what confuses me is that my class still runs as if the error never happened (My guess for this is the differing threads), and that no one thing in my code seems to be causing the error (I followed the stack-trace all the way through); it's just annoying to see the error pop up every so often and I would like to know how to fix it.
My class is a text based grid display that allows for keyboard input (I don't extend the JFrame class because I don't want anyone to be able to resize the display other than by changing the "width" and "height" fields). I hooked it up to another class with a main method that uses the display to play a top-view text-based platformer game to make the error more visible. As I move around, every so often I get an error similar to this one:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at javax.swing.text.CompositeView.getView(CompositeView.java:160)
at javax.swing.text.Utilities.getNextVisualPositionFrom(Utilities.java:1030)
at javax.swing.text.CompositeView.getNextEastWestVisualPositionFrom(CompositeView.java:757)
at javax.swing.text.CompositeView.getNextVisualPositionFrom(CompositeView.java:479)
at javax.swing.plaf.basic.BasicTextUI$RootView.getNextVisualPositionFrom(BasicTextUI.java:1588)
at javax.swing.plaf.basic.BasicTextUI.getNextVisualPositionFrom(BasicTextUI.java:1127)
at javax.swing.text.DefaultEditorKit$NextVisualPositionAction.actionPerformed(DefaultEditorKit.java:1690)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1663)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2929)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
at java.awt.Component.processEvent(Component.java:6310)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771)
at java.awt.Component.dispatchEventImpl(Component.java:4760)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
This is my class:
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class TextDisplay {
private int width;
private int height;
private int fontSize;
private double fontSpacing;
private char lastChar = 0;
private int lastKeyPress = 0;
private int lastKeyRelease = 0;
private JFrame mainframe;
private JTextPane field;
public TextDisplay(int width, int height) {
this.width = width;
this.height = height;
createGUI(false);
clearDisplay();
}
public TextDisplay(int width, int height, boolean visibility) {
this.width = width;
this.height = height;
createGUI(visibility);
clearDisplay();
}
private void createGUI(boolean visibility) {
mainframe = new JFrame();
if ((this.width < 1) || (this.height < 1)) {
throw new IllegalArgumentException();
}
mainframe.setResizable(false);
mainframe.setDefaultCloseOperation(3);
field = new JTextPane();
field.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
lastChar = e.getKeyChar();
}
public void keyPressed(KeyEvent e) {
lastKeyPress = e.getKeyCode();
}
public void keyReleased(KeyEvent e) {
lastKeyRelease = e.getKeyCode();
}
});
field.setEditable(false);
setFont(70, 0.0);
clearDisplay();
mainframe.add(field);
if (visibility) {
mainframe.setVisible(true);
}
}
public int getLastKeyPress() {
return lastKeyPress;
}
public int getLastKeyRelease() {
return lastKeyRelease;
}
public char getLastKeyTyped() {
return lastChar;
}
public void clearLastKeyPress() {
lastKeyPress = 0;
}
public void clearLastKeyRelease() {
lastKeyRelease = 0;
}
public void clearLastKeyTyped() {
lastChar = 0;
}
private int calcWindowWidth() {
FontMetrics fm = field.getFontMetrics(new Font("Consolas", 0, this.fontSize));
return 12 + fm.charWidth(' ') * this.width;
}
private int calcWindowHeight() {
FontMetrics fm = field.getFontMetrics(new Font("Consolas", 0, this.fontSize));
double s = this.fontSpacing;
int fh = fm.getHeight();
int h = this.height;
double tf = Math.signum(s) * -4;
int pixels = 40 + fh * h;
double spacingPixels = roundB(fh * s * (h - 1));
int oddPixels = (int) roundB(tf * Math.floor(8 * s / tf) - 8 * s);
int extraPixels = (int) spacingPixels;
return pixels + extraPixels - oddPixels;
}
public static double roundB(double value) {
return Math.round(value * 100000000000.0) / 100000000000.0;
}
public void refresh() {
mainframe.setVisible(false);
mainframe.setVisible(true);
}
public void dispose() {
mainframe.dispose();
}
public boolean isDisplayable() {
return mainframe.isDisplayable();
}
public void setVisible(boolean visibility) {
mainframe.setVisible(visibility);
}
public void setTitle(String name) {
mainframe.setTitle(name);
}
public int getFontSize() {
return this.fontSize;
}
public double getFontSpacing() {
return this.fontSpacing;
}
public void setFontSize(int fontSize) {
setFont(fontSize, this.fontSpacing);
}
public void setFontSpacing(double fontSpacing) {
setFont(this.fontSize, fontSpacing);
}
public void setFont(int fontSize, double fontSpacing) {
this.fontSize = fontSize;
this.fontSpacing = roundB(fontSpacing);
mainframe.setSize(calcWindowWidth(), calcWindowHeight());
StyledDocument doc = field.getStyledDocument();
MutableAttributeSet mas = new SimpleAttributeSet();
StyleConstants.setLineSpacing(mas, (float) this.fontSpacing);
StyleConstants.setFontSize(mas, this.fontSize);
StyleConstants.setFontFamily(mas, "Consolas");
doc.setParagraphAttributes(0, 1000, mas, true);
field.setStyledDocument(doc);
}
public void setDefaultCloseOperation(int operation) {
mainframe.setDefaultCloseOperation(operation);
}
public void clearDisplay() {
StringBuilder display = new StringBuilder();
for (int row = 0; row < this.height; row++) {
for (int col = 0; col < this.width; col++) {
display.append(' ');
}
display.append('\n');
}
field.setText(display.toString());
}
public void setDisplay(char[][] charMap) {
StringBuilder display = new StringBuilder();
if (charMap.length != this.height) {
throw new IllegalArgumentException("rows = " + charMap.length + ", this.height = " + this.height);
}
for (int row = 0; row < charMap.length; row++) {
if (charMap[row].length != this.width) {
throw new IllegalArgumentException(
"row = " + row + ", length = " + charMap[row].length + ", this.width = " + this.width);
}
char[] arrayOfChar;
int j = (arrayOfChar = charMap[row]).length;
for (int i = 0; i < j; i++) {
char c = arrayOfChar[i];
display.append(c);
}
display.append('\n');
}
field.setText(display.toString());
}
public void setDisplay(String[] lines) {
StringBuilder display = new StringBuilder();
if (lines.length != this.height) {
throw new IllegalArgumentException("rows = " + lines.length + ", this.height = " + this.height);
}
for (int i = 0; i < lines.length; i++) {
String string = lines[i];
if (string.length() != this.width) {
throw new IllegalArgumentException(
"row = " + i + ", length = " + string.length() + ", this.width = " + this.width);
}
display.append(string + '\n');
}
field.setText(display.toString());
}
public String[] getDisplay() {
return field.getText().split("\n");
}
public char[][] getDisplayCharMap() {
String[] display = getDisplay();
char[][] charMap = new char[this.height][this.width];
for (int row = 0; row < this.height; row++) {
charMap[row] = display[row].toCharArray();
}
return charMap;
}
public void setCharAt(char character, int row, int col) {
char[][] display = getDisplayCharMap();
if ((row >= this.height) || (col >= this.width) || (row < 0) || (col < 0)) {
throw new IllegalArgumentException("row = " + row + ", this.height = " + this.height + ", col = " + col
+ ", this.width = " + this.width);
}
display[row][col] = character;
setDisplay(display);
}
public char getCharAt(int row, int col) {
char[][] display = getDisplayCharMap();
if ((row >= this.height) || (col >= this.width) || (row < 0) || (col < 0)) {
throw new IllegalArgumentException("row = " + row + ", col = " + col);
}
return display[row][col];
}
public void output(String text, int row, int col) {
char[][] display = getDisplayCharMap();
if ((row >= this.height) || (col >= this.width) || (row < 0) || (col < 0)) {
throw new IllegalArgumentException("row = " + row + ", col = " + col);
}
char[] arrayOfChar = text.toCharArray();
for (char c : arrayOfChar) {
display[row][col] = c;
col++;
if (col >= this.width) {
col = 0;
row++;
}
if (row >= this.height) {
row = 0;
}
}
setDisplay(display);
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
}
This is the class I used with the main method:
import java.awt.event.KeyEvent;
public class Main {
volatile static int key;
public static void main(String[] args) {
TextDisplay display = new TextDisplay(10, 5);
display.setDisplay(new String[] {"OXXXXXXXXO","X X","X X","X X","OXXXXXXXXO"});
display.setVisible(true);
int x = 1;
int y = 1;
boolean gameRunning = true;
display.setCharAt('P', y, x);
while (gameRunning) {
key = display.getLastKeyPress();
if (key != 0) {
display.setCharAt(' ', y, x);
switch (key) {
case KeyEvent.VK_LEFT:
if (display.getCharAt(y, x - 1) == ' ') x--;
break;
case KeyEvent.VK_UP:
if (display.getCharAt(y - 1, x) == ' ') y--;
break;
case KeyEvent.VK_RIGHT:
if (display.getCharAt(y, x + 1) == ' ') x++;
break;
case KeyEvent.VK_DOWN:
if (display.getCharAt(y + 1, x) == ' ') y++;
break;
}
display.setCharAt('P', y, x);
display.clearLastKeyPress();
}
}
}
}
I can live with the error, but its quite annoying; could someone help me fix this?
EDIT: Figured this was impractical, so I just extended JFrame and wrapped any time I was changing the display with invokeLater. When I did this the error disappeared. Thanks to tsolakp for the help.
You are changing Swing UI state from main thread inside your while loop.
Keep in mind that after calling setVisible on display object the Event Dispatch Thread is started and you cannot modify UI directly after that call.
Swing does not guarantee proper operation in this type of usage.
Try to wrap all calls to display' variable aftersetVisiblecall withinvokeLater`.
1) Here is the code the uses invokeLater:
public static void main(String[] args) {
TextDisplay display = new TextDisplay(10, 5);
display.setDisplay(new String[] {"OXXXXXXXXO","X X","X X","X X","OXXXXXXXXO"});
display.setVisible(true);
Helper helper = new Helper(display);
boolean gameRunning = true;
while (gameRunning) {
SwingUtilities.invokeLater( () -> helper.check() );
}
}
private static class Helper{
int x = 1;
int y = 1;
TextDisplay display = null;
public Helper(TextDisplay display){
this.display = display;
display.setCharAt('P', y, x);
}
public void check(){
int key = display.getLastKeyPress();
if (key != 0) {
display.setCharAt(' ', y, x);
switch (key) {
case KeyEvent.VK_LEFT:
if (display.getCharAt(y, x - 1) == ' ') x--;
break;
case KeyEvent.VK_UP:
if (display.getCharAt(y - 1, x) == ' ') y--;
break;
case KeyEvent.VK_RIGHT:
if (display.getCharAt(y, x + 1) == ' ') x++;
break;
case KeyEvent.VK_DOWN:
if (display.getCharAt(y + 1, x) == ' ') y++;
break;
}
display.setCharAt('P', y, x);
display.clearLastKeyPress();
}
}
}
2) You dont really need to while loop at all. Just listen to key events. I just poster the approach with invokeLater so that you could familiarize how it can be used:
public static void main(String[] args) {
TextDisplay display = new TextDisplay(10, 5);
Helper helper = new Helper(display);
display.setDisplay(new String[] {"OXXXXXXXXO","X X","X X","X X","OXXXXXXXXO"});
display.addKeyListener(helper);
display.setVisible(true);
}
private static class Helper extends KeyAdapter{
int x = 1;
int y = 1;
TextDisplay display = null;
public Helper(TextDisplay display){
this.display = display;
display.setCharAt('P', y, x);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key != 0) {
display.setCharAt(' ', y, x);
switch (key) {
case KeyEvent.VK_LEFT:
if (display.getCharAt(y, x - 1) == ' ') x--;
break;
case KeyEvent.VK_UP:
if (display.getCharAt(y - 1, x) == ' ') y--;
break;
case KeyEvent.VK_RIGHT:
if (display.getCharAt(y, x + 1) == ' ') x++;
break;
case KeyEvent.VK_DOWN:
if (display.getCharAt(y + 1, x) == ' ') y++;
break;
}
display.setCharAt('P', y, x);
}
}
}
and add this method to your TextDisplay:
public void addKeyListener(KeyListener kl){
field.addKeyListener(kl);
}

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError occurs

I am trying to make a game which breaks the tile when I type a specific key.
Firstly, here is what the exception.
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.newLine(PrintStream.java:545)
at java.io.PrintStream.println(PrintStream.java:807)
at code.gui.NewView.addTileToDelete(NewView.java:192)
at code.gui.NewView.deleteTileByColor(NewView.java:151)
at code.gui.NewView.deleteTileByColor(NewView.java:158)
at code.gui.NewView.deleteTileByColor(NewView.java:152)
It runs fine if I execute deleteTileByColor method once,
however from the second time, above error occurs.
Here's the code for game.
package code.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import code.handlers.PressKeyHandler;
import code.model.DataModel;
import code.parts.GamePanel;
import code.parts.GameTile;
public class NewView extends JFrame {
int _exitCounter;
int _tileDeleteCounter;
int _column = 4;
int _row = 4;
GamePanel _gamePanel;
DataModel _dm;
GameTile _tile;
ArrayList<ArrayList<GameTile>> _gameTileList = new ArrayList<ArrayList<GameTile>>();
ArrayList<GamePanel> _gamePanLst = new ArrayList<GamePanel>();
ArrayList<Character> _letterList;
public NewView(DataModel dm) {
super("Sequence Game");
this._dm = dm;
setLayout(new GridLayout(1, 4));
shuffleLetter();
for (int i = 0; i < _column; i++) {
_gamePanel = new GamePanel();
System.out.println("1. _gameTileList에 new ArrayList 총 " + i + "개 추가");
for (int j = 0; j < _row; j++) {
_tile = new GameTile(_letterList.get((4 * i) + j));
_gamePanel.add(_tile);
_tile.addKeyListener(new PressKeyHandler(_dm));
}
_gamePanLst.add(_gamePanel);
}
System.out.println("어레이 리스트<어레이리스트> 사이즈 : " + _gameTileList.size());
setFrame();
this.setSize(300, 500);
this.setVisible(true);
this.add(_gamePanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
_dm.setView(this);
}
public void setFrame() {
for (int i = 0; i < _gamePanLst.size(); i++) {
this.add(_gamePanLst.get(i), i);
}
this.repaint();
this.revalidate();
}
public void update(char letter) {
resetTileArrLst();
Color tileColor;
for (int i = 0; i < _column; i++) {
for (int j = 0; j < _row; j++) {
if (_gamePanLst.get(i).getComponent(j).getName().equals("" + letter)) {
System.out.println("i : " + i + " / j : " + j);
// System.out.println("최초비교");
tileColor = setTileColor(_gamePanLst.get(i).getComponent(j));
addTileToDelete(i, j);
deleteTileByColor(i, j, tileColor);
}
}
}
checkToQuit();
setFrame();
}
public void shuffleLetter() {
ArrayList<Character> temp = new ArrayList<Character>();
int numOfLetters = 26;
for (int i = 0; i < numOfLetters; i++) {
temp.add((char) (97 + (i)));
}
Collections.shuffle(temp);
_letterList = temp;
}
public Color setTileColor(Component comp) {
System.out.println("**********setTileColor********** ");
System.out.println("compo color : " + comp.getBackground());
Color temp;
if (comp.getBackground().equals(Color.RED)) {
temp = Color.RED;
} else if (comp.getBackground().equals(Color.BLUE)) {
temp = Color.BLUE;
} else if (comp.getBackground().equals(Color.YELLOW)) {
temp = Color.YELLOW;
} else {
temp = Color.GREEN;
}
return temp;
}
public GameTile getEmptyTile() {
GameTile emptyTile = new GameTile(' ');
emptyTile.setBorder(BorderFactory.createEmptyBorder());
emptyTile.setBackground(Color.BLACK);
emptyTile.addKeyListener(new PressKeyHandler(_dm));
return emptyTile;
}
public void checkToQuit() {
int counter = 0;
for (int i = 0; i < _gamePanel.getComponentCount(); i++) {
if (_gamePanel.getComponent(i).getBackground() == Color.BLACK) {
counter++;
}
}
if (counter == _gamePanel.getComponentCount()) {
this.dispose();
}
}
public void deleteTile(int i) {
_gamePanel.remove(i);
_gamePanel.add(getEmptyTile(), i);
}
public void deleteTileByColor(int column, int row, Color tileColor) {
// Right
if (((column + 1) < 4) && tileColor == (_gamePanLst.get((column + 1)).getComponent(row).getBackground())) {
column = column + 1;
addTileToDelete(column, row);
deleteTileByColor(column, row, tileColor);
}
// Left
if ((column - 1 >= 0) && tileColor == (_gamePanLst.get(column - 1).getComponent(row).getBackground())) {
column = column - 1;
addTileToDelete(column, row);
deleteTileByColor(column, row, tileColor);
}
// Below
if ((row + 1 < 4) && tileColor == (_gamePanLst.get(column).getComponent(row + 1).getBackground())) {
row = row + 1;
addTileToDelete(column, row);
deleteTileByColor(column, row, tileColor);
}
// Above
if ((row - 1 >= 0) && tileColor == (_gamePanLst.get(column).getComponent(row - 1).getBackground())) {
row = row - 1;
addTileToDelete(column, row);
deleteTileByColor(column, row, tileColor);
}
moveDownTiles();
}
public void moveDownTiles() {
for (int i = 0; i < _column; i++) {
for (int j = 0; j < _row; j++) {
if (_gamePanLst.get(i).getComponent(j).equals(_gameTileList.get(i).get(j))) {
_gamePanLst.get(i).remove(j);
_gamePanLst.get(i).add(getEmptyTile(), 0);
}
}
}
resetTileArrLst();
}
public void addTileToDelete(int column, int row) {
_gameTileList.get(column).set(row, (GameTile) _gamePanLst.get(column).getComponent(row));
System.out.println("지울 타일 추가 완료 : " + _gamePanLst.get(column).getComponent(row).getName());
}
public int get_exitCounter() {
return _exitCounter;
}
public void set_exitCounter(int _exitCounter) {
this._exitCounter = _exitCounter;
}
public GamePanel get_gamePanel() {
return _gamePanel;
}
public void set_gamePanel(GamePanel _gamePanel) {
this._gamePanel = _gamePanel;
}
public ArrayList<ArrayList<GameTile>> get_gameTilesList() {
return _gameTileList;
}
public void set_gameTilesList(ArrayList<ArrayList<GameTile>> _gameTilesList) {
this._gameTileList = _gameTilesList;
}
public ArrayList<Character> get_letterList() {
return _letterList;
}
public void set_letterList(ArrayList<Character> _letterList) {
this._letterList = _letterList;
}
public ArrayList<GamePanel> get_gamePanLst() {
return _gamePanLst;
}
public void set_gamePanLst(ArrayList<GamePanel> _gamePanLst) {
this._gamePanLst = _gamePanLst;
}
public void resetTileArrLst() {
if (_gameTileList.size() != 0) {
_gameTileList.clear();
}
for (int i = 0; i < _column; i++) {
_gameTileList.add(i, new ArrayList<GameTile>());
for (int j = 0; j < _row; j++) {
_gameTileList.get(i).add(getEmptyTile());
}
}
}
}

java swing image path

The class is extracted from a game project. Everything works as it should, I can play the game, start a new game, etc. Only the .gif pics are not displayed. Where in my project do I have to store the .gif pics, so that the image path works? I hope the code is understandable.
class Field extends JPanel {
//fields in x direction
static final int max_x = 10;
//fields in y direction
static final int max_y = 10;
//array for field
JLabel[][] label = new JLabel [max_x][max_y];
//home-directory
String img_source = MainWindow.getDirectory();
//separator
String separator = MainWindow.getSeparator();
//stringarray for different viewing direction
String [] viewing_direction = {"player.gif", "player1.gif", "player2.gif", "player3.gif", "player4.gif", null, "player6.gif", "player7.gif", "player8.gif", "player9.gif", "loss.gif", "win.gif"};
//integer for last viewing direction
int viewing_direction_Player = 0;
Field() {
super();
this.setLayout(new GridLayout(max_x, max_y));
//set theme "game"
img_source = img_source + "image" + separator + "Game";
addJLabels();
}
//creates field with alternating background
private void addJLabels() {
for (int i = 0; i < max_y; i++) {
for (int k = 0; k < max_x; k++) {
label[i][k] = new JLabel();
if((i+k) % 2 == 0) { //modulo operation for alternating background
label[i][k].setBackground(Color.BLACK);
}
else {
label[i][k].setBackground(Color.WHITE);
}
label[i][k].setPreferredSize(new Dimension(50, 50));
label[i][k].setOpaque(true);
this.add(label[i][k]);
}
}
}
//method to get last viewing direction
public void setLastDirection(int lastDirection) {
viewing_direction_Player = lastDirection;
}
//method that draws all pawns
public void drawAllPawns(AbstractPawn[] pawns) {
for(int i = 0; i < (int) pawns.length; i++) {
if ((pawns[i].getX() < 0) || (pawns[i].getY() < 0)) {
} else if (pawns[i] instanceof Player) {
label[pawns[i].getY()][pawns[i].getX()].setIcon(new ImageIcon(img_source + separator + viewing_direction[viewing_direction_Player]));
} else if(pawns[i] instanceof Opponent) {
label[pawns[i].getY()][pawns[i].getX()].setIcon(new ImageIcon(img_source + separator + "opponent.gif"));
} else if(pawns[i] instanceof Vortex) {
label[pawns[i].getY()][pawns[i].getX()].setIcon(new ImageIcon(img_source + separator + "vortex.gif"));
} else if(pawns[i] instanceof Obstacle) {
label[pawns[i].getY()][pawns[i].getX()].setIcon(new ImageIcon(img_source + separator + "obstacle.gif"));
} else if(pawns[i] instanceof Destruction) {
label[pawns[i].getY()][pawns[i].getX()].setIcon(new ImageIcon(img_source + separator + "destruction.gif"));
} else if(pawns[i] instanceof Ammo) {
label[pawns[i].getY()][pawns[i].getX()].setIcon(new ImageIcon(img_source + separator + "ammo.gif"));
}
}
}
Here is the getDirectory from my mainwindow class
public static String getDirectory() {
String home = System.getProperty("user.dir");
return (home + getSeparator());
}
Simple way to use image
First drag and drop image in src folder
than type this code
ImageIcon ic = new ImageIcon(getResource().getClass("Example.jpg")); // image name instead of Example.jpg

Numbering A Crossword Java ACM Graphics

The problem asks for an acm graphics program that reads a txt file like this:
R
FUN
SALES
RECEIPT
MERE#FARM
DOVE###RAIL
MORE#####DRAW
HARD###TIED
LION#SAND
EVENING
EVADE
ARE
D
and makes a crossword puzzle, with blank squares on letters, black squares on '#', and nothing on empty spaces. The problem also asks that "if the square is at the beginning of a word running across, down, or both, the square should contain a number that is assigned sequentially through the puzzle."
I have the square drawing working, but I'm stuck on drawing the numbers correctly. There is something wrong with how I'm detecting null space and black squares. Can someone tell me what I'm doing wrong, please?
Here is the code:
import acm.program.*;
import java.io.*;
import java.util.*;
import acm.graphics.*;
import java.awt.*;
public class Crossword extends GraphicsProgram {
public void run() {
String fileName = "crosswordfile.txt";
makeCrosswordPuzzle(fileName);
}
private static final int sqCon = 15; // constant for square x and y dimensions
private int y = 0;
public void makeCrosswordPuzzle(String fileName) {
BufferedReader rd;
int y = 0; // y value for the square being added during that loop. increments by sqCon after every line
int wordNumber = 1; // variable for numbers added to certain boxes. increments every time the program adds a number
try {
rd = new BufferedReader(new FileReader(fileName));
String line = rd.readLine(); //reads one line of the text document at a time and makes it a string
while (line != null) {
int x = 0;
for (int i = 0; i < line.length(); i++) {
char lineChar = line.charAt(i);// the character being examined for each loop
GRect whiteSq = new GRect(sqCon,sqCon); //GRect for blank squares
GRect blackSq = new GRect(sqCon,sqCon);//GRect for black squares
blackSq.setFilled(true);
blackSq.setFillColor(Color.BLACK);
if (lineChar == '#'){
add (blackSq,x,y);
}
if (Character.isLetter(lineChar)) {
add (whiteSq, x, y);
// if the element above or to the left of the current focus is null or blackSq, place the number and then increment wordNumber
GObject above = getElementAt(x+sqCon/2,y-sqCon/2);
GObject left = getElementAt(x-sqCon/2, y+sqCon/2);
GLabel wordNumberLabel = new GLabel(Integer.toString(wordNumber));
if (above == null || left == null || above == blackSq || left == blackSq) {
add(wordNumberLabel,x,y+sqCon);
wordNumber++;
}
}
x += sqCon;
}
line = rd.readLine();
y += sqCon;
}
rd.close();
}
catch (IOException e) {
throw new ErrorException(e);
}
}
}
Edited to add:
I copied your code over to my Eclipse and ran it. Here's the result.
You did fine on the upper half, but you missed the down numbers on the lower half.
Here's the same code, reformatted so it's easier to read.
import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import acm.graphics.GLabel;
import acm.graphics.GObject;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.ErrorException;
public class Crossword extends GraphicsProgram {
private static final long serialVersionUID = -7971434624427958742L;
public void run() {
// String fileName = "crosswordfile.txt";
String fileName = "C:/Eclipse/eclipse-4.2-work/com.ggl.testing/crosswordfile.txt";
makeCrosswordPuzzle(fileName);
}
private static final int sqCon = 15; // constant for square x and y
// dimensions
private int y = 0;
public void makeCrosswordPuzzle(String fileName) {
BufferedReader rd;
int y = 0; // y value for the square being added during that loop.
// increments by sqCon after every line
int wordNumber = 1; // variable for numbers added to certain boxes.
// increments every time the program adds a number
try {
rd = new BufferedReader(new FileReader(fileName));
String line = rd.readLine(); // reads one line of the text document
// at a time and makes it a string
while (line != null) {
int x = 0;
for (int i = 0; i < line.length(); i++) {
char lineChar = line.charAt(i);// the character being
// examined for each loop
GRect whiteSq = new GRect(sqCon, sqCon); // GRect for blank
// squares
GRect blackSq = new GRect(sqCon, sqCon);// GRect for black
// squares
blackSq.setFilled(true);
blackSq.setFillColor(Color.BLACK);
if (lineChar == '#') {
add(blackSq, x, y);
}
if (Character.isLetter(lineChar)) {
add(whiteSq, x, y);
// if the element above or to the left of the current
// focus is null or blackSq, place the number and then
// increment wordNumber
GObject above = getElementAt(x + sqCon / 2, y - sqCon
/ 2);
GObject left = getElementAt(x - sqCon / 2, y + sqCon
/ 2);
GLabel wordNumberLabel = new GLabel(
Integer.toString(wordNumber));
if (above == null || left == null || above == blackSq
|| left == blackSq) {
add(wordNumberLabel, x, y + sqCon);
wordNumber++;
}
}
x += sqCon;
}
line = rd.readLine();
y += sqCon;
}
rd.close();
} catch (IOException e) {
throw new ErrorException(e);
}
}
}
I followed the advice of my own comment. I created the crossword puzzle answer, numbered the crossword puzzle answer, and finally drew the crossword puzzle answer.
Here's the applet result:
I kept a List of crossword puzzle cells. That way, I could determine the length and the width of the puzzle by the number of characters on a row and the number of rows of the input text file. I didn't have to hard code the dimensions.
For each crossword cell, I kept track of whether or not it was a letter, and whether or not it was a dark space.
When determining where to put the numbers, I followed 2 rules.
An across number is placed where the cell left of the cell is empty or dark, and there are three or more letters across.
A down number is placed where the cell above the cell is empty or dark, there are three or more letters down, and there is no across number.
You can see in the code that I had to do some debug printing to get the crossword puzzle clue numbering correct. I broke the process into many methods to keep each method as simple as possible.
Finally, I drew the crossword puzzle answer from the information in the List.
Here's the code:
import java.awt.Color;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import acm.graphics.GLabel;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.ErrorException;
public class Crossword extends GraphicsProgram {
private static final boolean DEBUG = false;
private static final long serialVersionUID = -7971434624427958742L;
private List<CrosswordCell> crosswordCellList;
#Override
public void run() {
this.crosswordCellList = new ArrayList<CrosswordCell>();
// String fileName = "crosswordfile.txt";
String fileName = "C:/Eclipse/eclipse-4.2-work/" +
"com.ggl.testing/crosswordfile.txt";
try {
readCrosswordAnswer(fileName);
if (DEBUG) printCrosswordAnswer();
numberCrosswordCells();
if (DEBUG) printCrosswordAnswer();
drawCrosswordAnswer();
} catch (FileNotFoundException e) {
throw new ErrorException(e);
} catch (IOException e) {
throw new ErrorException(e);
}
}
private void readCrosswordAnswer(String fileName)
throws FileNotFoundException, IOException {
BufferedReader reader =
new BufferedReader(new FileReader(fileName));
String line = "";
int row = 0;
while ((line = reader.readLine()) != null) {
for (int column = 0; column < line.length(); column++) {
CrosswordCell cell = new CrosswordCell(column, row);
char lineChar = line.charAt(column);
if (lineChar == '#') {
cell.setDarkCell(true);
} else if (Character.isLetter(lineChar)) {
cell.setLetter(true);
}
crosswordCellList.add(cell);
}
row++;
}
reader.close();
}
public void printCrosswordAnswer() {
for (CrosswordCell cell : crosswordCellList) {
System.out.println(cell);
}
}
private void numberCrosswordCells() {
int clueNumber = 1;
for (CrosswordCell cell : crosswordCellList) {
if (cell.isLetter()) {
clueNumber = testCell(cell, clueNumber);
}
}
}
private int testCell(CrosswordCell cell, int clueNumber) {
Point p = cell.getLocation();
CrosswordCell leftCell = getLeftCell(p.x, p.y);
List<CrosswordCell> acrossList = getRightCells(p.x, p.y);
if (DEBUG) {
System.out.print(p);
System.out.println(", " + leftCell + " " +
acrossList.size());
}
if ((leftCell == null) && (acrossList.size() >= 3)) {
cell.setClueNumber(clueNumber++);
} else {
CrosswordCell aboveCell = getAboveCell(p.x, p.y);
List<CrosswordCell> downList = getBelowCells(p.x, p.y);
if (DEBUG) {
System.out.print(p);
System.out.println(", " + aboveCell + " " +
downList.size());
}
if ((aboveCell == null) && (downList.size() >= 3)) {
cell.setClueNumber(clueNumber++);
}
}
return clueNumber;
}
private CrosswordCell getAboveCell(int x, int y) {
int yy = y - 1;
return getCell(x, yy);
}
private CrosswordCell getLeftCell(int x, int y) {
int xx = x - 1;
return getCell(xx, y);
}
private List<CrosswordCell> getBelowCells(int x, int y) {
List<CrosswordCell> list = new ArrayList<CrosswordCell>();
for (int i = y; i < (y + 3); i++) {
CrosswordCell cell = getCell(x, i);
if (cell != null) {
list.add(cell);
}
}
return list;
}
private List<CrosswordCell> getRightCells(int x, int y) {
List<CrosswordCell> list = new ArrayList<CrosswordCell>();
for (int i = x; i < (x + 3); i++) {
CrosswordCell cell = getCell(i, y);
if (cell != null) {
list.add(cell);
}
}
return list;
}
private CrosswordCell getCell(int x, int y) {
for (CrosswordCell cell : crosswordCellList) {
Point p = cell.getLocation();
if ((p.x == x) && (p.y == y)) {
if (cell.isDarkCell()) {
return null;
} else if (cell.isLetter()){
return cell;
} else {
return null;
}
}
}
return null;
}
private void drawCrosswordAnswer() {
int sqCon = 32;
for (CrosswordCell cell : crosswordCellList) {
Point p = cell.getLocation();
if (cell.isDarkCell()) {
drawDarkCell(p, sqCon);
} else if (cell.isLetter()) {
drawLetterCell(cell, p, sqCon);
}
}
}
private void drawDarkCell(Point p, int sqCon) {
GRect blackSq = new GRect(sqCon, sqCon);
blackSq.setFilled(true);
blackSq.setFillColor(Color.BLACK);
add(blackSq, p.x * sqCon, p.y * sqCon);
}
private void drawLetterCell(CrosswordCell cell, Point p, int sqCon) {
GRect whiteSq = new GRect(sqCon, sqCon);
add(whiteSq, p.x * sqCon, p.y * sqCon);
if (cell.getClueNumber() > 0) {
String label = Integer.toString(cell.getClueNumber());
GLabel wordNumberLabel = new GLabel(label);
add(wordNumberLabel, p.x * sqCon + 2, p.y * sqCon + 14);
}
}
class CrosswordCell {
private boolean darkCell;
private boolean isLetter;
private int clueNumber;
private Point location;
public CrosswordCell(int x, int y) {
this.location = new Point(x, y);
this.clueNumber = 0;
this.darkCell = false;
this.isLetter = false;
}
public boolean isDarkCell() {
return darkCell;
}
public void setDarkCell(boolean darkCell) {
this.darkCell = darkCell;
}
public boolean isLetter() {
return isLetter;
}
public void setLetter(boolean isLetter) {
this.isLetter = isLetter;
}
public int getClueNumber() {
return clueNumber;
}
public void setClueNumber(int clueNumber) {
this.clueNumber = clueNumber;
}
public Point getLocation() {
return location;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CrosswordCell [location=");
builder.append(location);
builder.append(", clueNumber=");
builder.append(clueNumber);
builder.append(", darkCell=");
builder.append(darkCell);
builder.append(", isLetter=");
builder.append(isLetter);
builder.append("]");
return builder.toString();
}
}
}

Analysing word frequencies in applet

i am writing a program in applet to measure the frequencies of word lengths in a given amount of text and display these frequencies during applet. i have written the program and it debugs without error.
however the output says i have 255 words of every length in the text i input, i have been staring at this for hours with no luck, i am aware that the drawstring method lists these outputs horizontally which i will be fixing at a later time.
i am assuming the problem resides in the analyseText method.
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.awt.Graphics;
import java.util.*;
public class StringAnalysis extends Applet implements MouseListener, ActionListener {
Font arielBold;
Label pr_Label;
TextField pr_txt;
int textFieldSize = 15;
Button pr_input1, pr_input2, pr_input3;
String textToAnalyse = ("Nothing has been entered.");
boolean output = false;
String testing ="";
//create array to show respective lengths of words
int [] lengthsOfWords = new int[textFieldSize];
//first we must separate strings from spaces and populate array for comparison
String [] arrayOfWords = new String[textFieldSize];
public void init() {
pr_Label = new Label("Enter the text you wish to analise: ");
add(pr_Label);
pr_txt = new TextField(textFieldSize);
add(pr_txt);
pr_input1 = new Button("Analyse");
pr_input2 = new Button("Reset");
add(pr_input1);
add(pr_input2);
pr_input1.addActionListener(this);
pr_input2.addActionListener(this);
}
public void start (){
setSize(1000, 500);
arielBold = new Font ("Ariel", Font.BOLD, 20);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == pr_input2) {
showStatus("Resseting....");
reset();
}
else if (e.getSource() == pr_input1){
showStatus("Analysing...a");
textToAnalyse = pr_txt.getText();
analyseText(textToAnalyse);
}
}
public void paint(Graphics g) {
String statsToOutput = ("There are:" + "\n" );
int counter = 1;
for (int lengths: lengthsOfWords) {
statsToOutput = statsToOutput +lengthsOfWords[0] + " words of length " + counter + "\n ";
counter ++;
}
if (output = true){
g.drawString(statsToOutput, 25, 200);
g.drawString("The text to be analysed is: " + textToAnalyse, 25, 100);
showStatus("Finished.");
}
else if (output = false){
g.setFont(arielBold);
g.drawString(textToAnalyse,50, 100);
showStatus("Finished.");
}
}
public void analyseText(String text){
///////////////////////////////////////////////////////////////////////////////////////////////////////
int position1 = 0, position2 = 0;
String newWord = "";
String currentLetter;
int pos1 = 0, pos2 = 0;
for ( pos1 = 0; pos1 <= arrayOfWords.length-1; pos1++) {
//Initializes a string object for each address in array
for (position1 = 0; position1 <= text.length()-1; position1++){
//steps through each character in text
currentLetter = Character.toString(text.charAt(position1));
if (currentLetter.matches("[A-Z][a-z][0-9]")) {
//checks if character is alphanumeric using regular expressions (regex)
newWord = newWord + currentLetter;
//if passes regex then ads character to word
}
}
if (newWord.length() > 0) {
pos1 = arrayOfWords.length;
}
arrayOfWords[pos1] = newWord;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
emptyArrayInt(lengthsOfWords);
//now compare each word with rest of array\
for ( pos2 = 0; pos2 <= arrayOfWords.length-1; pos2++) {
position2 = 0;
for (position2 = 0; position2 <= arrayOfWords.length-1; position2++){
if (arrayOfWords[pos2].length() == arrayOfWords[position2].length());
lengthsOfWords[arrayOfWords[pos2].length()] = lengthsOfWords[arrayOfWords[pos2].length()] + 1;
}
}
showStatus("finished analysing.");
output = true;
repaint();
}
public void emptyArrayInt(int[] array) {
int position = 0;
for (position = 0; position <= array.length-1; position ++)
array[position] = 0;
}
public void emptyArrayStr(String[] array) {
int position = 0;
for (position = 0; position <= array.length-1; position ++)
array[position] = "";
}
public void reset() {
pr_txt.setText("");
textToAnalyse = ("Nothing has been entered.");
emptyArrayInt(lengthsOfWords);
emptyArrayStr(arrayOfWords);
//repaint();
showStatus("Reset Successful.");
repaint();
}
public void mouseClicked(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
i would appreciate any help on this please, (I'm desperate).
Let's try section of code :
private Map<String, int> freqWords = new HashMap<String, int>();
public void analyzeText(String text) {
// You can split with another type of delimiter
String regex = ....
String[] inputs = text.split(regex);
for (String s : inputs) {
if(freqWords.containtsKey(s)) {
int frequency = inputs.get(s);
frequency++;
inputs.put(s, frequency);
} else {
inputs.put(s, 1);
}
}
}
Hope that it can help you. The main point here is you should use data structure Map to store the frequency words.

Categories