1
//FortuneTellerFrame.java

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.event.ActionEvent;
import java.util.Random;

public class FortuneTellerFrame extends JFrame
{
    JPanel master, panel1, panel2, panel3;
    JLabel image, heading, textArea;
    ImageIcon logo;
    JTextArea screen;  
    JScrollPane scroller;
    JButton quit, generate;
    ActionListener clicker, quiter;
    ArrayList<String>fortuneDB=new ArrayList<>();

    public FortuneTellerFrame()
    {
       super("Fortune Spitter");
       master = new JPanel();
       panel1();
       panel2();
       panel3();
       fortuneHolder();

       //add panels to master
       master.setLayout(new BorderLayout());
       master.add(panel1, BorderLayout.NORTH);
       master.add(panel3, BorderLayout.SOUTH);
       master.add(scroller, BorderLayout.CENTER);

       //master adjustments
       add(master);
       setSize(750,750);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       pack();

    }

    public void panel1()
    {
        panel1=new JPanel();
        heading = new JLabel("Harry Potter Fortune Teller");
        heading.setFont(new Font("Courier New", Font.ITALIC, 25));
        logo=new ImageIcon("\\Users\\x\\Desktop\\harry.jpg");
        image=new JLabel(logo);
        panel1.add(image);
        panel1.add(heading);
    }

    public void panel2()
    {
        panel2=new JPanel();
        screen=new JTextArea(50,50);
        screen.setEditable(false);
        scroller=new JScrollPane(screen); 
        scroller.setVisible(true);
    }

