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

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());
}
}
}
}

Related

How to keep BestScores in a File JAVA

I developed a game and I want to keep track of the Top-3 Best Scores in a file, so that we don't lose the Scores after closing the game. It's not working properly and I don't know why.
- The Best Scores are Integers, and the lowest it is the better. The Best Score is the lowest.
- It is not saving the Scores in ascending Order
It does create a file and it appears to work with the main tests but after a few Scores being add, it does not sort the array in ascending order, so the file is in the wrong way.
package pt.iscte.dcti.poo.sokoban.starter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
import pt.iul.ista.poo.utils.Point2D;
public class BestScores {
public int[] bestScore = new int[3];
public final int level;
public BestScores(int level) {
this.level = level;
}
public int[] getBestScore() {
return bestScore;
}
//Register BestScores
public void setBestScore(int score) {
for(int i = 0; i < bestScore.length; i++) {
if(bestScore[i] == 0) {
bestScore[i] = score;
return;
}
}
Arrays.sort(bestScore);
for (int i = 0; i < bestScore.length-1; i++) {
if(bestScore[i] == 0) {
int box1 = bestScore[i];
bestScore[i] = bestScore[i+1];
bestScore[i+1] = box1;
}
}
addBestScore(score);
}
public void addBestScore(int score) {
if(score < bestScore[bestScore.length - 1])
bestScore[bestScore.length - 1] = score;
Arrays.sort(bestScore);
for (int i = 0; i < bestScore.length-1; i++) {
if(bestScore[i] == 0) {
int box1 = bestScore[i];
bestScore[i] = bestScore[i+1];
bestScore[i+1] = box1;
}
}
}
public int getTopOne() {
return bestScore[0];
}
public int getLevel() {
return level;
}
//Check if the file exists, else create it
public void searchFile() {
File tmpDir = new File("bestScores/BestScore_" + level + ".txt");
if (!tmpDir.exists())
createOrAddScore();
else {
checkScores(tmpDir);
createOrAddScore();
}
}
//Create file with Scores if they exist.
public void createOrAddScore() {
try {
PrintWriter writer = new PrintWriter(new File("bestScores/BestScore_" + level + ".txt"));
writer.println("BestScores: ************Level:" + level + "************");
for(int i = 0; i < bestScore.length; i++) {
if(bestScore[i] != 0)
writer.println((i+1) + "º " + bestScore[i] + " " + "moves.");
}
writer.close();
}
catch (FileNotFoundException e) {
System.err.println("problema a escrever o ficheiro");
}
}
//Read File and return Best Scores, so that we don't lose the bestScores even after closing the game :D.
public void checkScores(File file) {
int[] array = new int[3];
try {
Scanner scanner = new Scanner(file);
String title_line = scanner.nextLine();
int i = 0;
while(scanner.hasNextLine()) {
String[] line = scanner.nextLine().split(" ");
array[i] = Integer.parseInt(line[1]);
i++;
}
}
catch (FileNotFoundException e) {
System.err.println("problema a escrever o ficheiro");
}
for (int i = 0; i < array.length; i++)
if(array[i] != 0)
setBestScore(array[i]);
}
public static void main(String[] args) {
// BestScores bS = new BestScores(4);
//test1 No BEstScores
// bS.searchFile();
//test2 WithBestScores
// bS.setBestScore(40);
// bS.setBestScore(15);
bS.setBestScore(50);
// bS.setBestScore(30);
// bS.setBestScore(10);
// bS.searchFile();
// int[] test = bS.getBestScore();
// for(int i = 0; i < test.length; i++)
// System.out.println(test[i]);
//test3 With file with Scores
// bS.searchFile();
// int[] test = bS.getBestScore();
// for(int i = 0; i < test.length; i++)
// System.out.println(test[i]);
}
}

MLFQ only functions when other class runs

