Reputation: 63
First, I have searched. And all of the answers I have found have been about NOT having the same reference to the same object in two different array lists. so maybe that should tell me I'm doing this wrong in itself? But I'm not sure of how else to manage this.
I am trying to learn Java. And part of that is Swing.
My app I am working on is a simple tournament/bracket app (think march madness. or any simple bracket tree).
Simplified code with just the issue at hand:
class Bracket extends JPanel {
ArrayList<Round> rounds = new ArrayList<Round>();
public void declareWinner(Team team, Game game, Round round) {
// code that gets current round, game, team numbers to calculate the next round, game, team numbers.
int currentRoundNum = rounds.indexOf(round);
int currentGameNum = rounds.get(currentRoundNum).games.indexOf(game);
int currentTeamNum = rounds.get(currentRoundNum).games.get(currentGameNum).teams.indexOf(team);
int nextRoundNum = currentRoundNum + 1;
int nextGameNum = (int) (Math.floor(gameNumber / 2));; // to position the team in the appropriate game slot in the next round
int nextTeamNum = ((gameNumber % 2) == 0) ? 0 : 1; // even game numbers will be the top team in the next round, odd team numbers will be the bottom team in the next round
// here is where things are getting wonky. Trying to set the next round slot to the team that is being declared the winner
rounds.get(nextRoundNum).games.get(nextGameNum).teams.set(nextTeamNum, team);
}
public Bracket(int numRounds) {
// code that creates the bracket structure. # of rounds. the correct # of games depending on the round. etc. Creates empty shell of "placeholder" teams with no name/info.
for(int i = 0; i < numRounds; i++) {
int numGames // set to (number of games of the last round added) * 2
rounds.add(0, new Round(numGames)
}
}
}
class Round extends JPanel {
ArrayList<Game> games = new ArrayList<Game>();
public Round(int numGames) {
for(int i = 0; i < numGames; i++) {
games.add(new Game());
}
}
// more code...
}
class Game extends JPanel {
ArrayList<Team> teams = new ArrayList<Team>();
// more code... creates two teams per each game in constructor
}
class Team extends JPanel {
String teamName;
public Team(String name) {
teamName = name;
add(new JLabel(name));
}
// simple team info, just going for functionality. not much else is here yet.
}
So, lets say in the first round (index 0 of rounds), in the first game (index 0 of rounds.get(0).games), Team 1 (index 0 of rounds.get(0).games.get(0).teams) wins. It's calculating all the stuff correctly. The team is placed in the correct slot. BUT, it completely removes the team from the current position in the round. So now I'm left with only 1 team in the first game of the first round.
It won't let me have the same Team object referenced in both ArrayLists in Rounds[0].Games[0].Teams and Rounds[1].Games[0].Teams. They are nested array lists in each, so 2 different Array Lists. Am I failing because it's bad to extend the JComponents on the classes themselves, and I should completely refactor this?
Upvotes: 0
Views: 64
Reputation: 705
I can't see exactly what is going on in your example code, as it is not self-contained. However from your description it looks like you are falling foul of the property that Swing components can only be added to one container at a time. If you add the same component to a second container it is automatically removed from the first one.
This doesn't affect the contents of your ArrayList
s in the slightest - you can have the same object in as many different ArrayList
s as you like.
It also looks like you are muddying the waters by storing this sort of data inside objects which extend Swing components. I suggest you consider separating out a data structure (the Model) from the display components (the View) to make things clearer. Just get the data structure working first, then build the view from it once you have verified it is correct.
On an unrelated note, it looks like you could simplify the start of your code, where before you had:
public void declareWinner(Team team, Game game, Round round) {
// code that gets current round, game, team numbers to calculate the next round, game, team numbers.
int currentRoundNum = rounds.indexOf(round);
int currentGameNum = rounds.get(currentRoundNum).games.indexOf(game);
int currentTeamNum = rounds.get(currentRoundNum).games.get(currentGameNum).teams.indexOf(team);
...
you could replace these lines with
public void declareWinner(Team team, Game game, Round round) {
// code that gets current round, game, team numbers to calculate the next round, game, team numbers.
int currentRoundNum = rounds.indexOf(round);
int currentGameNum = round.games.indexOf(game);
int currentTeamNum = game.teams.indexOf(team);
...
since you already have references to those objects passed in as arguments.
Upvotes: 2