problems trying to separating gui from logic - java

GUI.java
package ccc;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GUI implements ActionListener {
JFrame f;
JPanel bg, s, a;
JLabel ca, £, cav, co, cov, co2, pr, error;
JTextField tf;
JButton b1, b2;
public GUI(){
f = new JFrame();
bg = new JPanel();
bg.setSize(650, 500);
bg.setBackground(Color.darkGray);
bg.setLayout(null);
bg.setLocation(0, 0);
s = new JPanel();
s.setSize(180, 445);
s.setBackground(Color.white);
s.setLayout(null);
s.setLocation(10, 10);
a = new JPanel();
a.setSize(430, 445);
a.setBackground(Color.white);
a.setLayout(null);
a.setLocation(202, 10);
ca = new JLabel("CASH:");
ca.setSize(70,25);
ca.setLocation(10, 25);
£ = new JLabel("£");
£.setSize(10, 25);
£.setLocation(80, 25);
cav = new JLabel("128.23");
cav.setSize(80, 25);
cav.setLocation(90, 25);
co = new JLabel("COCAINE:");
co.setSize(70, 25);
co.setLocation(10, 50);
cov = new JLabel("6 units");
cov.setSize(70, 25);
cov.setLocation(80, 50);
co2 = new JLabel("COCAINE");
co2.setSize(70, 25);
co2.setLocation(10, 25);
pr = new JLabel("£39.95");
pr.setSize(60, 25);
pr.setLocation(90, 25);
tf = new JTextField();
tf.setSize(70, 25);
tf.setLocation(160, 25);
b1 = new JButton("BUY");
b1.setSize(70, 25);
b1.setLocation(270, 25);
b1.addActionListener(this);
b2 = new JButton("SELL");
b2.setSize(70, 25);
b2.setLocation(350, 25);
b2.addActionListener(this);
error = new JLabel();
error.setSize(200, 25);
error.setLocation(50, 50);
s.add(ca);
s.add(£);
s.add(cav);
s.add(co);
s.add(cov);
a.add(co2);
a.add(pr);
a.add(tf);
a.add(b1);
a.add(b2);
a.add(error);
bg.add(s);
bg.add(a);
f.add(bg);
f.setSize(650, 500);
f.setLayout(null);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public static void main(String[] args) {
new GUI();
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1){
Buy a = new Buy();
a.Buy();
}
if (e.getSource() == b2){
}
}
}
Buy.java
package ccc;
public class Buy extends GUI {
String pri, qua, cas, uni, aaa;
double price, quantity, cash, units, total, deduction;
public Buy(){
pri = pr.getText();
price = Double.parseDouble(pri);
qua = tf.getText();
quantity = Double.parseDouble(qua);
cas = cav.getText();
cash = Double.parseDouble(cas);
uni = cov.getText();
units = Double.parseDouble(uni);
total = price * quantity;
if (cash >= total){
deduction = cash - total;
aaa = String.valueOf(deduction);
cav.setText(aaa);
}
else if (cash < total){
error.setText("Sorry, you don't currently have the funds");
}
}
}
Hi folks,
I am currently learning java and wanted to give myself a project that was both challenging and fun. I decided to build a game that I remember playing when I was a kid called dopewars.
This is my second attempt at this game. When I began my first attempt, all went well. After a short while my source code began to fill wildly out of control until I could continue no more as I kept getting lost within mountains of code.
I then decided to begin again, only this time I wanted to seperate the gui from the logic (2 different .java files). This is where my problem lies. Previously this would work fine. Since seperating my java files the functionality has stopped.
When I press jbutton b1, my program is supposed to take the price value of cocaine and the units value entered into the jtextfield by the user, perform a calculation by accessing a method within Buy.java, and then update the appropriate JLabels within the s jpanel of GUI.java.
For example, user x wants to buy cocaine at the price indicated, so he enters a value representing the quantity he would like. He then presses the buy button which ultimately deducts the money from his pocket which is shown on the left side of the program window by using a method within the Buy class.
I hope you can understand my explanation and I hope to hear from you soon. Thanks.in advance. My Source code is below.

