Lambda error in code - java

public static void buttonAdd(boolean[][] coord) {
for (int col = 0; col < SIZE; col++) {
for (int row = 0; row < SIZE; row++) {
Button square = new Button(coord[col][row]);
square.addActionListener((ActionEvent e) -> {
if (bombOrNot) { //if bomb is true
JOptionPane lose = new JOptionPane();
lose.setMessage("You Lose");
frame.add(lose);
System.exit(0);
} else { //if bomb is false
frame.remove(square);
}
frame.add(square);
}
}
}
This code is not compiling, it seems like there is something wrong with the lambda. It says that the closing bracket for the lambda is expected to be a ")".

indenting the way the compiler sees the indentation of your code and commenting where the error happens (obviously the compiler does not see your code in that way since it get converted to a stream of tokens - without any indentation)
// wrong code, just re-indented to clarify
public static void buttonAdd(boolean[][] coord) {
for (int col = 0; col < SIZE; col++) {
for (int row = 0; row < SIZE; row++) {
Button square = new Button(coord[col][row]);
square.addActionListener(
(ActionEvent e) -> {
if (bombOrNot) { //if bomb is true
JOptionPane lose = new JOptionPane();
lose.setMessage("You Lose");
frame.add(lose);
System.exit(0);
} else { //if bomb is false
frame.remove(square);
}
frame.add(square);
}
} // missing ) to close addActionListener(
}
since you probably don't want to add square inside the lambda, you should close it '}' and close the addActionListener with ');` before that line.
...
} else { //if bomb is false
frame.remove(square);
}
} ); // this line is somehow missing in your code
frame.add(square);
...

The Lambda is passed in a call to the method addActionListener((ActionEvent e) -> which has only one argument
meaning that after the Lambda you need ); So...
public static void buttonAdd(boolean[][] coord) {
for (int col = 0; col < SIZE; col++) {
for (int row = 0; row < SIZE; row++) {
Button square = new Button(coord[col][row]);
square.addActionListener((ActionEvent e) -> {
if (bombOrNot) { //if bomb is true
JOptionPane lose = new JOptionPane();
lose.setMessage("You Lose");
frame.add(lose);
System.exit(0);
} else { //if bomb is false
frame.remove(square);
}
}); // <<<<<<<<< here Note: added } in edit
frame.add(square);
}
}
}

Related

How do I remove the line of TextArea where caret is located

what I tried to do is if when I call the function then the line disappeared where caret is located in JTextArea. I achieved at first line case but hard to do in middle and last line cases.
This is perfectly failed code what I did.
private void DeleteOptionActionPerformed(ActionEvent e) {
String[] lines = area.getText().split("\n");
int caret = area.getCaretPosition();
int beforeLocation = 0;
for(int i = 0; i < area.getLineCount(); i++) {
try {
if(i == 0) {
if(caret <= lines[i].length())
area.replaceRange(null, area.getLineStartOffset(i), area.getLineEndOffset(i));
}
else {
if(caret <= lines[i].length() && caret > lines[beforeLocation].length()) {
area.replaceRange(null, area.getLineStartOffset(i), area.getLineEndOffset(i));
}
else {
caret -= lines[i].length();
beforeLocation = i;
continue;
}
}
} catch(BadLocationException e1) {
e1.printStackTrace();
}
caret -= lines[i].length();
beforeLocation = i;
}
}
Try using the Utilities class.
No need for any looping logic. Code should be something like:
int offset = textArea.getCaretPosition();
int start = Utilities.getRowStart(...);
int end = Utilities.getRowEnd(...);
textArea.replaceRange("", start, end);

Find out which checkbox was selected in custom component tabs

Consider two classes:
public class Test
{
private boolean skip = false;
private JLabel label = "";
public boolean isSkipped()
{
return skip;
}
public void setSkipped(boolean skip)
{
this.skip = skip;
}
public void setLabel(String string)
{
label.setText(string);
}
}
and MainWindow class that we assume that has all fields and methods required for simple frame to be displayed. In this class we also have:
private JTabbedPane tabPane = new JTabbedPane();
private ArrayList<Test> test = new ArrayList<>();
for(int i = 0; i < 30; i++)
{
test.add(new Test());
}
JPanel checkBoxTab = new JPanel();
JCheckBox checkBox = new JCheckBox();
checkBox.addItemListener(new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
if(e.getStateChange() == ItemEvent.SELECTED)
{
test.get(?).setSkipped(true);
}
if(e.getStateChange() == ItemEvent.DESELECTED)
{
test.get(?).setSkipped(false);
}
for(int j = 0, k = 1; j < test.size(); j++)
{
if(test.get(j).isSkipped())
{
continue;
}
test.get(j).setLabel("" + k);
k++;
}
}
});
checkBox.setOpaque(false);
checkBoxTab.add(checkBox);
checkBoxTab.setOpaque(false);
for(int i = 0; i < test.size(); i++)
{
tabPane.addTab("", test.get(i));
tabPane.setTabComponentAt(i, checkBoxTab);
}
My question is: how do I replace that ? sign with index of tab that has the chackbox that was selected? I need it to be found dynamically during program run. The purpose of this code is to find out which tab was selected to be skipped, skip it without assigning next number of k to a label and assign next number of k to label in next tab (assuming it's not marked to be skipped, and if it is - repeat previous process). I tried to understand solution in here Close the clicked tab, not the currently selected tab JTabbedPane but I don't really see how could I implement the "tab content" thing. Depicting previous we have:
tabCount: 0 1 2 3 4 5 6 7 8
skip: f t f t t f f f t
label: 1 2 3 4 5
EDIT sorry there was a typo in MainWindow class
With help of Mad Programmer's comment I managed to implement what I wanted
checkBox.addItemListener(new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
if(e.getStateChange() == ItemEvent.SELECTED)
{
test.get(tabbedPane.indexOfTab(tabName)).setSkipped(true);
}
if(e.getStateChange() == ItemEvent.DESELECTED)
{
test.get(tabbedPane.indexOfTab(tabName)).setSkipped(false);
}
for(int j = 0, k = 1; j < test.size(); j++)
{
if(test.get(j).isSkipped())
{
continue;
}
test.get(j).setLabel("" + k);
k++;
}
}
});

Memory game does not call compare function correctly

I have coded a simple memory game. Card values are added to two arrays and after that, a compare function is called. But there is a problem with the logic of the compare function.
The specific problem seems related to the fact that the compare function is called on the third button click. So on first click it adds first value to first array , on second click second value to second array. But I must click for yet a third time to call the compare function to compare the match of two arrays.
The main problem is that after all cards are inverted (10 matches in 5x4 memory game), it does not show the result.
I have uploaded full code here : http://uloz.to/xcsJkYUK/memory-game-rar .
public class PEXESO5x4 extends JFrame implements ActionListener {
private JButton[] aHracieTlactika = new JButton[20];
private ArrayList<Integer> aHodnoty = new ArrayList<Integer>();
private int aPocitadlo = 1;
private int[] aTlacitkoIden = new int[2];
private int[] aHodnotaTlac = new int[2];
private JButton aTlacitkoExit;
private JButton aTlacitkoReplay;
private JButton[] aHracieTlacitko = new JButton[20];
private int aPocetTahov = 0;
public void vkladanieHodnot() {
for (int i = 0; i < 2; i++) {
for (int j = 1; j < (this.aHracieTlactika.length / 2) + 1; j++) {
this.aHodnoty.add(j);
}
}
Collections.shuffle(this.aHodnoty);
}
public boolean zhoda() {
if (this.aHodnotaTlac[0] == this.aHodnotaTlac[1]) {
return true;
}
return false;
}
public void zapisCislaDoSuboru() {
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Semestralka.txt", true)))) {
out.println("haha");
//more code
out.println("hahahahha");
//more code
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
}
public void actionPerformed(ActionEvent e) {
int match = 0;
if (this.aTlacitkoExit == e.getSource()) {
System.exit(0);
}
if (this.aTlacitkoReplay == e.getSource()) {
}
for (int i = 0; i < this.aHracieTlactika.length; i++) {
if (this.aHracieTlactika[i] == e.getSource()) {
this.aHracieTlactika[i].setText("" + this.aHodnoty.get(i));
this.aHracieTlactika[i].setEnabled(false);
this.aPocitadlo++;
this.aPocetTahov += 1;
if (this.aPocitadlo == 3) {
if (this.zhoda()) {
match+=1;
if (match==10)
{
System.out.println("You win");
}
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(false);
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(false);
} else {
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[0]].setText("");
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[1]].setText("");
}
this.aPocitadlo = 1;
}
if (this.aPocitadlo == 1) {
this.aTlacitkoIden[0] = i;
this.aHodnotaTlac[0] = this.aHodnoty.get(i);
}
if (this.aPocitadlo == 2) {
this.aTlacitkoIden[1] = i;
this.aHodnotaTlac[1] = this.aHodnoty.get(i);
}
}
}
}
}

Java - referencing variables from inner class must be final / effectively final loop

I am trying to develop a GUI for a Chess / Checkers game. When attempting to add ActionListeners to the buttons, Netbeans seems to give me a whole bunch of errors with suggestions that doesn't seem to solve the problem.
Here is the part of the code in question:
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
squares[i][j].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!pressed) {
pressed = true;
fromR = i;
}
throw new UnsupportedOperationException("Not supported yet.");
}
});
}
}
squares[][] is the array all the buttons are stored in; the error occurs on the line fromR = i;
Is there a better way to add ActionListeners into buttons stored in arrays altogether?
The problem is that you are referring to i inside the action listener and its continuously changing.
One option is to copy i to a new int like iValue here:
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
final int iValue = i;
squares[i][j].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!pressed) {
pressed = true;
fromR = iValue;
}
throw new UnsupportedOperationException("Not supported yet.");
}
});
}
}
This is clumsy though.
A cleaner alternative is to extract a method:
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
addActionListenerTo(squares[i][j], i);
}
}
Here is that method:
private void addActionListenerTo(WhateverThisIs square, int i) {
square.addActionListener(e -> {
if (!pressed) {
pressed = true;
fromR = i;
}
throw new UnsupportedOperationException("Not supported yet.");
});
}
Another alternative would be to have all the squares know their rank and file:
final class Square {
final int rank;
final int file:
Square(int rank, int file) {
this.rank = rank;
this.file = file;
}
}
Put those in a Collection and then you could do this:
squares.stream().forEach(square -> {
square.addActionListener(e -> {
if (!pressed) {
pressed = true;
fromR = square.rank;
}
throw new UnsupportedOperationException("Not supported yet.");
});
});

Java 2D Game NullPointerException [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am trying to create a 2D game in Java where a user is prompted for a row width and column length. A 'world' object is created that looks like this when printed (where P is the player's character):
P---
----
----
----
The user can then enter up, down, left, right or exit which should move the P around and do nothing if the move would move the character off the map. My issue is after I enter the width and length, I get the following error:
java.lang.NullPointerException
at World.displayWorld(Driver.java:90)
at Driver.main(Driver.java:28)
I believe this means that Java is seeing worldDimensions.length as empty/null?? I thought I was assigning a value to it when the world object is created.. Any guidance is much appreciated!
Here's my code:
import java.util.Scanner;
public class Driver {
public static void main(String args[]) {
//Create a scanner object
Scanner input = new Scanner(System. in );
boolean exit = true;
//Prompt user to enter world width and height
System.out.print("World width: ");
int userWidth = input.nextInt();
System.out.print("World height: ");
int userHeight = input.nextInt();
//Create a world object
World world1 = new World(userWidth, userHeight);
world1.displayWorld();
System.out.println("Possible inputs: up, down, left, right, exit");
while (exit = true) {
//display world
world1.displayWorld();
System.out.print("ACTION > ");
String userAction = input.next();
if (userAction == "up" || userAction == "down" || userAction == "left" || userAction == "right" || userAction == "exit") {
switch (userAction) {
case "up":
world1.moveUp();
break;
case "down":
world1.moveDown();
break;
case "left":
world1.moveLeft();
break;
case "right":
world1.moveRight();
break;
case "exit":
exit = false;
break;
}
} else {
System.out.println("Invalid Input. Possible inputs are: up, down, left, right, or exit.");
}
}
}
}
class World {
static private char[][] worldDimensions;
static private int characterRow;
static private int characterColumn;
public World(int userWidth, int userHeight) {
char[][] worldDimensions = new char[userHeight][userWidth];
int characterRow = 0;
int characterColumn = 0;
for (int row = 0; row < worldDimensions.length; row++) {
for (int column = 0; column < worldDimensions[row].length; column++) {
if (characterRow == row && characterColumn == column) {
worldDimensions[row][column] = (char)
'P';
} else {
worldDimensions[row][column] = (char)
'-';
}
}
}
}
public void displayWorld() {
for (int row = 0; row < worldDimensions.length; row++) {
for (int column = 0; column < worldDimensions[row].length; column++) {
System.out.print(worldDimensions[row][column]);
}
System.out.println();
}
}
public void moveUp() {
if (characterRow - 1 >= 0) {
characterRow--;
}
}
public void moveDown() {
if (characterRow + 1 <= worldDimensions[0].length) {
characterRow++;
}
}
public void moveLeft() {
if (characterColumn - 1 >= 0) {
characterColumn--;
}
}
public void moveRight() {
if (characterRow + 1 <= worldDimensions.length) {
characterRow++;
}
}
}
You're shadowing worldDimensions inside of your constructor. The local declaration does not give you the same field as previously declared.
Simply remove the declaration and you'll be alright (at least for that error):
worldDimensions = new char[userHeight][userWidth];
You're overwriting your class variable worldDimensions. Your World constructor should look like the following
public World(int userWidth, int userHeight)
{
//here is where you were overwriting the global variable, leaving it null
//and populating the local one instead
worldDimensions = new char[userHeight][userWidth];
int characterRow = 0;
int characterColumn = 0;
for (int row = 0; row < worldDimensions.length; row++)
{
for (int column = 0; column < worldDimensions[row].length; column++)
{
if (characterRow == row && characterColumn == column)
{
worldDimensions[row][column] = (char)'P';
}
else
{
worldDimensions[row][column] = (char)'-';
}
}
}
}

Categories