I have read quite a few pages of stackoverflow but I wasn't able to get my ArrayList to get copied unto another class. Here's the scenario, I'm building a quick book saver app, similar to what you would have in a library but simpler (for school).
I have my main library class (with the main) that has the swing set up for the main menu/options.
I have the book class with the constructor for new books as follows:
public class Livre {
private String titre;
private String soustitre;
private String auteur;
private String editeur;
private String collection;
private String isbn;
private long cup;
private double prixDeVenteSuggere;
private double prixVente;
private int nbPages;
private boolean disponible;
public Livre(String titre, String soustitre, String auteur, String editeur, String collection, String isbn, long cup, double prixDeVenteSuggere, double prixVente, int nbPages, boolean disponible){
this.titre = titre;
this.soustitre = soustitre;
this.auteur = auteur;
this.editeur = editeur;
this.collection = collection;
this.isbn = isbn;
this.cup = cup;
this.prixDeVenteSuggere = prixDeVenteSuggere;
this.prixVente = prixVente;
this.nbPages = nbPages;
disponible = true;
}
public Livre() {
}
public String getTitre() {
return titre;
}
public void setTitre(String titre) {
this.titre = titre;
}
public String getSoustitre() {
return soustitre;
}
public void setSoustitre(String soustitre) {
this.soustitre = soustitre;
}
public String getAuteur() {
return auteur;
}
public void setAuteur(String auteur) {
this.auteur = auteur;
}
public String getEditeur() {
return editeur;
}
public void setEditeur(String editeur) {
this.editeur = editeur;
}
public String getCollection() {
return collection;
}
public void setCollection(String collection) {
this.collection = collection;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public long getCup() {
return cup;
}
public void setCup(long cup) {
this.cup = cup;
}
public double getPrixDeVenteSuggere() {
return prixDeVenteSuggere;
}
public void setPrixDeVenteSuggere(double prixDeVenteSuggere) {
this.prixDeVenteSuggere = prixDeVenteSuggere;
}
public double getPrixVente() {
return prixVente;
}
public void setPrixVente(double prixVente) {
this.prixVente = prixVente;
}
public int getNbPages() {
return nbPages;
}
public void setNbPages(int nbPages) {
this.nbPages = nbPages;
}
public boolean isDisponible() {
return disponible;
}
public void setDisponible(boolean disponible) {
this.disponible = disponible;
}
}
Option #1 on the Library class (built with WindowBuilder) has the "New" button which opens a second JFrame to input all the info in regards to the book.
in this JFrame class, I've added an actionListener on the confirm button to confirm the input on the JTextFields to be added as an object as follows:
public void confirmerLivre(){
l = new Livre(txtTitre.getText(), txtSousTitre.getText(), txtAuteur.getText(),
txtEditeur.getText(), txtCollection.getText(), txtISBN.getText(),
Long.parseLong(txtCodebar.getText()), Double.parseDouble(txtPrixMSRP.getText()),
Double.parseDouble(txtPrix.getText()), Integer.parseInt(txtPages.getText()), true);
confirmerLivre.add(l); /// confirmerLivre is defined as an ArrayList
}
What I can't wrap my head around is being able to take the ArrayList confirmerLivre from the 2nd JFrame class and push it unto my main JFrame class to be manipulated further with other options.
Any help will be greatly appreciated.
Thank you
Probably the quickest fix is to create/expose these methods in your main JFrame class:
getBookList()
setBookList()
When you create your popup JFrame, you need to pass an instance of your main JFrame class to it in its constructor:
public PopupFrame extends JFrame {
private MainFrame main;
public PopupFrame(MainFrame main) {
this.main = main;
}
}
Now that you have access to your main JFrame class from your popup, you can just go main.getBookList() to get the list (I'd recommend reading this question also)
If you create your ArrayList as a public variable in the second JFrame class (outside any of the methods) then it can be used in the first class such as:
SecondJFramesName.confirmerLivre()
In this code SecondJFramesName is the name of your second JFrame class. Now that your ArrayList is a public variable it can be accessed outside the class.
Note: your second JFrame's name is the one you use to create it in a way such as this:
JFrame SecondJFramesName = new JFrame("My title");
If you need any more specific details please comment!
Hopefully this helps!
Maybe observer pattern could help you:
public interface ConfirmerLivreMonitor{
void onConfirmerLivreChange(List<...> confirmerLivre);
}
then
//...
private ConfirmerLivreMonitor confirmerLivreMonitor;
public void setConfirmerLivreMonitor(ConfirmerLivreMonitor confirmerLivreMonitor ){
this.confirmerLivreMonitor = confirmerLivreMonitor
}
//....
public void confirmerLivre(){
l = new Livre(txtTitre.getText(), txtSousTitre.getText(), txtAuteur.getText(),
txtEditeur.getText(), txtCollection.getText(), txtISBN.getText(),
Long.parseLong(txtCodebar.getText()), Double.parseDouble(txtPrixMSRP.getText()),
Double.parseDouble(txtPrix.getText()), Integer.parseInt(txtPages.getText()), true);
confirmerLivre.add(l); /// confirmerLivre is defined as an ArrayList
if(confirmerLivreMonitor != null){ //notify confirmerLivre change
confirmerLivreMonitor.onConfirmerLivreChange(confirmerLivre);
}
}
make the Main JFrame implemnents ConfirmerLivreMonitor,so you can:
sencondJFrame.setConfirmerLivreMonitor(this);
or just pass a anonymous class:
sencondJFrame.setConfirmerLivreMonitor(new ConfirmerLivreMonitor(){
public void onConfirmerLivreChange(List<...> confirmerLivre){
//display in Main JFrame,maybe
}
});
once the confirmerLivre change, the main frame can display(or something else)
the first time,very cool
Related
Novice java coder here, expert java drinker. I've been working on an assignment for my class all day where I have to write a java class known as "Pet" for a fictional program called Pet BAG(Boarding and grooming) for my fictional employer Global Rain. Anyway, I have alot of said code written, and am continuing to work on it dilligently however I have hit a roadblock. When I try the instant feed back tool I get "getDogSpaces()" or "getCatSpaces()" functions seem to be missing. Can anyone help me understand why I get this error so I can fix it and move on? I am stunped. My code is posted below.
public class Pet {
//Atrributes
private String petType;
private String petName;
private int petAge;
private int dogSpaces;
private int catSpaces;
private int daysStay;
private double amountDue;
public Pet (String petType, String petName, int petAge, int daysStay) {
setPetType(petType);
setPetName(petName);
setPetAge(petAge);
setDogSpace(30);
setCatSpace(12);
setDaysStay(daysStay);
}
//Accessors
public String getPetType() {
return petType;
}
public String getPetName() {
return petName;
}
public int getPetAge() {
return petAge;
}
public void setPetAge(int setPetAge) {
this.petAge = petAge;
}
public int getDogSpace() {
return dogSpace;
}
public void setDogSpace(int dogSpace) {
this.dogSpace = dogSpace;
}
public int getCatSpace() {
return catSpace;
}
public void setCatSpace(int catSpace) {
this.catSpace = catSpace;
}
public int getDaysStay() {
return daysStay;
}
public void setDaysStay(int daysStay) {
this.daysStay = daysStay;
}
public double getAmountDue() {
return amountDue;
}
public void setAmountDue(double amountDue) {
this.amountDue = amountDue;
}
}
I know my code block seems strange, but I did my best to line it up properly. Could anyone assist me?
Thank you,
Joseph
Sorry as I know this is obvious but I cant figure it out!
I have a parent class named 'Set', representing a set of a tennis match.
public class Set {
private String set1;
private String set2;
private String set3;
//private Object[] match;
public Set() {
setSet1(set1);
setSet2(set2);
setSet3(set3);
}
public void setSet1(String set1) {
this.set1 = set1;
}
public String getSet1() {
return set1;
}
public void setSet2(String set2) {
this.set2 = set2;
}
public String getSet2() {
return set2;
}
public void setSet3(String set3) {
this.set3 = set3;
}
public String getSet3() {
return set3;
}
public String toString(){
return String.format("set1: %s, set2: %s, set3: %s", set1, set2, set3);
}
}
And a sub class of 'Set' named 'SingleSet', where i try to add the sets into an array named 'game':
public class SingleSet extends Set{
private Object homePlayer;
private Object awayPlayer;
private String[] game;
public SingleSet(Object homePlayer, Object awayPlayer){
super();
game = new String[3];
game[0] = super.getSet1();
game[1] = super.getSet2();
game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
public void setHomePlayer(Object homePlayer) {
this.homePlayer = homePlayer;
}
public Object getHomePlayer() {
return homePlayer;
}
public void setAwayPlayer(Object awayPlayer) {
this.awayPlayer = awayPlayer;
}
public Object getAwayPlayer() {
return awayPlayer;
}
public void setGame(String[] game) {
this.game = game;
}
public String[] getGame() {
return game;
}
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
}
And this is where I am trying to add the Sets from my parents class into my sub class (this is for FXML, so the code is in my controller):
public void submit() {
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
System.out.println(game1);
When I print the result, all my values are null. I tried printing them individually and that worked fine, so I know the 'set1Box.getText()' is working fine.
Again sorry for any obvious rookie error!
I've updated my code and same issue. Thank you for the composition answer, I will need it for my project, but this is a IS-A relationship
Make sure that the toString() methods of the following attributes exist and return a correct string.
It seems as if there is no way to get a String from homePlayer, awayPlayer and all indices of game[x].
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
May be the Title isn't a specific one, I just don't know how to call it. I will explain you in detail
I have these classes:
public class ChannelComponent {
private String name;
private String mode; //(1P1C / XPXC / 1PXC)
private List<SourceProvidedPort> publishers = new ArrayList<SourceProvidedPort>();
private List<SinkRequiredPort> subscribers = new ArrayList<SinkRequiredPort>();
public ChannelComponent(String name, String mode) {
this.name = name;
this.mode = mode;
}
public boolean canISubscribe(SinkRequiredPort newPort) {
if ((mode.equals("1P1C") || mode.equals("1PXC")) && subscribers.size() < 1) {
subscribers.add(newPort);
return true;
} else if (mode.equals("XPXC")) {
subscribers.add(newPort);
return true;
}
return false;
}
public String getName() {
return name;
}
public String getMode() {
return mode;
}
public void printChannel() {
System.out.println("[" + name + "," + mode + "]" + "\n");
}
}
TestCentralRegistry
public class TestCentralRegistry {
private List<ChannelComponent> channels = new ArrayList<ChannelComponent>();
public void addChannelComponent(ChannelComponent c) {
channels.add(c);
}
public static void main(String... args) {
TestCentralRegistry demo = new TestCentralRegistry();
demo.addChannelComponent(new ChannelComponent("channel1", "1P1C"));
demo.addChannelComponent(new ChannelComponent("channel2", "XPXC"));
}
}
In the TestCentralRegistry class I created 2 channelComponents, these channels I would like to compare their mode value in the method canISubscribe (located in the ChannelComponent class). But how come, I could retrieve the values created in the TestCentralRegistry to read them in the ChannelComponent class?
what am I missing?
Because, from another class TestChannel I'm going to have a ChannelComponent reference, invoke the method canISubscribe
public class TestChannel {
ChannelComponent channelComponent;
public void callSubscribe(SinkRequiredPort newPort){
channelComponent.canISubscribe(newPort);
}
public static void main(String... args) {
TestChannel testChannel = new TestChannel();
SinkRequiredPort sinkPort = new SinkRequiredPort();
sinkPort.setWantsUse("channel1");
testChannel.callSubscribe(sinkPort);
}
}
And I need to compare the values, created in the TestCentralRegistry and TestChannel to see if there is a matching. I know that I still need to add some lines like getting the value from the newPort.getWantsUse(); and compare it with the channelComponent name ... but still I need the value created in the TestCentralRegistry
I hope my question is clear
Any suggestions?
Thank you in advance
Try holding a reference to TestCentralRegistry in ChannelComponent.
public class ChannelComponent {
private String name;
private String mode; //(1P1C / XPXC / 1PXC)
private List<SourceProvidedPort> publishers = new ArrayList<SourceProvidedPort>();
private List<SinkRequiredPort> subscribers = new ArrayList<SinkRequiredPort>();
private TestCentralRegistry testCentralRegistry;
public ChannelComponent(String name, String mode) {
this.name = name;
this.mode = mode;
}
public void registerTestCentralRegistry( TestCentralRegistry testCentralRegistry) {
this.testCentralRegistry = testCentralRegistry;
}
}
Register your TestCentralRegistry as shown below:
public class TestCentralRegistry {
private List<ChannelComponent> channels = new ArrayList<ChannelComponent>();
public void addChannelComponent(ChannelComponent c) {
channels.add(c);
}
public static void main(String... args) {
TestCentralRegistry demo = new TestCentralRegistry();
ChannelComponent cc1 = new ChannelComponent("channel1", "1P1C");
cc1.registerTestCentralRegistry( demo);
ChannelComponent cc2 = new ChannelComponent("channel2", "XPXC");
cc2.registerTestCentralRegistry( demo);
demo.addChannelComponent( cc1);
demo.addChannelComponent( cc2);
}
}
Then, you can retrieve the values created in the TestCentralRegistry by calling testCentralRegistry.getX() from ChannelComponent.
consider the below code:
public class Bid {
private double pe;
private List<ResChar> resourceList;
protected Map<Integer,Integer>scheduleOfSeller ;
public Map<Integer, Integer> getScheduleOfSeller() {
return scheduleOfSeller;
}
public void setScheduleOfSeller(Map<Integer, Integer> scheduleOfSeller) {
this.scheduleOfSeller = scheduleOfSeller;
}
private int bidId;
public int getBidId() {
return bidId;
}
public void setBidId(int bidId) {
this.bidId = bidId;
}
public double getPe() {
return pe;
}
public void setPe(double pe) {
this.pe = pe;
}
public List<ResChar> getResourceList() {
return resourceList;
}
public void setResourceList(List<ResChar> resourceList) {
this.resourceList = resourceList;
}
public Bid(int bidId,double pe, List<ResChar> resourceList){
setBidId(bidId);
setPe(pe);
setResourceList(resourceList);
this.scheduleOfSeller = new HashMap<Integer,Integer>();
}
}
I want to make a copy constructor of the bid like this :
public class BidCopy{
public Bid bid;
public BidCopy(Bid bidBuyer){
List<ResChar> resList = new LinkedList<ResChar>();
for (ResChar elt : bidBuyer.getResourceList()){
ResCharCopy eltCopy = new ResCharCopy(elt);
resList.add(eltCopy.elt);
}
this.bid = bidBuyer;
this.bid.setResourceList(resList);
}
}
The only solution that I know to make such copy is to proceed like follows :
public class BidCopy{
public Bid copy;
public BidCopy(Bid bid){
List<ResChar> resList = new LinkedList<ResChar>();
for (ResChar elt : bid.getResourceList()){
ResCharCopy eltCopy = new ResCharCopy(elt);
resList.add(eltCopy.elt);
}
this.copy = new Bid(bid.getBidId(), bid.getPe(), resList);
}
}
So I want to know if there is any other solution to make a copy of "Bid" Object more effectively ?
I would suggest making a copy constructor for your Bid object (and not a specific class for copying), a Bid is made out of its fields and not methods, like so:
public class Bid {
int ID;
String description;
Object bidStuff;
// ...as before
public Bid(Bid bid) {
this.ID = bid.ID;
this.description = bid.description;
this.bidStuff = bid.bidStuff;
}
public static void main(String[] args) {
List<Bid> original = new ArrayList<>();
// ..populate it
List<Bid> copy = new ArrayList<>(original.size());
for (Bid b : original) {
copy.add(new Bid(b));
}
}
}
You can even make the copy constructor protected or package-protected if you don't want anyone else to mess around with making multiple copies of bids.
There is not. Even though some collections have "copy constructors", these constructors will copy the elements' references, they will not create new elements for you.
You can however "optimize" the list creation itself by submitting the size of the initial list to the constructor:
List<X> newList = new LinkedList<X>(oldList.size());
public class TableModel extends AbstractTableModel {
public int page;
public TableModel(Integer p) {
this.page=p;
System.out.println("mm"+page);
}
public void pudata() {
System.out.println(page);
}
//System.out.println("model "+page);
private String[] columnNames = {"groupName","membersCount","previliage"};
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
#Override
public int getRowCount() {
return data.size() ;
}
Can not access variable page in getgroup() method it passes 0 to getgroup() method.
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
Your question is unclear, but I suspect the problem is just that all the instance initializers are being run before the constructor body, so you're seeing the default value for page. You should have something like:
public class TableModel extends AbstractTableModel {
private static final String[] columnNames =
{"groupName","membersCount","previliage"}; // TODO: Fix spelling!
private final int page;
private final List<GroupData> data;
public TableModel(int page) {
this.page = page;
this.data = new DatabaseLayer().getGroup(page);
}
...
}
It's generally a good idea to keep all your instance/static variable declarations in one place (I prefer to keep them at the top, but YMMV) and make them all private to make it easier to reason about how they're used. The main change, however, is moving the new DatabaseLayer ().getGroup(page) code into the constructor.
public class TableModel extends AbstractTableModel {
public int page;
public ArrayList<GroupData> data;
public TableModel(Integer p) {
this.page=p;
this.data = (new DatabaseLayer ()).getGroup(page);
System.out.println("mm"+page);
}
public void pudata() {
System.out.println(page);
}
//System.out.println("model "+page);
private String[] columnNames = {"groupName","membersCount","previliage"};
#Override
public int getRowCount() {
return data.size() ;
}
Refresh your data field every time when you assign a new value to the page field.
public TableModel(int p) {
setPage(p);
}
public void setPage(int p) {
this.page = p;
this.data = new DatabaseLayer ().getGroup(page);
}
This is absolute correct because:
public int page;
default value for page is 0 because its int.
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
Is a variable initialization so before initialization of page you are passing it into .getGroup(page) so default value will pass in that case.
So you have to call getGroup(int) method after page being initialized, one way can be following:
private final List<GroupData> data;
public TableModel(Integer p) {
this.page = p;
this.data = new DatabaseLayer().getGroup(page);
System.out.println("mm"+page);
}