    public void panel3()
    {
        panel3=new JPanel();
           //fortune-spitter
        generate = new JButton("Spit Fortune");
        generate.setFont(new Font("Times New Roman", Font.BOLD, 20));
        generate.addActionListener((ActionEvent ae) -> 
       //generate fortune button logic
       //Please suggest a way in which I can generate a new fortune each time without having to repeat the old fortune again.
    {
            int currentRnd;
            int previousRnd=0;
            Random rnd = new Random(); 
            do 
            {
                currentRnd=rnd.nextInt(12);//there are 12 fortunes
            }
            while(currentRnd== previousRnd);
            String fortune = fortuneDB.get(currentRnd); 
            int spot =screen.getCaretPosition();
            screen.insert(fortune+"\n", spot); 
            currentRnd = previousRnd;

//I am unable to write a loop that generates a new fortune each time I hit generate. }); panel3.add(generate);

        //quitter
        quit=new JButton("Quit"); //Text inside the button
        quit.setFont(new Font("Times New Roman", Font.BOLD, 20));
        quit.addActionListener((ActionEvent ae) -> 
        {
        System.exit(0);
        });
        panel3.add(quit);

//in the panel3 I want to output fortunes to the JTextArea and I do not want to repeat the same fortune twice. I tried some stuff on Google, but nothing helped. }

     private void fortuneHolder() 
    {
       fortuneDB.add("You will get a good GPA");
       fortuneDB.add("Your GPA does not mean anything!");
       fortuneDB.add("Please catch up on CPII labs");
       fortuneDB.add("Don't turn assignments in for points, make sure you gain the knowledge");
       fortuneDB.add("You will get a good co-op");
       fortuneDB.add("Click generate fortune to discover your true fortune");
       fortuneDB.add("The weather will soon be nice");
       fortuneDB.add("Buy a PowerBall");
       fortuneDB.add("Here are your lucky numbers 17-19-23-50-51");
       fortuneDB.add("If you win the Powerball dropuut of school");
       fortuneDB.add("Snow Day Coming");
       fortuneDB.add("Do Not waste your time");
    }   
}//end of FrameClass

//FortuneTellerViewer.java

    import javax.swing.JFrame;

public class FortuneTellerViewer 
{
    public static void main(String[]args)
    {
        JFrame frame = new FortuneTellerFrame();
        frame.setVisible(true);
    }
}
Sumanth M
  • 149
  • 1
  • 11
  • The above post contains 2 separate .java files 1) FortuneTellerFrame 2) FortuneTellerViewer I am unable to write a loop that generates a new fortune onto my JTextArea (screen), that generates a unique fortune each time I hit the "Spit Fortune" JButton. NOTE: Once a fortune is generated it cannot be repeated again in the same row. – Sumanth M Feb 28 '16 at 00:41
  • Possible duplicate of http://stackoverflow.com/questions/5224877/java-generate-random-range-of-specific-numbers-without-duplication-of-those-nu – Andreas Feb 28 '16 at 00:52

1 Answers1

1

Start by using Collections.shuffle to randomise the list

Then when the button is clicked, you would remove the first element from the list (List#remove(int)) until there are no more elements in the list.

If you need the original List, you could use a secondary list, this way, you could re-generate the "pick list" once you run out

Conceptually, the idea you're after is something like...

import java.util.ArrayList;
import java.util.Collections;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    private ArrayList<String> fortuneDB = new ArrayList<>();

    public Test() {
        String last = null;
        for (int index = 0; index < 10; index++) {
            // This makes sure that the last fortune isn't
            // the first on the next cycle...
            do {
                makeFortunes();
            } while (fortuneDB.get(0).equals(last));
            while (fortuneDB.size() > 0) {
                last = fortuneDB.remove(0);
                System.out.println(last);
            }
            System.out.println("----------");
        }
    }

    protected void makeFortunes() {
        fortuneDB = new ArrayList<>();
        fortuneDB.add("You will get a good GPA");
        fortuneDB.add("Your GPA does not mean anything!");
        fortuneDB.add("Please catch up on CPII labs");
        fortuneDB.add("Don't turn assignments in for points, make sure you gain the knowledge");
        fortuneDB.add("You will get a good co-op");
        fortuneDB.add("Click generate fortune to discover your true fortune");
        fortuneDB.add("The weather will soon be nice");
        fortuneDB.add("Buy a PowerBall");
        fortuneDB.add("Here are your lucky numbers 17-19-23-50-51");
        fortuneDB.add("If you win the Powerball dropuut of school");
        fortuneDB.add("Snow Day Coming");
        fortuneDB.add("Do Not waste your time");
        Collections.shuffle(fortuneDB);
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • @Sumanth M: Also consider treating the `List` as s circular queue, shown in the example cited [here](http://stackoverflow.com/a/8627912/230513). – trashgod Feb 28 '16 at 10:30
  • @MadProgrammer Thanks for the follow up. Where would I include the new lines of code which will randomize the items in my arrayList – Sumanth M Feb 28 '16 at 21:30
  • Where ever you need them, depending on whether you want a temporary list or use the main list or if you want to randomise the list before getting the next quote or just randomise it once – MadProgrammer Feb 28 '16 at 21:33
  • I apologize I am very new to programming and I have a hard time comprehending. Can you please show me how to print a non repeatng fortune onto the JTextArea with the code in the comment – Sumanth M Feb 28 '16 at 21:36
  • http://java2novice.com/java-collections-and-util/arraylist/shuffle/ I found this on the net, but I am unable to modify my code – Sumanth M Feb 28 '16 at 21:37
  • You have a `List`, you just need to call `Collections.shuffle(fortuneDB)` at some point after you've added data to it, when and where will depend on when and where you want it randomised – MadProgrammer Feb 28 '16 at 21:39
  • Here is what I did. int currentRnd; int previousRnd=0; Random rnd = new Random(); do { currentRnd=rnd.nextInt(12); //there are a total of 12 fortunes Collections.shuffle(fortuneDB); } while(currentRnd== previousRnd); String fortune = fortuneDB.get(currentRnd); int spot =screen.getCaretPosition(); screen.insert(fortune+"\n", spot); currentRnd = previousRnd; – Sumanth M Feb 28 '16 at 21:45
  • It is still not working I want it to randomize so that two fortunes do not repeat one after the other everytime the user clicks the spit fortune button – Sumanth M Feb 28 '16 at 21:45
  • So? Randomise to once, then when you want a fortune, you could remove the first element from the `List` (and maybe add it back to the end so it will cycle) – MadProgrammer Feb 28 '16 at 21:54
  • No, that means you understand what the demo code is doing and adapt it to your needs – MadProgrammer Feb 28 '16 at 22:43
  • I tried the demo code, but for some reason I am unable to figure out how to generate 1 fortune per 1 click – Sumanth M Feb 29 '16 at 16:10