I have a multi-level feedback class which I am not sure what its doing - it only ever seems to print the output I want when I run a pre-emptive multi-level class before it, when I don't it prints a different output. I am not sure how these are connected and making this happen.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MultiLevelFeedback {
List<Process> processList;
private int timeQuantum1;
private int timeQuantum2;
private int count;
int j=0;
private int ganntP[];
private int ganntT[];
private int totalWaitingTime = 0;
private int totalTurnAroundTime = 0;
private float avgWatingTime = 0;
private float avgTurnaroundTime = 0;
MultiLevelFeedback(List<Process> processList, int timeQuantum1,int timeQuantum2) {
count = processList.size();
ganntT=new int[200];
ganntP=new int[200];
this.timeQuantum1 = timeQuantum1;
this.timeQuantum2 = timeQuantum2;
this.processList=new ArrayList<Process>();
for(Process p : processList)
{
this.processList.add(new Process(p.getProcessId(), p.getArrivalTime(), p.getBurstTime(),p.getPriority()));
}
Collections.sort(this.processList, Process.BY_PRIORITY);
}
public void simulate() {
int currentTime =0;
int remainingProcess = count;
while (remainingProcess > processList.size()/2)
{
int clockTime=currentTime;
for (int i = 0; i < count; i++)
{
Process current = processList.get(i);
if(currentTime<current.getArrivalTime())
break;
if (current.getStartTime() == -1)
current.setStartTime(currentTime);
ganntP[j]=current.getProcessId();
ganntT[j]=currentTime;
j++;
if (current.getRemainingTime() <= timeQuantum1 && current.getEndTime()==-1)
{
current.setEndTime(currentTime + current.getRemainingTime());
currentTime += current.getRemainingTime();
current.setRemainingTime(0);
remainingProcess--;
}
else if (current.getRemainingTime()>timeQuantum1)
{
currentTime += timeQuantum1;
current.setRemainingTime(current.getRemainingTime()-timeQuantum1);
}
}
if(clockTime==currentTime)
{
currentTime++;
}
}
while (remainingProcess > processList.size()/2)
{
int clockTime=currentTime;
for (int i = 0; i < count; i++)
{
Process current = processList.get(i);
if(currentTime<current.getArrivalTime())
break;
if (current.getStartTime() == -1)
current.setStartTime(currentTime);
ganntP[j]=current.getProcessId();
ganntT[j]=currentTime;
j++;
if (current.getRemainingTime() <= timeQuantum2 && current.getEndTime()==-1)
{
current.setEndTime(currentTime + current.getRemainingTime());
currentTime += current.getRemainingTime();
current.setRemainingTime(0);
remainingProcess--;
}
else if (current.getRemainingTime()>timeQuantum2)
{
currentTime += timeQuantum2;
current.setRemainingTime(current.getRemainingTime()-timeQuantum2);
}
}
if(clockTime==currentTime)
{
currentTime++;
}
}
for(int i=0;i<count;i++)
{
Process current=processList.get(i);
if(current.getRemainingTime()>0 )
{
if(currentTime<current.getArrivalTime())
{
currentTime=current.getArrivalTime();
current.setStartTime(currentTime);
}
current.setEndTime(currentTime+current.getRemainingTime());
currentTime+=current.getRemainingTime();
}
}
for (int i = 0; i < count; i++)
{
Process current = processList.get(i);
current.setWaitingTime(current.getEndTime()-current.getBurstTime()-current.getArrivalTime());
current.setTurnaroundTime(current.getEndTime() - current.getArrivalTime());
totalWaitingTime += current.getWaitingTime();
totalTurnAroundTime += current.getTurnaroundTime();
}
avgWatingTime = (float) totalWaitingTime / count;
avgTurnaroundTime = (float) totalTurnAroundTime / count;
}
public void printResult()
{
System.out.println("Simulation result of MultiLevelFeedback ");
System.out.println("PId ArrivalT BurstT Priority StartT EndT WaitingT TurnAroundT");
for (Process p : processList)
{
System.out.println(p);
}
System.out.println("Average Waiting Time of MultiLevelFeedback "
+ avgWatingTime);
System.out.println("Average TurnAround Time of MultiLevelFeedback "
+ avgTurnaroundTime);
for(int i=0;i<j;i++)
{
System.out.println("time "+ganntT[i]+" process "+ganntP[i]);
}
System.out.println();
}
}
I am confused as there's nothing in the mlfq class which has anything to do with the pre-emptive multi-level class - they are both separate algorithms - except it is differing the output when I run both.

Java 2 dimensional array throwing out of bounds

