How can I create Shuffle play (with GUI) in java - java

I have to create an application for audio stream with different functionalities. I am stuck with the shuffle play action. Because on my previous project were GUI wasnt included I created this method where I created a new playlist with a different order.
But now where I have the GUI part and I need to show the playlist in a JList I cant change the original playlist. How am I supposed to get random songs when I press Next without changing the original playlist? Thank you.
public ArrayList<String> playRandom(ArrayList<String> songsPath, Player p) {
ArrayList<String> newPlaylist = new ArrayList<>();
while(songsPath.size()>0) {
String song = songsPath.get(randomIndex(songsPath.size()));
songsPath.remove(song);
newPlaylist.add(song);
}
return newPlaylist;
}
That's what I used to do but it changes the original playlist which is a problem if someone wants to go back to playing the songs in the original row.

Related

ActionListener and dynamic(?) GUI

I've read through a dozen or so actionlistener/loop related questions here, but I'm not sure I've found my answer. I started on my first large Java project, a text RPG that's spiraled into around 5K lines of logic and game features which was functioning as intended using just the console - when I decided I'd try to build a Java swing GUI for it instead. Here's my problem:
I use a Room object which handles the description of where the player is at and also has an array of options for the player to choose next which it creates dynamically based on what cell the room's id is in on a csv file and what is beside it. I stopped outputting this to the console and instead started creating JButtons based on the options array like so:
public void showNarrate(){
add(dd,gridConstraints);
optionCopy.clear();
int i = 0;
for(JButton j : optionButtons){
//adding and formatting buttons to gridBagConstraint I also set actionCommand for each button to the triggerValue (ID of the next room which the button should take the player to)
}
//I tried using a copy of my JButton array here so I could have something to iterate over in actionListener after clearing out the original
//(Since it needs to be cleared so the next Room's buttons can be built after the player chooses an option)
for(JButton j : optionButtons){
optionCopy.add(j);
}
optionButtons.clear();
//dd is a seperate drawingComponent I used for outputting room descriptions which may be totally unnecessary at this point :/
dd.repaint();
setVisible(true);
}
Over in actionlistener (Same class) this is how I tried to swing it:
for(JButton j : optionCopy){
if(e.getActionCommand().equals(j.getActionCommand())){
Main.saveRoom = Main.currentRoom;
Main.currentRoom = j.getActionCommand();
System.out.println(Main.currentRoom);
}
}}
Then in my main class I call:
narrator.narrate(currentRoom, saveRoom); which takes care of some other logic concerning locked doors, encounters, etc.
Also in Main loop are some other methods related to autosave and tracking which rooms the player has visited. I know from other q/a i'v read on here that this is all pretty bad design, and I'm sttarting to understand that now, but my issue is this:
The first room of the game loads up fine, when I click a button it outputs to console(Just for testing) the correct trigger value of the room the button should be calling, so I'm getting that far, but how can I call the same method over again now?
-If I call narrate from actionListener it will wind up calling itself again and complain about ConcurrentModification.
-If I try to keep a loop going in my Main class it will keep looping and won't allow for the player to actually choose a button.
I've never used threads before, which I wonder might be the answer,and the closest thing to a related answer I've found is this:
Java: Method wait for ActionListener in another class
but I don't think moving actionListener to Main class would resolve my problem which is actionListener winding up calling itself recursively. And as for the observer-observable pattern... I just can't understand it :(
I appreciate any and all help, I've learned a LOT trying to make this thing work without seeking help as much as possible but this has stumped me.
Your loop in actionPerformed only checks whether a JButton exists in your optionList with the given actionCommand. However this can be done before actually doing something:
boolean contained = false;
for (JButton j : optionButtons)
if (j.getActionCommand().equals(e.getActionCommand()))
contained = true;
if (contained) {
// change room
}
now you can call narrate because you have finished iterating over the collection beforehand and will not get a ConcurrentModificationException

Why do i get a NullPointerException when loading in ImageViews

I am currently making a poker game in java. The model works just fine. I do however also have to make a proper view for the game. I have to use javaFX scenebuilider as well as a graphic view class with actual code. In order to do this I made a superview to include both. When i am trying to run my application I get a white window and a nullpointerexception (for the code I included).
I do not get what I am doing wrong, since no one ever explained to me the basics of Imageviews and loading images in.
I made a package "res" where I embedded all the pics that represent my cards in the deck. Also note that k.toString() automatically generates the proper name of the file including the ".png" part. I printed it out and I am sure it works!
I use the for-loop to go through my list of cards that make the deck. My cards are generated in the Class Card. So basically I am going through an ArrayList of cards.
public void initializeDeck(){
for(Card c:model.getRound().getDeck().getList()){
int index = model.getRound().getDeck().getList().indexOf(c);
imv = new ImageView(new Image(getClass().getResourceAsStream("/res/"+k.toString()),95, 141, false, true));
deckView.add(index, imv);
}
getChildren().addAll(stapelView);
}

Selecting Objects from an ArrayList using Keyboard Input

thanks for coming by. I have been working on a game inventory system, its been working awesome when I pick items from the world and then they get added into the list and displayed inside an inventory box when I hit "I", but now I want to be able to interact with them using the arrow keys and the ENTER key, every item has a method called "use" in which it executes an action, (Ex: HP potion, increases player health) now I want to be able to select items from the list and when I hit enter that the selected item's method "use" is actually used, I've got the input handling covered, I only wish to know how to access the objects inside the arraylist depending on the selected choice.
So far I got:
private int currentChoice=0;//the value is the index position within the
//array, so 0 would mean I selected an object
//at index 0.
private ArrayList<Item> playerItems;//This is the array in which I store
//the player's items.
private boolean inventoryDisplayed;//This is used when I click "I" then the
//the arrow keys stop moving the player
//and should now be used to interact with
//the items inside the inventory.
If you guys could help me that would brighten my week, seriously, this project is very important to me, any help is very appreciated, thanks for taking your time to help a fellow member from stackOverflow, may good fortune shine on your life, have a big choco cookie just for reading up 'till here. :)
Basically you can get the element at a specific position in a list by using
list.get(index);
or in your case
playerItems.get(currentChoice);
First thing, define playerItems as private List<Item> playerItems; and then instantiate it as playerItems = new ArrayList<Item>();. This is one of the core principles of well designed code, particularly if you need to change playerItems to a LinkedList later on.
You'll need to add a KeyListener or KeyAdapter to the appropriate component when the 'i' character is typed. Then, implement the keyTyped (or maybe the keyPressed) method as follows:
#Override
public void keyTyped(KeyEvent e)
{
switch(e.getKeyChar())
{
case KeyEvent.VK_LEFT:
if(--currentChoice < 0)
currentChoice = playerItems.size() - 1;
break;
case KeyEvent.VK_RIGHT:
if(++currentChoice >= playerItems.size())
currentChoice = 0;
break;
}
}
Then you can retrieve the appropriate item with: playerItems.get(currentChoice);

Java ArrayList in ArrayList

I have a question about an ArrayList inside an Arraylist. It's about multiple worlds with multiple spawns. I want to check every world one by one and save all the spawns of that world in an ArrayList. At the end I have an ArrayList with on every position (every position is a world) another Arraylist containing the spawns of that world.
How can I do this if I don't know how many spawns or worlds there are going to be? I thought of this:
Looking to just one world:
public ArrayList<Location> Spawnpoints = new ArrayList<Location>();
//ArrayList containing all the spawns of this world).
Looking to every single spawn in the world
Spawnpoints.add(new Location(spawnX , spawnY , spawnZ));
//Adding every spawn to the ArrayList spawnpoints.
So after I looked at a world I have filled the ArrayList spawnpoints with locations. Now I want to add the ArrayList spawnpoints to a new ArrayList worlds.
After that I will repeat the code above for the next world, untill I have had all the worlds.
EDIT.
I think it's working. I have troubles with getting the size of the list when I only have the name.
So let's say I did this: allSpawnpoints.put("yourWorld",Spawnpoints);
Now I want to get the size of the Spawnpoints list for the string yourWorld. Any idea how I can do this?
I tried: int number = allSpawnpoints.get("yourWorld").size();
it looks like that isn't working.
I hope someone can help me! Thanks for reading.
Regards.
Instead of an ArrayList or World objects try using a Map of World to List of Location. Something like this:
Map<World,List<Location>> allSpawnpoints = new HashMap<World,List<Location>>();
Then, after you have created your list of spawnpoints for a World put it into your Map like this:
allSpawnpoints.put(yourWorld,Spawnpoints);
... and then move onto the next World.
I would also suggest renaming Spawnpoints as spawnPoints.

creating objects for the correct object

first off apologies for the question title I wasn't to sure what to name this.
anyway I'm working on a game, where there can be a number of players who can each have a number of pets. I have developed the main structure to the game, e.g. player class, pet class and a main class .. From there I have been working on the GUI, where I ask how many players, and how many pets each player would like.. Where I am getting stuck is how to to create the pets for each player.
I have created a pretty basic form that asks for the player to choose a pet type, give it a name and then create the pet..
public void createPets( final Player player){
//various buttons,comboBox and labels go here
//layout managers
//add it all to a frame
JButton jbCreatePet = new JButton("Create Pet");
jbCreatePet.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String name = jtfName.toString();
if (cbSpecies.getSelectedIndex() == 0){
Alien alien = new Alien();
alien.setName(name);
player.getAllPets.add(alien);
}
else if(cbSpecies.getSelectedIndex() == 1){
create other pet2
}
else{
create other pet3
}
}
});
player is a Player object passed into the method using a for loop..
for (Player player: allPlayers){
createPets(player);
}
Now I know that its NOT correct to use the for loop e.g. the form will simply skip to the last player and none of the other players will get to create a pet..
So I have a couple of questions:
When I assigned the created pet to the players list of all pets, eclipse told me I had to create it final. I somewhat understand why but what I am wondering is by making the player parameter final does that mean i wont be able to create pets for other plays, only the first player..
How can I show my form to each player e.g. 2 players in the game both with 2 pets, player 1 chooses a pet and gives it a name then creates it, he will then be told he needs to create another pet (form shows again) so he creates another pet, then its player 2s turn to choose and create 2 pets... I guess I am trying to figure out how to pass the right player argument into the createPet method at the right time...
Please let me know if you would like me to clarify anything else...
Big thanks to whoever can help me with this!!!!
When I assigned the created pet to the players list of all pets, eclipse told me I had to create it final. I somewhat understand why but what I am wondering is by making the player parameter final does that mean i wont be able to create pets for other plays, only the first player..
Eclipse isn't requiring this -- Java is because you're using the Player parameter within an anonymous inner class and so it must be final. This will not prevent you using this same method for other players.
How can I show my form to each player e.g. 2 players in the game both with 2 pets, player 1 chooses a pet and gives it a name then creates it, he will then be told he needs to create another pet (form shows again) so he creates another pet, then its player 2s turn to choose and create 2 pets... I guess I am trying to figure out how to pass the right player argument into the createPet method at the right time...
The main Game object will control all of the above, correct? I suppose you could use a for loop, one that say displays a modal dialog such as a JOptionPane inside of the loop.
Another option is to create JPanel view that allows all players to enter their pets. It's all up to you, and I recommend that you experiment with different approaches.
One main thing that you'll want to be sure to do early on is to strongly separate your program's logic from the GUI. For instance your Player and Pet classes should have no knowledge about the GUI, should have no Swing code whatsoever, so that the code to logically add Pets is non-GUI (but can and will be used by the GUI).
Edit
Consider giving your Game class a registerPlayer(Player player) or editPlayer(Player player) method that any Player can call to register their name, their Pets, and any other property that may be needed to play the game. Then have this method called once when a JButton is pressed. Don't allow the game to progress unless all Players have been properly registered.

Categories