Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Problem with Cloning...

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class LeagueWindow extends Observable implements ActionListener
{
TeamLeague CurrentLeague;
TeamLeague BackupLeague;
LeagueViewer CurrentView;
WinWindow WinningScores;
WrongWindow WrongScore;
JButton AddButton;
JButton EditTeam;
JButton SaveLeague;
JButton RollBack;
JButton QuitLeague;
JFrame MainFrame;

public LeagueWindow(TeamLeague ThisLeague)
{
//first, place the ThisLeague object as the current league
CurrentLeague = new TeamLeague(ThisLeague);

//add in a observer for the new league
final ViewOne NewView = new ViewOne();
CurrentLeague.addObserver(NewView);

//now create the league view by creating a league viewer
//with our basic league as it stands with no games played
CurrentView = new LeagueViewer(CurrentLeague);
//now we need to create the GUI to house the information in
//first create the buttons
AddButton = new JButton("Add Games");
EditTeam = new JButton("Edit Team");
RollBack = new JButton("Rollback Results");
SaveLeague = new JButton("Save League");
QuitLeague =new JButton("Quit");
//add an action listener to all objects
AddButton.addActionListener(this);
EditTeam.addActionListener(this);
SaveLeague.addActionListener(this);
RollBack.addActionListener(this);
QuitLeague.addActionListener(this);
//now create a box to house all the buttons
Box OptionsBox = new Box(BoxLayout.X_AXIS);
OptionsBox.add(AddButton);
OptionsBox.add(EditTeam);
OptionsBox.add(SaveLeague);
OptionsBox.add(RollBack);
OptionsBox.add(QuitLeague);
//now get the GUI from our leagueviewer
Component Table = CurrentView.getGUI();
//create our JFrame initiator
MainFrame = new JFrame("League Information");
//now add the Table and options views in together
MainFrame.getContentPane().add(Table, BorderLayout.WEST);
MainFrame.getContentPane().add(OptionsBox, BorderLayout.SOUTH);
MainFrame.setLocation(200, 200);
MainFrame.pack();
MainFrame.setVisible(true);

WinningScores = new WinWindow();
WrongScore = new WrongWindow();
}

public synchronized void actionPerformed(ActionEvent ThisEvent)
{
JButton TestButton = (JButton)ThisEvent.getSource();

if(TestButton == AddButton)
{

BackupLeague = (TeamLeague)CurrentLeague.clone();
//now we want to state the number of results
//that we are going to work with
//the number of games that can be played can only be half
//the size of the league itself so we get the length of the
//league and divide it by 2. If we only have 2 teams we can
//omly have 1 game so test for that first
int NumPlayed = 0;
//start a fixtures window ot be called when required
GamesPlayed Fixtures;

if(CurrentLeague.returnLength() == 2)
{
//if there is only two teams we can only have
//a maximum of 1 fixture so call the window with 1
//and set number of games playes as 1
Fixtures = new GamesPlayed(1);
NumPlayed = 1;
}
else
{
//otherwise we have more than 2 teams which means
//we can have more than 1 fixture at a time so prompt
//to see how many fixtures they want to put in
//this uses option 3 in the league setup to call the
//container with the right GUI inside it
LeagueSetupNew NewFixtureAmount =
new LeagueSetupNew(3, (CurrentLeague.returnLength()/2));

//returns the number of games to be played
String NumGames = NewFixtureAmount.returnSelected();

if(NumGames == null)
{
NumPlayed = 1;
}
else
{
NumPlayed = Integer.parseInt(NumGames);
}
//calls the fixtures window with the required number of games
Fixtures = new GamesPlayed(NumPlayed);
}

//now we have the fixtures we need to update the league
for(int x = 0; x < NumPlayed; x++)
{
//place each of the results in a holder. We will
//test each of these against null as if we have
//a null value then we know that that particular
//entry has been placed in wrongly and we need to
//ignore it
boolean Tester = false;
String Home = Fixtures.getHomeTeam(x);
String Away = Fixtures.getAwayTeam(x);
String HGoals = Fixtures.getHomeScore(x);
String AGoals = Fixtures.getAwayScore(x);

Tester = CurrentLeague.AddWins(Home, Away, HGoals, AGoals);
CurrentLeague.sort();
CurrentView.update(CurrentLeague);

System.out.println("Tester is " + Tester);

if(Tester == true)
{
//if its true then the result has been added correctly
//then we show it in a text area
WinningScores.Update(Home, Away, HGoals, AGoals);
}
else
{
//otherwise the result entered was wrong. This lists all
//the wrong results entered
WrongScore.Update(Home, Away, HGoals, AGoals);
}
}

System.out.println("Backup League is");
String Show = BackupLeague.showLeague();
System.out.println(Show);
}
if(TestButton == EditTeam)
{
//call the edit menu
EditFrame NewMenu = new EditFrame(CurrentLeague);
//sort the league with the update
CurrentLeague.sort();
//display the newly updated league
CurrentView.update(CurrentLeague);
}
if(TestButton == SaveLeague)
{
System.out.println("In Saver League");
try
{
SLeague Saver = new SLeague(CurrentLeague);
}
catch(Exception ThisException)
{
}
}
if(TestButton == RollBack)
{
int LoopValue = BackupLeague.returnLength();

System.out.println("Current League is");
String Show = CurrentLeague.showLeague();
System.out.println(Show);
System.out.println("Backup League is");
Show = BackupLeague.showLeague();
System.out.println(Show);

for(int i = 1; i <= LoopValue; i++)
{
Team FirstTeam = BackupLeague.returnTeam(i);
CurrentLeague.setTeam(i, FirstTeam);
}

CurrentView.update(CurrentLeague);
}
else if(TestButton == QuitLeague)
{
MainFrame.setVisible(false);
MainFrame.dispose();
System.exit(0);
}
}
}

