I'm trying to make the game Dots and I have already figured out a way to generate random dots using an int[][]. I've also created a method to remove dots if they are next to each other and have the same colour when selected. My playfield is 7 by 7 and is filled with JButtons (which could also be JLabels). Now I need to find a way to drag over a few dots and select them if they are the same colour as the initial dot, but whenever I try to do something like that, I always end up either selecting the initial dot itself and send that button's coordinates whenever I move the mouse, or select the x and y values for the pointer on the screen.
Here is the relevant code:
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
final int finalJ = j;
final int finalI = i;
playField[i][j].addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
try {
while (true) {
dotsController.beginZet(finalI, finalJ);
}
} catch (DotsException e1) {
e1.printStackTrace();
}
}
});
playField[i][j].addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
try {
dotsController.doeZet();
} catch (DotsException e1) {
e1.printStackTrace();
}
}
});
}
}
Related
Instead of hard coding 64 buttons to create a board did a 2D array and I need to get the array coordinates. This is the code I tried using and the error I got.
code:
public void mousePressed(MouseEvent e)
{
JButton[][] clicked = (JButton[][])e.getSource();
int x = clicked.length;
int y = clicked[0].length;
board[x][y].setIcon(selected);
}
Error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JButton cannot be cast to [[Ljavax.swing.JButton;
I figured out how to not hard code each option use a for loop for the action listener and use variables.
Solution:
public void mousePressed(MouseEvent e)
{
JButton clicked = (JButton)e.getSource();
for(int x = 0; x<8; x++)
{
for(int y = 0;y<8;y++)
{
if(clicked == board[x][y])
{
occupied[x][y] = true;
board[x][y].setIcon(selected);
}
}
}
}
The idea of my program is to select one name from a list that saved before in other JFrame. I'd like to print in the label all names one after the other with small delay between them, and after that stop at one of them. The problem is that lbl.setText("String"); doesn't work if there is more than one setText code.
Here is the part of my code :
public void actionPerformed(ActionEvent e)
{
if (RandomNames.size != 0)
{
for (int i = 0; i < 30; i++)
{
int rand = (int)(Math.random() * RandomNames.size);
stars.setText(RandomNames.list.get(rand));
try
{
Thread.sleep(100);
}
catch (InterruptedException err)
{
err.printStackTrace();
}
}
int rand2 = (int)(Math.random() * RandomNames.size);
stars.setText(RandomNames.list.get(rand2));
RandomNames.list.remove(rand2);
RandomNames.size = RandomNames.list.size();
}
if (RandomNames.list.size() == 0)
{
last.setText("\u062A\u0645 \u0638\u0647\u0648\u0631 \u062C\u0645\u064A\u0639 \u0627\u0644\u0623\u0633\u0645\u0627\u0621 \u0627\u0644\u062A\u064A \u0641\u064A \u0627\u0644\u0642\u0627\u0626\u0645\u0629 !");
}
}
Don't use a loop or Thread.sleep. Just use a javax.swing.Timer. The following will cause 30 iterations occurring every 1000 milliseconds. You can adjust the code in the actionPerformed accordingly to what you wish to happen every so many milliseconds.
int count = 0;
...
Timer timer = new Timer(1000, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
if (count == 30) {
((Timer)e.getSource()).stop();
} else {
int rand = (int) (Math.random()* RandomNames.size);
stars.setText(RandomNames.list.get(rand));
count++;
}
}
});
timer.start();
If you want you can just set up the Timer in the constructor, and start() it in the actionPerformed of another button's listener.
See more at How to use Swing Timers
This class is in a program for a game I'm writing that is basically Space Invaders. I'm getting Exceptions for some reason and I don't see why I should be getting them.
Here's the class in question, but I can post all the code if necessary:
public class GamePanel extends JPanel {
Launcher launcher1;
Background bground1;
Shot shot;
public ArrayList<Shot> shots;
public int numShots;
public static int counter;
public GamePanel() throws IOException {
super();
this.shots = new ArrayList<>();
this.numShots = 0;
launcher1 = new Launcher();
bground1 = new Background();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bground1.background, 0, 0, getWidth(), getHeight(), null);
g.drawImage(launcher1.baldEagleImage, launcher1.getLxCoord(), launcher1.lyCoord, null);//paint the launcher
while (counter == 1) {
for (int i = 0; i < shots.size(); i++) {
g.drawImage(shots.get(i).mcDShotImage, shots.get(i).staticXLauncherCoord, shots.get(i).getSyCoord(), null);
}
}
}
public void move(GamePanel gamePanel) {
launcher1.moveX();
if (numShots > 0) {
moveShot();
}
repaint();
}
public void moveShot() {
for (int i = 0; i < numShots; i++) {//loop to move all the shots
if (shots.get(i).getSyCoord() > 10) { // THIS IS THE ISSUE, but I don't know why
counter = 1;
shots.get(i).moveY();
repaint();
} else {
counter = 0;
shots.remove(i);
repaint();
}
}
}
public void createShots() {
try {
for (int j = 0; j < numShots; j++) {
shots.add(new Shot());
}
} catch (IOException | IndexOutOfBoundsException e) {
System.out.println("caught an exception" + e);
}
}
}
The problem is in this piece of code:
} else {
counter = 0;
shots.remove(i);
repaint();
}
You remove an item from shots without adjusting numShots, causing an index out of bounds exception in one of subsequent iterations.
To fix this, either add numShots-- in the else branch, or use the built-in size() method that returns the count of elements in a list instead: unlike numShots which you need to maintain, shots.size() never gets "out of sync" with the actual count.
In the above line of code what is apparent is the issue is numShots is > shots.size() (because you also remove shots.
Since I couldn't where you are incrementing the numShots, in this piece of code one simple (albeit not sure from your logic perspective) change your for loop as below:
for (int i = 0; i < shots.size(); i++)
I'm trying to save an ArrayList to a text file in a particular format. It's in the correct format but it only prints out the color of one element in the ArrayList of blocks. I know the problem lies with the getBlockColor() method, what's the best way to implement this method? Here's what I've got so far.
This is the method that is in the class with the ArrayList of frames.
public void saveFrames(String fileName) {
System.out.println("**method save writes data back to a file "
+ fileName);
try {
PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(fileName)));
outfile.println(frames.size());
outfile.println(Frame.getCOLUMNS());
for (Frame f : frames) {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
Color a = f.getBlockColor();
if (a.equals(Color.white)) {
outfile.print("w");
}
if (a.equals(Color.orange)) {
outfile.print("o");
}
if (a.equals(Color.red)) {
outfile.print("r");
}
if (a.equals(Color.yellow)) {
outfile.print("y");
}
if (a.equals(Color.green)) {
outfile.print("g");
}
if (a.equals(Color.blue)) {
outfile.print("b");
}
}
outfile.println("");
}
}
outfile.close();
}
catch (IOException e) {
System.out.println("file not found try again");
}
}
This is the code from the frame that is supposed to get the color of the blocks.
public Color getBlockColor() {
for (int ROWS = 0; ROWS < 20; ROWS++) {
for (int COLUMNS = 0; COLUMNS < 20; COLUMNS++) {
blockColor = blocks[ROWS][COLUMNS].getBackground();
}
}
return blockColor;
}
I think you made a small mistake in getting the block color.
I guess you were supposed to return the color for a specific row and column, like this:
public Color getBlockColor(int row, int column) {
return blocks[row][column].getBackground();
}
I wrote the code below. It checks input from a JTextField and ensures the user is typing in numbers. If not the box flashes red and the invalid character is removed.
The tipArray[] is an array of JTextFields that I add to the JFrame with a loop.
How can I apply the following code to every possible array (tipArray[0], tipArray[1] ....tipArray[6])?
tipArray[6].addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
char keyChar = e.getKeyChar();;
char[] badCharArray = "abcdefghijklmnopqrstuvwxyz-`~!##$%^&*()[,]{}<>_+=|\"':;?/ ".toCharArray();
for (int i = 0; i < badCharArray.length; i++) {
if (badCharArray[i] == keyChar) {
tipArray[1].setBackground(Color.RED);
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (tipArray[6].getBackground() == Color.RED) {
if (tipArray[6].getText() != "0"){
String removeLastLetter = tipArray[1].getText().substring(0, tipArray[6].getText().length()-1);
tipArray[6].setText(removeLastLetter);
tipArray[6].setBackground(Color.WHITE);
}
}
}
});
The loops I have tried dont work:
for (int i = 0; i <= 6; i++) {
tipArray[i].addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
char keyChar = e.getKeyChar();;
char[] badCharArray = "abcdefghijklmnopqrstuvwxyz-`~!##$%^&*()[,]{}<>_+=|\"':;?/ ".toCharArray();
for (int x = 0; x < badCharArray.length; x++) {
if (badCharArray[x] == keyChar) {
tipArray[i].setBackground(Color.RED);
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (tipArray[i].getBackground() == Color.RED) {
if (tipArray[i].getText() != "0"){
String removeLastLetter = tipArray[i].getText().substring(0, tipArray[i].getText().length()-1);
tipArray[i].setText(removeLastLetter);
tipArray[i].setBackground(Color.WHITE);
}
}
}
});
}
^The above results in all of the variable i's after line "if (badCharArray[x] == keyChar) {" having a syntax error.
Change your counter in the for loop in the second one to be a different variable (z instead of i perhaps). You have a duplicate variable the way it is now (two i's). Also, it is recommended you use a DocumentListener, not KeyListener, for checking for invalid characters, as KeyListeners sometimes fail.