I'm new with arrays.
This program i have created is throwing an out of bounds error with every method inside of the BlueJays class.
To be honest, im not even sure if im searching through the array right. Any help would be appreciated.
Thanks
This is my main
public class Lab1 {
static final int NBPLAYERS = 11;
static final int NBMONTHS = 6;
public static void main(String[] args) {
String[] month = {"April", "May","June", "July", "August","September"};
String[] players = {"Colabello","Donaldson","Smoak","Martin","Goins","Encarnacion","Carrera","Tulowitzki","Pillar","Bautista","Travis"};
double[][] battingAvg = {
{0,.368,.300,.224,.386,.268},
{.319,.306,.269,.287,.324,.296},
{.229,.310,.213,.191,.203,.262},
{.197,.327,.239,.256,.138,.213},
{.276,.236,.172,.240,.314,.279},
{.205,.225,.303,.241,.407,.279},
{0,.302,.282,.244,.333,.231},
{0,0,0,.357,.214,.237},
{.273,.181,365,.283,.240,.323},
{.164,.295,.226,.219,.286,.293},
{.325,.189,.313,.368,0,0}};
double [][] onBase = {
{.417,.330,.286,.413,.362,.429},
{.370,.373,.322,.370,.408,.403},
{.372,.333,.275,.283,.243,.324},
{.367,.362,.329,.322,.263,.300},
{.323,.278,.221,.286,.442,.347},
{.258,.333,.382,.384,.460,.411},
{0,.357,.333,.277,.333,.313},
{0,0,0,.400,.325,.250},
{.297,.237,.380,.323,.283,.363},
{.325,.418,.388,.300,.370,.436},
{.393,.246,.313,.421,0,0}};
PlayerStats Player;
BlueJays team = new BlueJays(NBPLAYERS, NBMONTHS);
team.getHighestSingleMonthBattingAvg();
team.getHighestOnBase(5);
team.getLowestBattingAvg(6);
team.getBestMonth("Bautista");
team.getBestOverallRecord();
team.getLowestOnBase();
}
}
This is my PlayerStats which has accessor/mutator methods.
class PlayerStats {
private String name;
private int month;
private double battAvg, onBase;
public PlayerStats(String name, int month, double battingAvg, double onBase2) {
this.name = name;
this.month = month;
this.battAvg = battingAvg;
this.onBase = onBase2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public double getAvg() {
return battAvg;
}
public double getOnBase() {
return onBase;
}
public double getBoth() {
return battAvg + onBase;
}
}
And this is the class where the 2d array is created.
class BlueJays {
int nbPlayers;
int nbMonths;
int j = 0;
int highestBattingAvg;
int highestBattingMonth;
String highestBattingPlayer;
int highestOnBase;
int lowestAvg;
String lowestAvgPlayer;
int highestOverall;
String highestOverallPlayer;
int lowestOnBase;
int lowestOnBaseMonth;
String highestOnBasePlayer;
double bestOverAllMonth;
public BlueJays(int nbplayers2, int nbmonths2) {
this.nbPlayers = nbplayers2;
this.nbMonths = nbmonths2;
}
PlayerStats[][] stats = new PlayerStats[nbPlayers][nbMonths];
PlayerStats setPlayerStatsCell(PlayerStats player, int iPlayer, int iMonth) {
return player;
}
PlayerStats getHighestSingleMonthBattingAvg() {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getAvg();
if(highestBattingAvg < stats[i][j].getAvg()) {
highestBattingMonth = stats[i][j].getMonth();
highestBattingPlayer = stats[i][j].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Highest average batting player for the month " + highestBattingMonth + " is " + highestBattingPlayer);
}
}
return null;
}
PlayerStats getHighestOnBase(int month) {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][month].getOnBase();
if(highestOnBase < stats[i][month].getOnBase()) {
highestOnBasePlayer = stats[i][month].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Highest average onBase player for the month " + month + highestOnBasePlayer);
}
}
return null;
}
public PlayerStats getLowestBattingAvg(int month) {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][month].getOnBase();
if(lowestAvg > stats[i][month].getAvg()) {
lowestAvgPlayer = stats[i][month].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Lowest average batting player for the month " + month + " is " + lowestAvgPlayer);
}
}
return null;
}
PlayerStats getBestMonth(String player) {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getBoth();
if(bestOverAllMonth > stats[i][j].getAvg() && stats[i][j].getName().contains(player)) {
bestOverAllMonth = stats[i][j].getBoth();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Best month for the player " + player + " is " + bestOverAllMonth);
}
}
return null;
}
public String getBestOverallRecord() {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getBoth();
if(highestOverall < stats[i][j].getBoth()) {
highestOverallPlayer = stats[i][j].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Highest overall record is " + highestOverallPlayer);
}
}
return null;
}
public PlayerStats getLowestOnBase() {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getOnBase();
if(lowestOnBase > stats[i][j].getOnBase()) {
double lowestOnBase = stats[i][j].getOnBase();
if(lowestOnBase > 0) {
lowestAvgPlayer = stats[i][j].getName();
} else {
i++;
}
if (i == nbMonths) {
j++;
i = 0;
}
}
System.out.println("Lowest On Base is " + lowestOnBase);
}
}
return null;
}
}
Here is the exception
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at BlueJays.getHighestSingleMonthBattingAvg(BlueJays.java:42)
at Lab1.main(JonathanRoy_Lab1.java:40)
Your problem may lay here:
// ... lots of other stuff
public BlueJays(int nbplayers2, int nbmonths2) {
this.nbPlayers = nbplayers2;
this.nbMonths = nbmonths2;
}
PlayerStats[][] stats = new PlayerStats[nbPlayers][nbMonths];
If you initialize an instance of your BlueJay-class it will create the array before you set the values nbPlayers and nbMonths. So you'll have an array of the size 0 and 0.
To avoid this you have to do following:
// ... lots of other stuff
public BlueJays(int nbPlayers, int nbMonths) {
this.nbPlayers = nbPlayers;
this.nbMonths = nbMonths;
// doesn't matter if you take the parameters or fields
this.stats = new PlayerStats[nbPlayers][nbMonths];
}
Hope I helped you out :)
I don't know what the exception is but here's what I got by scanning through your code.
You never reset j so most of your function calls won't make it past the first comparison.
The function call team.getLowestBattingAvg(6); uses the index 6, but since nbMonths=6, the highest index you can use is 5 (the indices go from 0 to 5 inclusive).