Your problems begin right here:
public class Buy extends GUI {
Try to rewrite you game logic so that it does not know a single thing about GUI. Assume you want to make your game playable via command line. Your game logic should be written in a way that it does not have to be changed at all to make this possible.
Try to identify the interface through which the user interacts with model of the game. Then implement this interface.
Here are some ideas (I don't know DopeWars, so I'll give you some generalized examples)
public class MyGameEngine {
public PlayerData getPlayerData() { ... }
public void sellSomeStuff(int numberOfStuff) throws InvalidPlayerOperation {
if (numberOfStuff > getPlayerData().getAmountOfStuff() {
throw new InvalidPlayerOperation("Not enough stuff");
}
....
}
}
public class PlayerData {
public int getAmountOfStuff() { ... }
}
public class InvalidPlayerOperation extends RuntimeException { ... }
There are a lot of patterns in this area. But if you want really to learn something, try it without looking up patterns first. When you got it working, there will be enough time to learn about patterns and then you check your code if you used them intuitively or if you could introduce them to improve its quality.
In particular, the MVC pattern might be overkill for your simple game, especially if you don't want to use an MVC framework (you don't).
The Singleton pattern, on the other hand, seems simple at first but is generally bad style and will only cause problems later on.

The following answer in no shape or form encourages real dope wars ;)
MVC is your friend. The way I do this usually is to write the data and data manipulation parts of the code first, without any thought whatsoever as to how it's going to look on screen.
Try to separate out the "data" part of your code first. Keep that neatly elsewhere; simple pojo objects representing real world objects, for example.
Then write the operations you can do on those objects into different classes. Make these completely independent of UI, as I said before. This ensures that the functionality part of your code is nice and separate, and essentially test-able.
Then write your UI part. A button click routes to a method call in your operations part of the code, for example.
Hope that helps.

Related

Making an interactive GUI in Java for own program

To start with -- I'm not sure, that I have properly formulated the question (I'm new in Java and in making programs with GUI).
It is the following thing, I'm trying to do. I have a window with several similar parameters (numbers are just for distinction between lines and it ist just very simplified example, of what should my GUI be):
Initial Window
Then, by clicking on the "+"-button I would like to add an new line, like here:
Line 35 is added
It should be also possible to delete lines, like here: Line 30 was deleted, by pressing "-"-Button.
As I wrote at the beginning, it is possible, that there was such a question, but I couldn't find anything (probably, because I do not now the keywords or I was looking with a wrong ones).
How such window can be done? The only idea I have is to draw a new window after every +/-.
Addition: Code (not working in the part of changing the number of rows).
import javax.swing.*;
import java.awt.event.*;
public class Test extends JFrame {
public Test() {
setSize(200, 600);
JButton plusButton[] = new JButton[100];
JButton minusButton[] = new JButton[100];
JTextField fields[] = new JTextField[100];
JPanel panel1 = new JPanel();
for (int i=0; i<plusButton.length; i++) {
plusButton[i]=new JButton("+");
minusButton[i]=new JButton("-");
fields[i] = new JTextField("Text "+ i);
}
for (int i=1; i<4; i++) {
panel1.add(plusButton[i*10]);
plusButton[i*10].setActionCommand("add after " +String.valueOf(i));
panel1.add(minusButton[i*10]);
minusButton[i*10].setActionCommand("remove " +String.valueOf(i));
panel1.add(fields[i*10]);
}
panel1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
this.getContentPane().add(panel1);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
for (int i=0; i<100; i++) {
String stand1 = "add after "+String.valueOf(i);
String stand2 = "remove "+String.valueOf(i);
if (stand1.equals(e.getActionCommand())) {
//add "row" of elements
panel1.add(plusButton[i]);
plusButton[i+1].setActionCommand("add");
panel1.add(minusButton[i+1]);
minusButton[i+1].setActionCommand("remove");
panel1.add(fields[i+1]);
} else if (stand2.equals(e.getActionCommand())) {
//delete "row" of elements
}
}
}
public static void main(String[] args) {
Test a = new Test();
}
}
The Problem, that is obvious -- when I want to add 2 rows (i think it is proper definition) of buttons after button 20, there will be an doubling of numbers. As a solution I see here a creation of a new panel for each new row. But it is sounds wrong for me.
P.S. Unfortunately I do not have time to end this topic or to post a working example. I actually found some kind of solution, beginning from the Question here, on Stack Overflow:
Adding JButton to JTable as cell.
So, in case somebody will be looking for such topic, it should sounds like "jButton in jTable".
There are multiple GUI frameworks for Java. First decide which one you wanna use.
As for your particular query
Add functionality to the + and - such that it will create an instance of a field object (that line with parameters as you call them) or destroy that particular instance of the object.
+ is clicked -> Create new object on consecutive line and increase the pointer-count(?) of the following fields.
- is clicked -> Call destructor for the particular object and decrease the pointer-count of the following fields.