Above is a small GUI that displays a soccer league table. Initially this table is created and populated in another function and passed as ThisLeague.
I then create it as a new object CurrentLeague by calling the constructor Thisleague as an argument.
Everything is ok but what I want to do is create a backup league that sits one operation back from the current one. So when I initilly try to add results by clicking the Add button I want to create a clone of Currentleague called backupleague which will hold the league table before any results are added. Currentleague should then be updated and Backup league should hold the table before the results are added.
However when I call backup table once the reuslts have been added I find that it has also been updated and I cant figure out why, can anyone help?

The clone and Teamleague constructor code looks like this:

public class TeamLeague extends Observable implements League, Cloneable
{
//size of the leage
private int Size;
//a array of teams that comprise a league
private Team[] NewLeague;
public TeamLeague(TeamLeague ThisLeague)
{
System.out.println("In Constructor with league");

final TeamLeague TempLeague = (TeamLeague)ThisLeague;

Size = TempLeague.Size;

NewLeague = new Team[Size + 1];

System.arraycopy(TempLeague.NewLeague, 1, NewLeague, 1, Size);
}

public Object clone()
{
try
{

TeamLeague NewObject = (TeamLeague)super.clone();
NewObject.NewLeague = (Team[])NewLeague.clone();
return NewObject;
}

catch(CloneNotSupportedException ThisClone)
{
throw new InternalError(ThisClone.toString());
}
}
}

If anyone can help it would be much appreciated
 
Ranch Hand
Posts: 429
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm guessing that at some point only a shallow clone is created, when you need a deep clone. The default clone behavior for many classes only does shallow cloning. For example, if you clone an ArrayList, you'll have two ArrayLists holding references to the same exact objects. If the objects are modified, you'll see the modification no matter which array list you use. For example:



In your case, for example, your backup league's NewLeague array is probably pointing to the same exact Team objects as your current league's array. So when the team's stats are updated through the current league, these will be reflected in the backup since they all reference the same Team object instance. If you want a deep copy, depending on the objects you're working with you may have to implement it yourself.

By the way, I strongly recommend that you use the standard Java naming conventions in which variables/attribute names start with lower-case letters (final TeamLeague tempLeague = (TeamLeague)thisLeague instead of final TeamLeague TempLeague = (TeamLeague)ThisLeague.) It would make it a lot easier for other people to understand your code.
[ May 02, 2006: Message edited by: Yuriy Zilbergleyt ]
 
You had your fun. Now it's time to go to jail. Thanks for your help tiny ad.
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic