For my program, I am trying to get a random range with variables I can input, but it seems to cause the program to crash when I try to work it. I have pinpointed where the main problem is, though:
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import java.util.Random;
public class main {
private static Text attackBox;
private static Text cooldownBox;
private static Text ammoBox;
private static Text stabilityBox;
static int attack = 0;
static int ammo = 0;
static int stability = 0;
static int damage = 0;
static int damageRaw = 0;
static int minuteDamage = 0;
static int minuteDamageRaw = 0;
static float attacksPerMinute = 0;
static float cooldown = 0;
static Random rand;
/**
* Launch the application.
* #param args
*/
public static void main(String[] args) {
Display display = Display.getDefault();
Shell shell = new Shell();
shell.setSize(450, 269);
shell.setText("Xenolbade X DPS Calculation");
shell.setLayout(null);
Label lblAttack = new Label(shell, SWT.NONE);
lblAttack.setBounds(10, 10, 69, 15);
lblAttack.setText("Attack:");
Label lblCooldown = new Label(shell, SWT.NONE);
lblCooldown.setBounds(10, 31, 69, 15);
lblCooldown.setText("Cooldown: ");
Label lblAmmo = new Label(shell, SWT.NONE);
lblAmmo.setBounds(10, 52, 69, 15);
lblAmmo.setText("Ammo:");
Label lblStability = new Label(shell, SWT.NONE);
lblStability.setBounds(10, 73, 69, 15);
lblStability.setText("Stability: \u00B1");
attackBox = new Text(shell, SWT.BORDER);
attackBox.setText("0");
attackBox.setBounds(85, 10, 76, 21);
cooldownBox = new Text(shell, SWT.BORDER);
cooldownBox.setText("0");
cooldownBox.setBounds(85, 31, 76, 21);
ammoBox = new Text(shell, SWT.BORDER);
ammoBox.setText("0");
ammoBox.setBounds(85, 52, 76, 21);
stabilityBox = new Text(shell, SWT.BORDER);
stabilityBox.setText("0");
stabilityBox.setBounds(85, 73, 76, 21);
Label label = new Label(shell, SWT.NONE);
label.setBounds(10, 94, 414, 15);
label.setText("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Label lblWithoutStability = new Label(shell, SWT.NONE);
lblWithoutStability.setBounds(10, 115, 414, 15);
lblWithoutStability.setText("Within a minute, without stability, your weapon would do:");
Label rawDamageLabel = new Label(shell, SWT.NONE);
rawDamageLabel.setBounds(10, 136, 414, 30);
rawDamageLabel.setText(damageRaw + " damage " + (int)attacksPerMinute + " times for a total of "
+ minuteDamageRaw + " damage per minute.");
Label lblNewLabel_1 = new Label(shell, SWT.NONE);
lblNewLabel_1.setBounds(10, 172, 414, 15);
lblNewLabel_1.setText("If we include the stability, we can estimate a minute of combat to do:");
Label stabilityDamageLabel = new Label(shell, SWT.NONE);
stabilityDamageLabel.setBounds(10, 193, 414, 30);
stabilityDamageLabel.setText(damage + " damage " + (int)attacksPerMinute + " times for a total of "
+ minuteDamage + " damage per minute.");
Button runButton = new Button(shell, SWT.NONE);
runButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
damage = 0;
damageRaw = 0;
minuteDamage = 0;
minuteDamageRaw = 0;
attack = Integer.valueOf(attackBox.getText());
cooldown = Float.valueOf(cooldownBox.getText());
ammo = Integer.valueOf(ammoBox.getText());
stability = Integer.valueOf(stabilityBox.getText());
attacksPerMinute = 60 / cooldown;
damageRaw = attack * ammo;
minuteDamageRaw = damageRaw * (int)attacksPerMinute;
rawDamageLabel.setText(damageRaw + " damage " + (int)attacksPerMinute + " times for a total of "
+ minuteDamageRaw + " damage per minute.");
float flux = stability/100;
int max = (int)(attack * (1 + flux));
int min = (int)(attack * (1 - flux));
System.out.println(min);
System.out.println(max);
for (int i = 0; i < attacksPerMinute; ++i) {
damage = 0;
for (int j = 0; j < ammo; ++j) {
damage += damageFlux(min, max);
//
}
minuteDamage += damage;
}
stabilityDamageLabel.setText(damage + " damage " + (int)attacksPerMinute + " times for a total of "
+ minuteDamage + " damage per minute.");
}
});
runButton.setBounds(349, 10, 75, 25);
runButton.setText("Open Fire!");
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private static int damageFlux(int min, int max) {
if (min >= max) {
throw new IllegalArgumentException("max must be greater than min");
}
Random r = new Random();
return r.nextInt((max - min) + 1) + min;
}
}
T
The error:
Exception in thread "main" java.lang.IllegalArgumentException: max must be greater than min
at main.damageFlux(main.java:144)
at main.access$4(main.java:141)
at main$1.widgetSelected(main.java:120)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:249)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817)
at main.main(main.java:135)
Now, in my head, the min and max should work, but its not. It causes the error to be thrown, most likely because its not doing the math to cause the pair to be different. Here are a couple variables on how it should work:
If attack is 10 and the flux is .20, then max should be (10 * (1 + .20) = 12 and min should be (10 * (1 - .20) = 8. However, if I am getting the error thrown by the damageFlux call, then it means they are matching the same value. by doing a System.out.println on the min and max, they are both returning as 10 instead of 8 and 12.
You should change float flux = stability/100; to float flux = stability/100.0f;.
That way, by having a float in the operation, you promote the division's result to a float. Your actual code makes it so that stability, an int, divided by 100 an other int, results in a rounded answer. Judging by your examples, the result of that is closer to 0 so when that's the case, your next operations with flux become:
int max = (int)(attack * (1 + 0));
int min = (int)(attack * (1 - 0));
Which is why you see 10 in both variables.
For more info, please see: Java implicit conversion
It seems that variable attack is negative. You get it from the UI.
BTW: Add to error message values of min and max. It makes easier debugging
Related
Instructions:
Write a WidgetViewer GUI that has the following widgets:
a button labeled "go up/down"
a label initialized to 0 (we'll call this the left label)
a label initialized to 0 (we'll call this the right label)
a button labeled "go down/up"
When the "go up/down" button is pushed, a random number between 1 and 10 (inclusive)
is generated and added to the left label, and another random number between 1 and 10 (inclusive)
is generated and subtracted from the right label.
When the "go down/up" button is pushed, a random number between 1 and 10 (inclusive) is
generated and subtracted from the left label, and another random number between 1 and 10
(inclusive) is generated and added to the right label.
Error msg:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "Go up/down"
Code:
I cant seem to figure out this error message, it might have a possibility that i am adding a string but im not sure, it may be my logic. But im trying to figure out how i can get the Jbutton called goupdown and godownup to display a random number then add or subtract by 1 if needed.
public class UpAndDown {
public UpAndDown() {
WidgetViewer wv = new WidgetViewer();
JButton goUpDown = new JButton("Go up/down");
JLabel leftLabel = new JLabel("0");
wv.add(goUpDown, 10, 30, 150, 20);
wv.add(leftLabel, 10, 60, 150, 25);
JButton goDownUp = new JButton("Go down/up");
JLabel rightLabel = new JLabel("0");
wv.add(goDownUp, 10, 120, 150, 20);
wv.add(rightLabel, 10, 160, 150, 25);
ButtonIncrement action = new ButtonIncrement(goUpDown);
goUpDown.addActionListener(action);
ButtonIncrement action2 = new ButtonIncrement(goDownUp);
goDownUp.addActionListener(action2);
}
static class ButtonIncrement implements ActionListener {
private final JButton goUpDownBtn;
private final JButton goDownUpBtn;
public ButtonIncrement(JButton buttonToModify) {
goUpDownBtn = buttonToModify;
goDownUpBtn = buttonToModify;
}
#Override
public void actionPerformed(ActionEvent e) {
int rand = (int) (Math.random() * 10);
String val = goUpDownBtn.getText();
//JButton jc = (JButton) e.getSource();
int newVal = Integer.parseInt(val) + rand;
goDownUpBtn.setText(String.valueOf(newVal));
//jc.setText(goDownUpBtn.getText() + " " + val);// get string, convert to int, add rand value. then convert int back to string and set text to string
/*String val2 = goDownUpBtn.getText();
int newVal2 = Integer.parseInt(val2) + rand;
goDownUpBtn.setText(String.valueOf(newVal2));*/
}
}
Write a WidgetViewer GUI that has the following widgets:
a button labeled "go up/down" a label initialized to 0 (we'll call
this the left label) a label initialized to 0 (we'll call this the
right label) a button labeled "go down/up"
When the "go up/down" button is pushed, a random number between 1 and
10 (inclusive) is generated and added to the left label, and another
random number between 1 and 10 (inclusive) is generated and subtracted
from the right label.
When the "go down/up" button is pushed, a random number between 1 and
10 (inclusive) is generated and subtracted from the left label, and
another random number between 1 and 10 (inclusive) is generated and
added to the right label.
So, there's a bunch of important things we need to take away from this.
The values are initially initialised to 0
You need to update a label when a button is triggered
Depending on which button is triggered, will determine which values is added or subtracted to
So, we could simply start with
class IncrementDecrementAction implements ActionListener {
private final JLabel leftLabel;
private final JLabel rightLabel;
private int leftValue = 0;
private int rightValue = 0;
public IncrementDecrementAction(JLabel leftLabel, JLabel rightLabel) {
this.leftLabel = leftLabel;
this.rightLabel = rightLabel;
}
#Override
public void actionPerformed(ActionEvent e) {
int rand = (int) (Math.random() * 10) + 1;
leftValue += rand;
rand = (int) (Math.random() * 10) + 1;
rightValue += rand;
this.leftLabel.setText(Integer.toString(leftValue));
this.rightLabel.setText(Integer.toString(rightValue));
}
}
Okay, but this only solves the problem in one direction, what about down/up?
Well, we could write a second ActionListener which dealt with that, but then you'd need some kind of model to maintain the left and right values so both listeners knew what the current value was. Not an unreasonable idea, but it's an extra two classes to make it work.
Instead, we can take advantage of the ActionEvent's actionCommand support and give each button a specific name, which we can lookup when the action is triggered...
class IncrementDecrementAction implements ActionListener {
private final JLabel leftLabel;
private final JLabel rightLabel;
private int leftValue = 0;
private int rightValue = 0;
public IncrementDecrementAction(JLabel leftLabel, JLabel rightLabel) {
this.leftLabel = leftLabel;
this.rightLabel = rightLabel;
}
#Override
public void actionPerformed(ActionEvent e) {
int leftRandom = (int) (Math.random() * 10) + 1;
int rightRandom = (int) (Math.random() * 10) + 1;
if (e.getActionCommand().equals("upDown")) {
leftValue += leftRandom;
rightValue -= rightRandom;
} else if (e.getActionCommand().equals("downUp")) {
leftValue -= leftRandom;
rightValue += rightRandom;
}
this.leftLabel.setText(Integer.toString(leftValue));
this.rightLabel.setText(Integer.toString(rightValue));
}
}
This basically changes the direction of the calculation based on the source of the event - and it does it without having to now what the source of the event actually was (a button, a menu item, a key binding), it just doesn't care.
You simply set this up by applying the appropriate actionCommand to the appropriate Jbutton, for example...
public class TestPane extends JPanel {
private JLabel leftLabel;
private JLabel rightLabel;
private JButton upDownButton;
private JButton downUpButton;
public TestPane() {
leftLabel = new JLabel("0");
rightLabel = new JLabel("0");
upDownButton = new JButton("Up/down");
downUpButton = new JButton("Down/up");
upDownButton.setActionCommand("upDown");
downUpButton.setActionCommand("downUp");
ActionListener actionListener = new IncrementDecrementAction(leftLabel, rightLabel);
upDownButton.addActionListener(actionListener);
downUpButton.addActionListener(actionListener);
add(leftLabel);
add(rightLabel);
add(upDownButton);
add(downUpButton);
}
}
Now, I went through a dozen or so ideas before getting to this point - my point was to try and keep it as simple as I could without trying to introduce a whole bunch of complexity which might not need to be added - be beware - I don't know what the intention of the exercise is, so I might have gone in the wrong direction from the one your instructor was trying to get you to do
Modified code:
I modified the answer you gave according to the instructions with the WV object to display the GUI and this is the correct version.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class UpAndDown extends JPanel {
private JLabel leftLabel;
private JLabel rightLabel;
private JButton upDownButton;
private JButton downUpButton;
public UpAndDown() {
WidgetViewer wv = new WidgetViewer();
JButton upDownButton = new JButton("Up/down");
wv.add(upDownButton, 10, 30, 150, 20);
JButton downUpButton = new JButton("Down/up");
wv.add(downUpButton, 10, 120, 150, 20);
JLabel leftLabel = new JLabel("0");
wv.add(leftLabel, 10, 60, 150, 25);
JLabel rightLabel = new JLabel("0");
wv.add(rightLabel, 10, 140, 150, 25);
upDownButton.setActionCommand("upDown");
downUpButton.setActionCommand("downUp");
ActionListener actionListener = new IncrementDecrementAction(leftLabel, rightLabel);
upDownButton.addActionListener(actionListener);
downUpButton.addActionListener(actionListener);
}
static class IncrementDecrementAction implements ActionListener {
private final JLabel leftLabel;
private final JLabel rightLabel;
private int leftValue = 0;
private int rightValue = 0;
public IncrementDecrementAction(JLabel leftLabel, JLabel rightLabel) {
this.leftLabel = leftLabel;
this.rightLabel = rightLabel;
}
public void actionPerformed(ActionEvent e) {
int leftRandom = (int) (Math.random() * 10) + 1;
int rightRandom = (int) (Math.random() * 10) + 1;
if (e.getActionCommand().equals("upDown")) {
leftValue += leftRandom;
rightValue -= rightRandom;
} else if (e.getActionCommand().equals("downUp")) {
leftValue -= leftRandom;
rightValue += rightRandom;
}
this.leftLabel.setText(Integer.toString(leftValue));
this.rightLabel.setText(Integer.toString(rightValue));
}
}
}
I'm experimenting with OLSMultipleLinearRegression and I wonder which of my parameters has most impact on the prediction. I do not understand which method in OLSMultipleLinearRegression that will return that information.
static void test() {
double y[] = {110, 120, 135, 140};
double data[][] = {
{9, 100},
{21, 260},
{29, 490},
{41, 650}
};
OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
regression.newSampleData(y, data);
double[] beta = regression.estimateRegressionParameters();
for(int i = 0;i<beta.length;i++) {
System.out.printf("b%d = %.3f\n",i, beta[i]);
}
int ROW = 3;
double value = y[ROW];
double predict = beta[0] + beta[1] * data[ROW][0] + beta[2] * data[ROW][1];
System.out.printf("y=%.3f + %.3f * %.3f + %.3f * %.3f\n", beta[0],beta[1],data[ROW][0],beta[2],data[ROW][1]);
System.out.printf("predict=%.3f value=%.3f\n", predict, value );
}
I am wondering how I can change my objects individually when giving them a name (setName) seen below.
Code:
//textfield & labels
String[] arrLabelsKlanten = new String[] {"KlantID", "Gebruikersnaam", "Wachtwoord", "Voornaam", "Achternaam", "Straat", "Huisnummer", "Gemeente", "Email", "Telefoonnr"};
for (int i = 0; i < arrLabelsKlanten.length; i++)
{
if(i < 5)
{
lblLabelsKlanten = new ClassLabels.lblIngelogdAls(arrLabelsKlanten[i] + ":", 350, 510 + i * 50, 300, 50);
lblLabelsKlanten.setName(String.valueOf(i));
add(lblLabelsKlanten);
txtTextvakken = new ClassTextfields.txtAdmin(500, 515 + i * 50, 300, 30);
txtTextvakken.setName(String.valueOf(i));
add(txtTextvakken);
}else if (i >= 5)
{
lblLabelsKlanten = new ClassLabels.lblIngelogdAls(arrLabelsKlanten[i] + ":", 910, 260 + i * 50, 300, 50);
lblLabelsKlanten.setName(String.valueOf(i));
add(lblLabelsKlanten);
txtTextvakken = new ClassTextfields.txtAdmin(1050, 265 + i * 50, 300, 30);
txtTextvakken.setName(String.valueOf(i));
add(txtTextvakken);
}
}
}
Your strings are stored in an array named lblLabelKlanten, the valueOf(i) is your iterator, not the array.
lblLabelKlanten.setName(arrLabalKlanten[i]); should get you the String inside your array, and set the name of your object to the string value.
at least I think that is the question you are asking?
I'm a java novice, and by far my weakest point in java is using graphics. I'm trying to make a retirement calculator that allows a user to input several pieces of data into an application through JTextFields and then press a button to calculate an account balance at each year (i.e. create an array of the balances at the end of each year). However, I want to display this information using a bar graph representing these balances, so the bar graph must draw its rectangles using the numbers in the array. However, since paintComponent is called at the beginning of the program and the values of the array aren't initialized until the press of the JButton, I can't have the paintComponent method refer to those values, otherwise I get a nullPointerException upon running and things don't render properly. Here's my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JPanel
{
static double start;
static double age;
static double retirement;
static double apr;
static double inflation;
static double daily;
static double life;
static double income;
static int yearsToRetirement = (int)(retirement - age);
static int yearsPostRetirement = (int)(life - retirement);
static double real = (1.0 + (apr / 100.0))/(1.0 + (inflation/100.0)) - 1.0;
static double[] balance;
static double[] yearEndBalance;
static double[] balance2;
public Calculator()
{
setLayout(new BorderLayout());
JPanel subpanel = new JPanel();
add(subpanel, BorderLayout.LINE_END);
subpanel.setBackground(Color.GRAY);
subpanel.setLayout(new GridLayout(9, 1));
// Daily savings
JPanel pnlDailySavings = new JPanel();
JLabel lblDailySavings = new JLabel("Daily savings amount:");
final JTextField txtDailySavings = new JTextField(10);
pnlDailySavings.add(lblDailySavings);
pnlDailySavings.add(txtDailySavings);
subpanel.add(pnlDailySavings);
// Age
JPanel pnlAge = new JPanel();
JLabel lblAge = new JLabel(" Current age:");
final JTextField txtAge = new JTextField(10);
pnlAge.add(lblAge);
pnlAge.add(txtAge);
subpanel.add(pnlAge);
// Starting amount of savings
JPanel pnlStart = new JPanel();
JLabel lblStart = new JLabel("Starting amount of savings:");
final JTextField txtStart = new JTextField(10);
pnlStart.add(lblStart);
pnlStart.add(txtStart);
subpanel.add(pnlStart);
// Age of retirement
JPanel pnlRetirement = new JPanel();
JLabel lblRetirement = new JLabel("Expected age of retirement:");
final JTextField txtRetirement = new JTextField(10);
pnlRetirement.add(lblRetirement);
pnlRetirement.add(txtRetirement);
subpanel.add(pnlRetirement);
// Annual retirement income
JPanel pnlIncome = new JPanel();
JLabel lblIncome = new JLabel("Annual retirement income:");
final JTextField txtIncome = new JTextField(10);
pnlIncome.add(lblIncome);
pnlIncome.add(txtIncome);
subpanel.add(pnlIncome);
// Life expectancy
JPanel pnlLife = new JPanel();
JLabel lblLife = new JLabel("Life expectancy:");
final JTextField txtLife = new JTextField(10);
pnlLife.add(lblLife);
pnlLife.add(txtLife);
subpanel.add(pnlLife);
// Estimated rate of return on savings
JPanel pnlReturn = new JPanel();
JLabel lblReturn = new JLabel("Estimated rate of return on savings:");
final JTextField txtReturn = new JTextField(10);
pnlReturn.add(lblReturn);
pnlReturn.add(txtReturn);
subpanel.add(pnlReturn);
// Estimated rate of inflation
JPanel pnlInflation = new JPanel();
JLabel lblInflation = new JLabel("Estimated rate of inflation:");
final JTextField txtInflation = new JTextField(10);
pnlInflation.add(lblInflation);
pnlInflation.add(txtInflation);
subpanel.add(pnlInflation);
JButton btnCalculate = new JButton("Calculate your retirement savings");
btnCalculate.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
daily = Double.parseDouble(txtDailySavings.getText());
age = Double.parseDouble(txtAge.getText());
start = Double.parseDouble(txtStart.getText());
retirement = Double.parseDouble(txtRetirement.getText());
income = Double.parseDouble(txtIncome.getText());
life = Double.parseDouble(txtLife.getText());
apr = Double.parseDouble(txtReturn.getText());
inflation = Double.parseDouble(txtInflation.getText());
System.out.printf("%f%n%f%n%f%n%f%n%f%n%f%n%f%n%f%n", daily, age, start, retirement, income, life, apr, inflation);
balance = new double[365 * yearsToRetirement];
yearEndBalance = new double[yearsToRetirement];
balance2 = new double[yearsPostRetirement];
double total = start;
for (int i = 0; i < balance.length; i++)
{
total = total * (1 + real/365.0) + daily;
balance[i] = total;
}
for (int i = 0; i < balance2.length; i++)
{
total = total * Math.pow((1 + real/365.0), 365) - income;
balance2[i] = total;
}
for (int i = 0; i < yearEndBalance.length; i++)
{
yearEndBalance[i] = balance[365 * i];
}
printArray(yearEndBalance);
printArray(balance2);
printArray(balance);
repaint();
}
});
subpanel.add(btnCalculate);
}
public static void printArray(double[] array)
{
for (int i = 0; i < array.length; i++)
{
System.out.println(array[i]);
}
}
public void paintComponent(Graphics g)
{
int width = this.getWidth();
int height = this.getHeight();
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine((int)(width - 0.9 * width), (int)(height - 0.1 * height), (int)(width - 0.1 * width), (int)(height - 0.1 * height));
for (int i = 0; i < balance2.length; i++)
{
g.fillRect(((int)(width - 0.9 * width) + 5 * i), ((int)(height - 0.1 * height) - 5 * i), 5, 5 * i);
}
}
}
This code is obviously a work in progress, but right now my biggest hurdle is facilitating the communication between the arrays created upon JButton and creation of a bar graph. Can anyone help?
Five things...
Only paint the graph if the balance2 is not null and is not empty (length > 0)
Consider using paintComponent over paint, see Performing Custom Painting for more details.
Also call super.paint (or super.paintComponent if you've overridden paintComponent) to preserve the paint chain. See Painting in AWT and Swing for more details (nb: You are calling super.paintComponent from within paint, this is bad idea and could affect updates to the GUI)
Paint your graph to a separate, dedicated component, otherwise you will be painting underneath the other components
Call repaint on the bar component when you want to repaint it's content
For example..
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = this.getWidth();
int height = this.getHeight();
if (balance2 != null && balance2.length > 0) {
g.setColor(Color.BLACK);
g.drawLine((int)(width - 0.9 * width), (int)(height - 0.1 * height), (int)(width - 0.1 * width), (int)(height - 0.1 * height));
for (int i = 0; i < balance2.length; i++)
{
g.fillRect(((int)(width - 0.9 * width) + 5 * i), ((int)(height - 0.1 * height) - 5 * i), 5, 5 * i);
}
}
}
I'm having a difficult time understanding where and when to repaint() in my Craps game. I understand that after every instance of an event, like when Start Game or Roll Dice is selected, I need to put repaint(). However when I change the string output from "" to "You've Won!!" in each case and then reprint, the app does not recognize it. I have scanned the site for possible remedies, but cannot find anything like what I'm trying to do, as I'm using .gif's for the dice images and am writing an applet, thus I cannot just sysout in a main method. Any and all criticism is of course welcome, I can handle the heat..
What I have so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.*;
import java.util.Random;
public class Craps extends JApplet implements ActionListener {
Random gen = new Random();
// constant variables for game status
final int WON = 0, loss = 1, CONTINUE = 2;
// other variables used
boolean firstRoll = true; // true if first roll of dice
int diceSum = 1; // sum of the dice
int aPoint = 1; // point if no win/loss on first roll
int stillGame = CONTINUE; // game not over yet
int dice1 = gen.nextInt(6) + 1;
int dice2 = gen.nextInt(6) + 1;
int diceSec, dice2Sec;
int Horizon = gen.nextInt(260) + 25;
int secHorizon = gen.nextInt(260) + 25;
int Vertical = gen.nextInt(150) + 40;
int SecVerto = gen.nextInt(150) + 40;
Image[] dice = new Image[6];
int Low = 35, High = 335;
int Up = 50, Down = 250;
int wins = 0;
String s1 = "";
// GUI
JButton rollButton, startButton;
public void init() {
Button rollButton = new Button("Roll Dice");
Button startButton = new Button("Start Game");
setSize(400, 400);
setLayout(null);
for (int i = 0; i < 6; i++) {
dice[i] = getImage(getCodeBase(), "dice" + (i + 1) + ".gif");
}
// create button to start the game
startButton.setBounds(40, 300, 100, 20);
add(startButton);
startButton.addActionListener(this);
startButton.setEnabled(true);
// create button to roll dice
rollButton.setBounds(230, 300, 100, 20);
add(rollButton);
rollButton.addActionListener(this);
rollButton.setEnabled(true);
} // end of init
public void paint(Graphics g) {
super.paint(g);
// draw craps table
g.setColor(Color.red);
g.fillRect(1, 1, 400, 400);
// draw playing field
g.setColor(Color.green);
g.fillRoundRect(25, 40, 310, 210, 75, 75);
// paint the images of the dice
g.drawImage(dice[dice1 - 1], Horizon, Vertical, 32, 32, this);
g.drawImage(dice[dice2 - 1], secHorizon, SecVerto, 32, 32, this);
g.setColor(Color.black);
g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 22));
g.drawString(s1, 33, 280);
}
public void actionPerformed(ActionEvent e) {
// first roll of dice
Horizon = gen.nextInt(260) + 25;
secHorizon = gen.nextInt(260) + 25;
Vertical = gen.nextInt(150) + 40;
SecVerto = gen.nextInt(150) + 40;
if (e.getSource() == rollButton) {
// while (stillGame == CONTINUE) {
if (firstRoll) {
diceSum = diceRoller(); // roll dice
// repaint();
switch (diceSum) {
// user victory on first roll
case 7:
case 11:
stillGame = WON;
s1 = "You Win";
wins++;
break;
// user loss on first roll
case 2:
case 3:
case 12:
stillGame = loss;
s1 = "You Lose";
break;
default:
stillGame = CONTINUE;
aPoint = diceSum;
firstRoll = false;
s1 = "The Point is " + aPoint + "";
break;
} // end switch
// end if (firstRoll) statement
repaint();
}
else {
diceSum = diceRoller(); // roll dice
// determine game status
if (diceSum == aPoint) // win by making point
s1 = "You Win!!";
else if (diceSum == 7) // lose by rolling seven
s1 = "Suck It";
}
// end while loop
} // end if structure body
// subsequent roll of dice
else {
diceSum = diceRoller(); // roll dice
// determine game status
if (diceSum == aPoint) { // win by making point
s1 = "You Win!!";
stillGame = WON;
} else if (diceSum == 7) { // lose by rolling seven
s1 = "You've Lost";
stillGame = loss;
}
}// end else structure
if (e.getSource() == startButton) {
s1 = "";
}
repaint();
}
// roll dice, calculate sum and display results
public int diceRoller() {
int sum;
dice1 = gen.nextInt(6) + 1; // pick random dice values
dice2 = gen.nextInt(6) + 1;
sum = dice1 + dice2; // sum die values
return sum; // return the sum of dice
} // end method rollDice
} // end
Seems your problem in next: in init() method you declare local variables:
Button rollButton = new Button("Roll Dice");
Button startButton = new Button("Start Game");
and add ActionListener to them, but in your actionPerformed(ActionEvent e) method you compare source with null :
e.getSource() == rollButton
e.getSource() == startButton
here : rollButton == null and startButton == null, because of that, your if statement never execute, only else statement.
Declare your buttons in init() method like next:
rollButton = new JButton("Roll Dice");
startButton = new JButton("Start Game");
I think it helps you.
Also read about variables in java.