CardPile Index Out of bounds

I'm currently trying to convert my code to ArrayList and I can't seem to make it work. I'm running the whole program and it tells me Index out bounds. I'm sure I forgot to add the size of the array for the cards, but I don't know how to add it. Thanks for the help!
Edit: The error I get is at the bottom. Also, it tells me to go to the removeTop method. It looks fine there.
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
public class CardPile {
private ArrayList<Card> cards = new ArrayList<Card>();
private static Random r = new Random(1);
public void addToBottom(Card c) {
if (this.cards.size() == 52) {
System.out.println("The CardPile is full. You cannot add any more Card objects.");
}
this.cards.add(c);
}
public Card removeCard(Card c) {
if (this.cards.contains(c)) {
this.cards.remove(c);
}
return null;
}
public Card removeTop() {
return this.cards.remove(0);
}
public int searchValue(int value) {
int count = 0,
for (int i = 0;i < this.cards.size();i++) {
if (this.cards.get(i).getValue() == value) {
count++;
}
}
//System.out.println("Count = "+count);
return count;
}
public Card[] removeAll(int value)
//System.out.println("(removeAll) cards ="+ cards);
int count = searchValue(value);
Card[] removed = new Card[count];
int deletedCount = 0;
int i = 0;
while (deletedCount < count) {
if (this.cards.get(i).getValue() == value) {
removed[deletedCount] = this.cards.remove(i);
deletedCount++;
} else {
i++;
}
}
return removed;
}
public int getNumberCards() {
return this.cards.size();
}
public String toString() {
if (this.cards.isEmpty()) {
return "";
}
String builder = "";
for (int i = 0;i < this.cards.size() - 1;i++) {
builder = builder + this.cards.get(i) + ", ";
}
builder = builder + this.cards.get(this.cards.size() - 1);
return builder;
}
public void shuffle() {
if (this.cards.isEmpty()) {
return;
}
for (int count = 0; count < 100000;count++) {
int i = r.nextInt(this.cards.size());
int j = r.nextInt(this.cards.size());
Card temp = this.cards.get(i);
this.cards.set(i, this.cards.get(j));
this.cards.set(j, temp);
}
}
public static CardPile makeFullDeck() {
CardPile deck = new CardPile();
for (int suit = 0;suit < 4;suit++) {
for (int value = 1; value <= 13;value++) {
deck.addToBottom(new Card(suit, value));
}
}
deck.shuffle();
return deck;
}
}
**Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at CardPile.removeTop(CardPile.java:40)
at GoFish.dealCards(GoFish.java:112)
at GoFish.main(GoFish.java:13)**
EDIT:
This is the Player class:
public class Player {
private boolean[] books;
private CardPile pile;
private static int MAXIMUM_VALUE_CARD = 13;
public Player()
{
this.pile = new CardPile();
this.books = new boolean[13]; //by default all are false
}
public boolean hasCard(int value)
{
return this.pile.searchValue(value) > 0;
}
public Card[] removeAll(int value)
{
return this.pile.removeAll(value);
}
public void addAll(Card[] cards)
{
for (int i = 0; i < cards.length; i++)
{
this.pile.addToBottom(cards[i]);
}
}
//optional additional method
public void addCard(Card card)
{
this.pile.addToBottom(card);
}
public int getNumberCards()
{
return this.pile.getNumberCards();
}
public int countBooks()
{
int count = 0;
for (int i = 0; i < MAXIMUM_VALUE_CARD; i++)
{
if (books[i])
{
count++;
}
}
return count;
}
public void addBook(int value)
{
this.books[value - 1] = true;
}
public void printHand()
{
System.out.println("Player's hand is " + this.pile);
}
}
And this is the GoFish class:
import java.util.Scanner;
public class GoFish {
private static Scanner reader;
public static void main(String[] args)
{
System.out.println("How many players?");
reader = new Scanner(System.in);
int numberPlayers = reader.nextInt();
Player[] players = createPlayersArray(numberPlayers);
int currentTurn = 0;
CardPile deck = CardPile.makeFullDeck();
dealCards(deck, players);
int maximumRetries = 2;
int numRetries = 0;
while(deck.getNumberCards() > 0 && players[currentTurn].getNumberCards() > 0)
{
updateBooks(players[currentTurn]);
if (numRetries == maximumRetries)
{
numRetries = 0;
currentTurn++;
if (currentTurn == numberPlayers)
{
currentTurn = 0;
}
}
System.out.println("Player " + currentTurn + ", here is your hand. What card would you like to ask for?");
players[currentTurn].printHand();
int queryCard = reader.nextInt();
System.out.println("And from whom would you like to get it from?");
int queryPlayer = reader.nextInt();
if (queryCard < 1 || queryCard > 13 || queryPlayer < 0 || queryPlayer >= numberPlayers || queryPlayer == currentTurn)
{
System.out.println("Invalid entries. Please retry");
numRetries++;
}
else
{
numRetries = 0;
boolean hasCard = players[queryPlayer].hasCard(queryCard);
if (hasCard)
{
System.out.println("Cards found!");
Card[] removed = players[queryPlayer].removeAll(queryCard);
players[currentTurn].addAll(removed);
}
else
{
System.out.println("Go fish!");
Card top = deck.removeTop();
System.out.println("You drew " + top);
players[currentTurn].addCard(top);
//check to make sure this extra card didn't form a book
//Note this could happen even if it doesn't match the card they were asking about
updateBooks(players[currentTurn]);
if (top.getValue() == queryCard)
{
System.out.println("You successfully went fishing!");
}
else
{
currentTurn++;
if (currentTurn == numberPlayers)
{
currentTurn = 0;
}
}
}
}
}
//calculate the winner now
int maxPlayer = 0;
int maxPlayerBooks = players[0].countBooks();
for (int i = 1; i < numberPlayers; i++)
{
int currentBooks = players[i].countBooks();
if (currentBooks > maxPlayerBooks)
{
maxPlayer = i;
maxPlayerBooks = currentBooks;
}
}
System.out.println("Congratulations! Player " + maxPlayer + " you have won the game by accumulating " + maxPlayerBooks + " books!");
}
private static Player[] createPlayersArray(int numPlayers)
{
Player[] players = new Player[numPlayers];
for (int i = 0; i < numPlayers; i++)
{
players[i] = new Player();
}
return players;
}
private static void dealCards(CardPile deck, Player[] players)
{
final int NUMBER_CARDS_PER_PLAYER = 7;
for (int i = 0; i < NUMBER_CARDS_PER_PLAYER * players.length; i++)
{
Card next = deck.removeTop();
players[i % players.length].addCard(next);
}
}
private static void updateBooks(Player player)
{
for (int i = 1; i <= 13; i++)
{
//alternative option would be to modify the hasCard method to return an int instead of boolean. Then we could just count (this is probably better design)
Card[] valued = player.removeAll(i);
if (valued.length == 4)
{
player.addBook(i);
}
else
{
player.addAll(valued);
}
}
}
}

accessing javascript from inside 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.

Categories