Binding a Actionlistener (button) to Resultset.next

I need to make a program that asks data from a mysql database displays it. (in the full program it also needs to be able to create, alter and delete rows but I'm already stuck with displaying).
The way I went at this is by making a connection with jdbc.
Then execute a query and put that in a resultset.
Then using a if statement to get the first row of information with resultset.next and a bunch of parsestring and settext methods.
The next step is a next and previous button to scroll through the resultset and display the information.
My plan was to put a rs.next() in the actionlistener and redo all the setTexts on the textfields with the new strings but I've tried to a 100 different ways it feels like but I keep getting errors one way or the other.
Someone also suggested I should try and set the actionlistener to add 1 to a variable. And then putting the rest of the code in a class where I can call it with a method but I don't know how to make a method like that.
Any help whatsoever would be amazing. I've been coding for only a few weeks now and I'm feeling like I am in way over my head. So if there are any other things I'm doing wrong please tell me. Cheers
The code
package duo.opdracht.info.pagina;
import javax.swing.*;
import java.awt.event.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.*;
public class DUOOpdrachtInfoPagina extends JFrame {
public static void main(String[] args) {
JFrame frame = new DUOOpdrachtInfoPagina();
frame.setSize(1000, 750);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Optredens");
frame.setContentPane(new Paneel());
frame.setVisible(true);
}
}
class Paneel extends JPanel {
private JButton volgendeKnop, vorigeKnop;
private JTextField bandArtiestVak, starttijdVak, eindtijdVak, podiumVak;
private JLabel bandArtiestLabel, starttijdLabel, eindtijdLabel, podiumLabel;
public Paneel() {
setLayout(null);
volgendeKnop = new JButton("Volgende");
volgendeKnop.addActionListener(new ButtonHandler());
vorigeKnop = new JButton("Vorige");
bandArtiestVak = new JTextField(20);
starttijdVak = new JTextField(20);
eindtijdVak = new JTextField(20);
podiumVak = new JTextField(20);
bandArtiestLabel = new JLabel("Artiest / Band: ");
starttijdLabel = new JLabel("Starttijd: ");
eindtijdLabel = new JLabel("Eindtijd: ");
podiumLabel = new JLabel("Podium: ");
volgendeKnop.setBounds(850, 600, 100, 25);
vorigeKnop.setBounds(50, 600, 100, 25);
bandArtiestVak.setBounds(200, 100, 300, 25);
starttijdVak.setBounds(200, 130, 300, 25);
eindtijdVak.setBounds(200, 160, 300, 25);
podiumVak.setBounds(200, 190, 300, 25);
bandArtiestLabel.setBounds(100, 100, 300, 25);
starttijdLabel.setBounds(100, 130, 300, 25);
eindtijdLabel.setBounds(100, 160, 300, 25);
podiumLabel.setBounds(100, 190, 300, 25);
bandArtiestVak.setEditable(false);
starttijdVak.setEditable(false);
eindtijdVak.setEditable(false);
podiumVak.setEditable(false);
add(volgendeKnop);
add(vorigeKnop);
add(bandArtiestVak);
add(starttijdVak);
add(eindtijdVak);
add(podiumVak);
add(bandArtiestLabel);
add(starttijdLabel);
add(eindtijdLabel);
add(podiumLabel);
// create our mysql database connection
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/DUO_1", "duo1", "duo1");
Statement stmt = null;
String query
= "SELECT BandArtiestNaam, Starttijd, Eindtijd, Podiumnaam FROM optreden";
stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(query);
if (rs.next()) {
String naam = rs.getString(1);
String stijd = rs.getString(2);
String etijd = rs.getString(3);
String pnaam = rs.getString(4);
bandArtiestVak.setText(naam);
starttijdVak.setText(stijd);
eindtijdVak.setText(etijd);
podiumVak.setText(pnaam);
}
} catch (SQLException e) {
System.out.println(e);
}
}
class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
}
}
}
Break your problem down into different concerns, you shouldn't have a class which does absolutely everything in your application. You will find, as you are right now, that when you have a problem, it is very hard to track down, much harder than you could have ever imagined. Lets rather start by breaking this problem down into manageable chunks, that's really all programming is.
View - your actual Swing panel with the other panels, this should have nothing other than just a bunch of panels and buttons, do not have any sql code there, and don't have any, (or extremely view) listeners, absolutely nothing but the view.
Dao (data access object) - This class has all your SQL code, the only thing it does is perform CRUD operations. It may do some other stuff to change a result set into something more meaningful, it may be a good idea to contain the result set to this class, as this is a concern of the dao. In general people use things like hibernate instead of writing SQL code but your free to do as you please, but I encourage you to check it out.
Controller - This will be the link between your View, and your Dao. It will take both of these as parameters in its constructor. The controller will add action listeners to wherever it needs to in your view, take any inputs from the view, and call the Dao with the corresponding input arguments, and return this back to the view as needed.
This is a design pattern called MVC - (model view controller) different variations exist for different applications desktop/web ect. This will allow you to separate each concern into the relevant component, and test to see if each one is working, and where the problem is. You will be able to test, for instance the Dao, without needing to create a view and add listeners. Sounds like you are learning so I strongly suggest you learn this design pattern. You will find that you are unable to make a substantial application with your current design, as problems becoming ever increasingly harder to track down, and new functionality harder to add.
A few more things, you should really just convert the whole result set into something more meaningful, it's already loaded. Using rs.next every time you want a new row will mean you cannot close the result set, and you'll probably have all these resource warnings. Otherwise check out hibernate. I very much liked this site when I was starting to learn programming in Java, I suggest you check it out https://www.caveofprogramming.com/java-design-patterns/mvc-example.html

