Unfortunately I’ve got a bug that I have been working on for 1 full day now, and though I know there are ways to work around it, I am very excited to learn where my logic goes wrong.
Now, my program is about a match between two teams of chessplayers. It predicts the scores depending on the player-setup chosen by the coach (the user). *(more background info below my question)
So I first ask the user which players are in his team. Ofcourse I want this “PlayerList” information to stay constant (and the bug I referred to is that it mysteriously doesnt)
So I made a Gui that pops up all the boards, with the players in the order that the user submitted them to the program. Then whenever he clicks one of the buttons, the acionlistener of that button should display the next player, (and it lets the main program know that there was another player selected on that board and adjust the prediction accordingly, but these tasks work perfectly).
Now, the problem is that if a user has replaced for example Marcel on board 2 for someone else, that when the user is going to click on the button for board 3, he no longer has the options Marcel at his disposal. The “playerList”-field of all buttons has been set to the chosen player setup in the main program, instead of the original list that the main program prompted the user for at the start of the run…
(see attached image)
So there is some really annoying dependency between the players that are assigned to these buttons, and the actually chosen player list that has been made by the user. If I look at my code I cannot comprehend why…
So something goes wrong with them buttons that I defined.
now this is what we’ve got:
I extended JButton, so that the button has the info on the available players in the users team like this:
public class JButtonPlus extends JButton {
public Team team;
private int aantalSpelers;
final ArrayList<Player> playerList;
private Integer spelerNr;
private Integer bordNr;
public JButtonPlus(ArrayList<Player>playerList_, Integer spelernr, Integer bordnr){
playerList=playerList_;
aantalSpelers=playerList_.size();
spelerNr=spelernr;
bordNr = bordnr;
}
So the problem is that this final ArrayList playerList is not constant at all.
It changes after invoking any of the actionListeners by clicking any of the other buttons.
This is the code in the main program that makes the buttons and adds the actionlisteners:
(note: this teams.get(0) refers to the user’s team, and the field players refers to an ArrayList that got filled with all of the players that he submitted to the program. The method displaySpelernr(i) adds the playername to the setText method of the JButtonPlus)
Box verticalBox_1 = Box.createVerticalBox();
frame.getContentPane().add(verticalBox_1);
JLabel lblNewLabel = new JLabel("opstelling thuisteam");
verticalBox_1.add(lblNewLabel);
for (int i = 0; i < teams.get(0).players.size(); i++) {
final JButtonPlus btnSpeler = new JButtonPlus(
teams.get(0).players,i, i);
btnSpeler.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
btnSpeler.displayVolgendeSpeler();
}
});
verticalBox_1.add(btnSpeler);
btnSpeler.displaySpelerNr(i);
}
the method that is invoked at userClick, displayVolgendeSpeler is like this
public void displayVolgendeSpeler(){
spelerNr =(spelerNr+1)%aantalSpelers;
displaySpelerNr(spelerNr);
the problem is above statement, other statements concern the calculation, which works like it should. This displaySpelerNr() method looks like his
public void displaySpelerNr(Integer i){
setText(playerList.get(i).SpelerNaam);
and here the bug gets noted: the playerList object has been changed..
Does anybody see why this supposedly constant source of players playerList changes when a button is clicked?
*(more background info)
A match between two chessteams involves all players to play 1 match against one of the opponents players. Typically, the players in a team are of different strength. So for example, if youve got team A with player strength ranging from beginner to master, and team B with players ranging from intermediate to grandmaster, you know that if you pair the players based on increasing strength, then team A will lose for sure. The fun starts when Team A will sacrifice one or two of their weakest players by pairing them to the two strongest players of Team B. This means a loss of two points, but the remaining players of team A will now each face a weaker player instead of a stronger one. There might even be pairings so that it is more likely that the weaker team wins. My program tries to show which pairings are worst and best, and gives the statistics. Ofcourse it would be nice if the coach that might use this program is actually able to get this Gui to be set at his desired team, and this is where you come in, dear StackOverflow-champ!
Declaring a field as
finalmeans that you can’t assign a new value to it. If, however, that field contains an Object, you can still modify non-final fields inside of that Object. The code below should illustrate what I mean.In your code, you have a
final ArrayList<Player>, which means you can’t store a new ArrayList in that field. You can, however, modify the contents of the existing ArrayList in any of the usual ways (adding, removing, updating elements, etc).You’re also passing the same ArrayList to all of your
JButtonPlusinstances, so changing it in any of those classes will result in a change to all of them. Try passing in a copy of the ArrayList, and see if that solves the problem.