Eclipse program JPanel wont run

I'm not sure why but when I try to run this the only thing that shows is the last program I ran, I even added the serialVersionUID and it still wont show. Anyone have an i dea on why, maybe some setup problem on my eclipse or coomputer?
import java.awt.Graphics;
import javax.swing.JPanel;
public class Shapes extends JPanel {
private static final long serialVersionUID = 1L;
private int choice;
public Shapes(int userChoice) {
choice = userChoice;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; 1 < 10; i++) {
switch (choice) {
case 1:
g.drawRect(10 + i * 10, 10 + i * 10, 50 + i * 10, 50 + i * 10);
case 2:
g.drawOval(10 + i * 10, 10 + i * 10, 50 + i * 10, 50 + i * 10);
break;
}
}
}
}
First of all, you have no entry-point to your program. You can't just expect a program in Java, or basically any other compiled language to run without an entry point.
Inside your class, you need to have the following for the program to begin:
public static void main(String[] args) {
// Entry-point began. Put code in here.
}
Secondly, it is not a good practise (correct me if I'm wrong) to extend any of the JComponent derivatives. Without explaining again, a good reason can be found here:
Excerpt:
It makes it harder to change things later - if you've made a class public, swapping the superclass is going to break subclasses - it's a choice which, once you've made the code public, you're married to. So if you're not altering the real functionality to your superclass, you get much more freedom to change things later if you use, rather than extend the thing you need. Take, for example, subclassing JPanel - this is usually wrong; and if the subclass is public somewhere, you never get a chance to revisit that decision. If it's accessed as JComponent getThePanel() , you can still do it (hint: expose models for the components within as your API). This especially applies because your class is a Shape. So when Shape extends JPanel, every single shape will.
Object hierarchies don't scale (or making them scale later is much harder than planning ahead) - this is the classic "too many layers" problem. I'll go into this below, and how the AskTheOracle pattern can solve it (though it may offend OOP purists).
Especially since you are extending JPanel, and aren't even initialising a JFrame to begin with. Before starting out with Swing applications in Java, you should read the JavaDoc and Oracles examples beforehand...
JavaDoc: JFrame / JPanel
Example: How to make Frames.
So, revising on what I have said, a basic Swing class would look as follows:
import javax.swing.*;
public class Shapes {
public Shapes() {
JFrame frame = new JFrame();
JPanel window = new JPanel();
frame.setSize(600, 400); // Width: 600, Height: 400.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(window);
window.setLayout(new BorderLayout());
// Perform graphics drawing.
frame.revalidate();
frame.repaint();
}
public static void main(String[] args) {
new Shapes();
}
}

JButton doesn't appear until clicked

For this program, the JButton doesn't seem to show up unless you click the area where the JButton should be; the JFrame starts up blank. The moment you click the button, the respective code runs and the button finally shows up.
How do I get the buttons to show up upon starting the program?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/*
The Amazing BlackJack Advisory Tool by JoshK,HieuV, and AlvinC.
Prepare to be amazed :O
*/
public class BlckJackUI {
//main class, will contain the JFrame of the program, as well as all the buttons.
public static void main(String args[])
{
//Creating the JFrame
JFrame GUI = new JFrame("Blackjack Advisor");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(1300, 900);
GUI.setContentPane(new JLabel(new ImageIcon("C:\\Users\\Hieu Vo\\Desktop\\Green Background.png")));
GUI.setVisible(true);
// Because each button needs to run through the Math class.
final Math math = new Math();
// The Ace Button:
ImageIcon Ace = new ImageIcon("/Users/computerscience2/Downloads/Ace.jpg");
JButton ace = new JButton(Ace);
ace.setSize(300, 100);
ace.setLocation(100, 100);
ace.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Automatically default the the Ace to 11, and if Bust, Ace becomes 1.
if (math.array.playerhandtotal <= 21)
{
math.cardvalue = math.cardvalue + 11;
}
else
{
math.cardvalue = math.cardvalue + 1;
}
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
GUI.add(ace);
ImageIcon Two = new ImageIcon("/Users/computerscience2/Downloads/2.jpg");
JButton two = new JButton(Two);
two.setSize(300, 100);
two.setLocation(100, 200);
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
/*
This generally repeats throughout the whole class, and the only
thing different is the changing cardvalue. When a button is pressed,
respective cardvalues are added into the playerhand ArrayList, and
totaled up to form playerhandtotal, which is a major factor in
bringing up the advice.
*/
math.cardvalue = math.cardvalue + 2;
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
GUI.add(two);
Et cetera, Et cetera... Just a bunch of the same stuff, more buttons coded the same exact way as JButton two, but with different value associated to them.
JButton start = new JButton("Start/Reset");
start.setSize(300, 100);
start.setLocation(500,500);
start.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
/*
The start button also acts like a reset button, and the concept is fairly
simple. If we reset all the important values to 0 or "null," then the
program acts as if it was just opened.
*/
Arrays array = new Arrays();
array.playerhand.clear();
array.dealer = 0;
math.array.starttracker++;
math.array.clicktracker = 0;
array.playerhandtotal = 0;
math.cardvalue = 0;
array.result = null;
JOptionPane.showMessageDialog(null,"Please select the card \nthat the dealer is showing :)");
}
});
GUI.add(start);
GUI.setLayout(null);
This is all in the same class, and I understand a layout would be nicer, but perhaps there's a way to fix this issue using what I have now?
The program starts blank because you are calling setVisible before you add components. Call setVisible after you add components (in the end of contructor) and it should work fine.
Also, avoid absolute positioning and call of set|Preferred|Minimum|MaximumSize methods for your components. Learn how to use layout managers.
Write GUI.validate(); after you add all the components to your frame. Any time you add something to a frame you have to validate it like this. Otherwise, you will get the behavior that you have described.
No. The problem is caused by the layout. Before adding anything to a JFrame or a JPanel which you want it to have an absolute position, you have to setLayout(null). Otherwise, you'll have unexpected behaviours all the time. I just figured it out by myself after three hours of experimenting; suddenly, I connected your post with other different subject, and it worked, but this isn't well explained on the Internet yet.

Issues creating java GUI with while loop

I am creating a java GUI which is a fortune teller. The GUI will spit out one of twelve fortunes every time you click the "get my fortune" button, the strings will never repeat back to back, can can repeat later after other strings have gone before it. I have made already for the most part. But now I am having some trouble creating the while loops to display the strings without repeating. I have looked at my book which didn't really help. If you guys could point me in the right direction,it would be much appreciated. Thanks!
I entered all of the code so you can see the variables used. But my question starts at class RndButtonListener.
package FortuneTellerRunner;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
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;
/**
*
* #author a3cal_000
*/
class FortuneTellerFrame extends JFrame
{
final private JPanel mainPnl, titlePnl, displayPnl, buttonPnl, imagePnl;
final private JButton quitBtn, rndBtn;
final private JLabel titleLbl, iconLbl;
final private JTextArea displayTa;
final private JScrollPane scroller;
public String[] fortune = new String [12];
int newIndex, oldIndex;
private static final int HEIGHT = 250;
private static final int WIDTH = 450;
public FortuneTellerFrame()
{
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPnl = new JPanel();
mainPnl.setLayout(new BorderLayout());
displayPnl = new JPanel();
buttonPnl = new JPanel();
titlePnl = new JPanel();
ImageIcon icon = new ImageIcon("FortuneTellerIcon.JPEG");
iconLbl = new JLabel(icon);
titleLbl = new JLabel("Fortune Teller!");
displayTa = new JTextArea();
imagePnl = new JPanel();
scroller = new JScrollPane();
// Create the layout of the title panel
titlePnl.setLayout(new GridLayout(2,1));
add(mainPnl);
// Set the label to the panel.
titlePnl.add(titleLbl);
titlePnl.add(iconLbl);
// add the panel to the main panel.
mainPnl.add(titlePnl, BorderLayout.NORTH);
mainPnl.add(scroller, BorderLayout.CENTER);
mainPnl.add(displayTa, BorderLayout.CENTER);
// Create the "Get my fortune button.
rndBtn = new JButton("Get My Fortune!");
quitBtn = new JButton("Quit");
// Add the buttons to the buttonPnl in grid layout.
buttonPnl.add(rndBtn);
buttonPnl.add(quitBtn);
// Create the grid layout for the button panel.
buttonPnl.setLayout( new GridLayout(1, 2));
// Add the button panel to the grid layout, South.
mainPnl.add(buttonPnl, BorderLayout.SOUTH);
ActionListener listener = new RndButtonListener();
rndBtn.addActionListener(listener);
quitBtn.addActionListener(listener);
}
class RndButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
fortune[0] = "He who throws dirt is losing ground.";
fortune[1] = "You will find the love of your life in food.";
fortune[2] = "Do or do not, there is no try.";
fortune[3] = "Tomorrow is a better day to try anything of importance.";
fortune[4] = "Life's not about how hard you can hit, but how hard you can get hit and keep moving forward.";
fortune[5] = "You can't be late until you show up.";
fortune[6] = "If you think things can't get worse it's probably only because you lack sufficent imagination.";
fortune[7] = "If youre at the top it means you have further to fall.";
fortune[8] = "Even in last place, youre still in the race.";
fortune[9] = "The road to riches is paved on the failures of others.";
fortune[10] = "If you feel like your going no where, get off the treadmill.";
fortune[11] = "Thinking about going to the gym is just as good as going.";
Random rnd = new Random(fortune.length);
do
{
newIndex = rnd.nextInt(fortune.length);
}
while(newIndex == oldIndex);
do
{
System.out.println(fortune[newIndex]);
displayTa.append(fortune[newIndex] + "||");
displayTa.updateUI();
mainPnl.updateUI();
oldIndex = newIndex;
}
while(newIndex != oldIndex);
class QuitButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
System.exit(0);
}
}
}
}
}
The basic problem is you are re-creating the Random with the same seed each time, which is generally creating the same random sequence over and over again.
Instead try using...
do {
newIndex = (int) Math.round(Math.random() * (fortune.length - 1));
} while (newIndex == oldIndex);
You also don't need the second loop, it's just clutter that confuses the situation.
You may also find that...
displayTa.append(fortune[newIndex] + "\n");
produces nicer output (IMHO)
You may also wish to take a look at How to use Scroll Panes
Your program run fine, but this is a problem, fortune.length is a random seed which return me only 6 and 8 when I later called Random.nextInt().
Random rnd = new Random(fortune.length);
Do it this way
Random rnd = new Random();
and also consider the formatting solution given by MadProgrammer.
Random() gives you same number pattern. Try Random(System.currentTimeMillis()). It uses current time as seed, so you can get real random numbers.
I did something similar to this just today, so let's see if I can remember... I made an ArrayList of type int of how many items I had (fortunes)
ArrayList<Integer> fortuneSeq = new ArrayList<Integer>();
Then add in some numbers starting from 0 to code for the fortunes.
for(int i = 0; i < fortune.length; i++) {
fortuneSeq.add(i);
}
Then I used the shuffle() method from the Collections class to randomize the list.
Collections.shuffle(fortuneSeq);
After that, just loop through to access the fortunes.
for(int i = 0; i < fortune.length; i++) {
System.out.println(fortune[fortuneSeq.get(i)]);
//...
}
Edit: Silly autocorrect, you don't like programmers.
Edit: Fixed some furtunes instead of fortunes and fixed println statement.

Categories

Resources