I'm making an app, with multiple classes, and in one class i have some code to assign a random number from 1 - 6 to a variable. In another class i have a JLabel showing this variable. And in another class i have a JButton, with a ActionListener, within this is an IF Statement, with the variable with the random number in.
The variable is in Class1.
package Dice;
public class DiceRoll {
public int DICEONE;
public int DICETWO;
private int max = 6;
private int min = 1;
public void DiceRollMethod() {
DICEONE = (int) (Math.floor(Math.random() * (max - min + 1)) + min);
DICETWO = (int) (Math.floor(Math.random() * (max - min + 1)) + min);
System.out.println(DICEONE);
System.out.println(DICETWO);
}
}
The variable is 'DICEONE'
The JLabel is in Class2 (which rolls the dice).
package Dice;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class DiceButton extends JPanel{
private static final long serialVersionUID = 1L;
DiceRoll roll = new DiceRoll();
JButton btnRoll;
public JLabel DB1, DB2;
public DiceButton() {
DB1 = new JLabel("Dice 1: " + roll.DICEONE);
DB2 = new JLabel("Dice 2: " + roll.DICETWO);
DB1.setVisible(true);
DB2.setVisible(true);
btnRoll = new JButton("Roll Dice");
btnRoll.setVisible(true);
btnRoll.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
roll.DiceRollMethod();
DB1.setText("Dice 1: " + roll.DICEONE);
DB2.setText("Dice 2: " + roll.DICETWO);
}
});
add(DB1);
add(DB2);
add(btnRoll);
}
}
When the button is clicked, the random number is assigned to the variable and then displayed.
Finally the variable is used in the ActionListener in Class3 (this is the bit i have a problem with).
package Tiles;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
import Dice.DiceButton;
import Dice.DiceRoll;
public class SpaceOne extends JPanel{
private static final long serialVersionUID = 1L;
DiceRoll roll = new DiceRoll();
DiceButton dButton = new DiceButton();
JButton btn1;
JLabel lbl1;
Font lblFont = new Font("Helvetica", Font.BOLD, 90);
Border lblBorder = BorderFactory.createLineBorder(Color.BLACK, 3);
public SpaceOne() {
setSize(50,100);
setLayout(new GridLayout(1,2));
lbl1 = new JLabel("1");
lbl1.setVisible(true);
lbl1.setFont(lblFont);
lbl1.setBorder(lblBorder);
lbl1.setLocation(1, 1);
btn1 = new JButton("1");
btn1.setVisible(true);
btn1.setLocation(1, 2);
btn1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(roll.DICEONE == 1) {
lbl1.setText(".");
System.out.println("DICEONE");
}else if(roll.DICETWO == 1) {
lbl1.setText(".");
System.out.println("DICETWO");
}
}
});
add(btn1);
add(lbl1);
}
}
The idea is that when the button is clicked, it will check if the variable is equal to a number, and if it is, to change the JLabel text.
But when I click the button nothing changes. The button to roll the dice works fine.
Related
I am trying to make a multiplication table made of buttons with the math fact on them that changes to the product when pressed, then returned to the fact when pressed again. Got the first part but can't figure out how to get it to return to the original button setting. I have my program constructed in 2 classes. First makes the buttons and populates them with original facts. Used nested loop to write the text (math facts) on the buttons.
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class Grid {
public static void main(String args[]){
JFrame frame = new JFrame("Grid Layout");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setResizable(false);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout (9, 9, 5, 5));
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
int i, j;
for (i = 1; i<=9; i++){
for (j = 1; j <= 9; j++){
FactButton button =new FactButton();
button.setText(i + " x " + j);
panel.add(button);
}
}
frame.add(panel);
}
}
Second class defines what buttons do when pressed. I made two cases. The first is the default, second changes the button to present product. This works fine when pressed the first time. When button is pressed a second time I get error messages and nothing changes. Can I change my first case to integers based on
the button's location on the panel (column, row)? How do I do this? Other suggestions?
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.event.ActionEvent;
public class FactButton extends JButton implements ActionListener{
private static final long serialVersionUID = 1L;
public FactButton() {
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
String prob = this.getText();
String left = prob.substring(0, prob.indexOf(" "));
String right = prob.substring(prob.indexOf(" ")+3, prob.length() );
int i = Integer.parseInt(left);
int j = Integer.parseInt(right);
int v=0;
v++;
v%=2;
switch(v){
case 0:
this.setText(null);
break;
case 1:
this.setText(i*j+"");
this.setBackground(Color.WHITE);
this.setContentAreaFilled(false);
this.setOpaque(true);
break;
}
}
}
It switches to the product on first press. Breaks on second. Thought it would go back to a blank button. How can I get it to show the original math fact?
Keep the numbers inside FactButton as members. Then you can use them whenever you want. In the current situation you are parsing numbers from the button text. But after first click text of the button is changing. So you are losing the numbers which set during instantiation.
Change your FactButton with this:
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.event.ActionEvent;
public class FactButton extends JButton implements ActionListener {
private final static int PRODUCT_STATE = 0;
private final static int FACT_STATE = 1;
private int buttonState = FACT_STATE;
private int firstNumber;
private int secondNumber;
public FactButton(int firstNumber, int secondNumber) {
this.firstNumber = firstNumber;
this.secondNumber = secondNumber;
this.setText(firstNumber + " x " + secondNumber);
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
switch (buttonState) {
case PRODUCT_STATE:
this.setText(firstNumber + " x " + secondNumber);
this.setBackground(null);
this.setContentAreaFilled(true);
buttonState = FACT_STATE;
break;
case FACT_STATE:
this.setText(firstNumber * secondNumber + "");
this.setBackground(Color.WHITE);
this.setContentAreaFilled(false);
this.setOpaque(true);
buttonState = PRODUCT_STATE;
break;
}
}
}
And do not set button's text after instantiation. Do it like this:
FactButton button =new FactButton(i, j);
//not needed
//button.setText(i + " x " + j);
panel.add(button);
Answer is here :)
First of all, your thing with the switch is very messy, so i corrected it using regex: it checks if the text is only a number or something else, so if its on the form "64" or "8 x 8" by example
In your case, i won't be using column and row. Imagine you suddenly added a row or something... You should use HashMap, by setting the default value of every button in it, like this:
Grid.java :
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Grid {
static HashMap<JButton, String> map = new HashMap<JButton, String>();
public static void main(String args[]){
JFrame frame = new JFrame("Grid Layout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 800);
frame.setResizable(false);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout (9, 9, 5, 5));
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
int i, j;
for (i = 1; i<=9; i++){
for (j = 1; j <= 9; j++){
FactButton button =new FactButton();
String txt = i + " x " + j;
button.setText(txt);
map.put(button, txt);
panel.add(button);
}
}
frame.add(panel);
frame.setVisible(true);
}
public static String getOriginalFromButton(JButton button){
return map.get(button);
}
}
FactButton.java:
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.event.ActionEvent;
public class FactButton extends JButton implements ActionListener{
private static final long serialVersionUID = 1L;
public FactButton() {
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
String prob = this.getText();
int i = 0,j = 0;
if(!prob.matches("-?\\d+")){//it was on the "x*y" form
String left = prob.substring(0, prob.indexOf(" "));
String right = prob.substring(prob.indexOf(" ")+3, prob.length());
i = Integer.parseInt(left);
j = Integer.parseInt(right);
this.setText(i*j+"");
this.setBackground(Color.WHITE);
this.setContentAreaFilled(false);
this.setOpaque(true);
} else {//so it was on the form of a number
this.setText(Grid.getOriginalFromButton(this));
//any other changes like color
}
}
}
Hope it helped :)
I think the error message is occuring because of this line;
String right = prob.substring(prob.indexOf(" ")+3, prob.length() );
If the result is shown, let's say it's 42, prob.indexOf(" ") returns -1, therefore it's equivalent to prob.substring(2, 2); Since 42 is only 2 characters long, you can't reach it's 2nd index, which would be the 3rd letter. Also, I don't think that
int v=0;
v++;
v%=2;
is doing much. v always be 1
The simplest solution to your problem would be to just parse the original text to the FactButton constructor. You might also want to use a JToggleButton instead of a JButton to let it show it's state.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JFrame;
public class Grid {
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Grid Layout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setResizable(false);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(9, 9, 5, 5));
int i, j;
for (i = 1; i <= 9; i++) {
for (j = 1; j <= 9; j++) {
FactButton button = new FactButton(i + " x " + j);
panel.add(button);
}
}
frame.add(panel);
frame.setVisible(true);
}
});
}
}
class FactButton extends JToggleButton {
private static final long serialVersionUID = 1L;
String orgText;
public FactButton(String orgText) {
this.orgText = orgText;
setText(orgText);
addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent evt) {
if (evt.getStateChange() == ItemEvent.SELECTED) {
String prob = getText();
String left = prob.substring(0, prob.indexOf(" "));
String right = prob.substring(prob.indexOf(" ") + 3, prob.length());
int i = Integer.parseInt(left);
int j = Integer.parseInt(right);
setText(i * j + "");
} else if (evt.getStateChange() == ItemEvent.DESELECTED) {
setText(orgText);
}
}
});
}
}
I'd like to create a Java Swing Photo Album but I can't manage to find the right way to do it. I think it should be to create two ArrayList, one to stock the photo objects and another one to stock the buttons.
After that I should find a way to assign each images to the buttons and add them into the panel.
My question is : Do you think it is the right way to do it and if so, could you give me a hint? (For the last class at the bottom)
Here's my code at the moment :
Main :
import javax.swing.JFrame;
public class Main extends JFrame {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new AlbumFrame();
}
});
}
}
AlbumFrame :
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AlbumFrame extends JFrame {
private JPanel MenuPanel;
private JPanel PhotoPanel;
public AlbumFrame(){
super("JPhone");
setLayout(new BorderLayout());
PhotoPanel = new PhotoPanel();
add(PhotoPanel,BorderLayout.CENTER);
MenuPanel = new MenuPanel();
add(MenuPanel,BorderLayout.SOUTH);
setSize(480,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
MenuPanel
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MenuPanel extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private JButton backButton;
private JButton homeButton;
private JButton turnButton;
private JButton addButton;
final private JFileChooser fc;
public MenuPanel(){
fc = new JFileChooser();
backButton = new JButton(new ImageIcon(getClass().getResource("/Images/back.png")));
homeButton = new JButton(new ImageIcon(getClass().getResource("/Images/home.png")));
turnButton = new JButton(new ImageIcon(getClass().getResource("/Images/turn.png")));
addButton = new JButton(new ImageIcon(getClass().getResource("/Images/add.png")));
backButton.setPreferredSize(new Dimension(55,55));
homeButton.setPreferredSize(new Dimension(55,55));
turnButton.setPreferredSize(new Dimension(55,55));
addButton.setPreferredSize(new Dimension(55,55));
backButton.addActionListener(this);
homeButton.addActionListener(this);
turnButton.addActionListener(this);
addButton.addActionListener(this);
setLayout(new FlowLayout(FlowLayout.CENTER));
add(backButton);
add(homeButton);
add(turnButton);
add(addButton);
}
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton)e.getSource();
//Test for the moment
if(clicked == backButton){
System.out.println("back");
}else if(clicked == homeButton){
System.out.println("home");
}else if(clicked == turnButton){
System.out.println("turn");
}else if(clicked == addButton){
int returnVal = fc.showOpenDialog(MenuPanel.this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
}
}
}
}
PhotoPanel
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PhotoPanel extends JPanel implements ActionListener {
ArrayList<Photo> Album = new ArrayList<Photo>();
ArrayList<JButton> Buttons = new ArrayList<JButton>();
public PhotoPanel(){
setLayout(new FlowLayout(FlowLayout.CENTER));
}
public void actionPerformed(ActionEvent e) {
}
}
I would use separate class like PhotoCard to avoid lists:
class PhotoCard {
public PhotoCard(Photo photo) {
add(photo);
// also add buttons, listeners, etc.
}
}
that holds necessary data and initializes listeners.
And then class can be added to to your PhotoPanel:
PhotoPanel.add(new PhotoCard(...));
So I am trying to make a Fahrenheit to Celsius (or vice versa) conversion program. So it sort of works but I have a drop down menu which I take the value from to check which conversion equation I need. My program isn't quiet finished I only have one equation but It doesn't go back to normal once I've pressed convert. Does anyone know how I can refresh so it goes back to the first option?
package tools;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JButton;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
public class TempConvert extends JFrame {
private JTextField Value;
private JComboBox Options;
private JLabel FVal;
private JButton Convert;
private static String[] OptionsList = {"","Celsius", "Farinheit"};
String TempVal;
int GetVal;
double C2F;
float F2C;
int GetUnit;
public TempConvert(){
super("Tempurature Converter");
setLayout(new FlowLayout());
FVal = new JLabel();
Convert = new JButton();
Options = new JComboBox(OptionsList);
Value = new JTextField("Insert Temperature here:");
Value.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
TempVal = Value.getText();
GetVal = Integer.parseInt(TempVal);
}
}
);
Options.addItemListener(
new ItemListener(){
public void itemStateChanged(ItemEvent event){
if (event.getStateChange()==ItemEvent.SELECTED)
System.out.print(Options.getSelectedIndex());
GetUnit = Options.getSelectedIndex();
}
}
);
Convert.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (GetUnit==1){
double Calc= (GetVal * 1.8);
C2F = (Calc+32);
System.out.println(C2F);
FVal.setText(C2F + " Fahrenheit");
Convert.revalidate();
Convert.repaint();
}
}
}
);
add(Options);
add(Value);
add (Convert);
add(FVal);
}
}
So I am trying to pass a variable from a button press in one class to another class, and can't quite figure it out. The button press creates a random number to simulate a dice roll, adds it to a variable which then is suppose to be passed to the board class which has the game board built on it and will then use said variable to determine which space on the board the player is on. Thank you in advance.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.util.Random;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
public class Game extends JPanel{
private JLabel lblP1Name, lblP2Name, lblRules, lblDiceRoll;
private JTextField txtP1Name, txtP2Name;
private JButton diceRoll;
private JRadioButton rdP1, rdP2;
private int dice;
private static int countP1;
private int countP2;
private JPanel panelNorth;
private void groupButton( ) {
ButtonGroup bg1 = new ButtonGroup( );
bg1.add(rdP1);
bg1.add(rdP2);
}
public Game() throws FileNotFoundException {
setLayout (new BorderLayout());
rdP1 = new JRadioButton("Player 1");
rdP2 = new JRadioButton("Player 2");
ButtonListener listener = new ButtonListener();
Player1 player1 = new Player1(countP1);
Player2 player2 = new Player2(countP2);
Board board = new Board();
Rules rules = new Rules();
JButton diceRoll = new JButton("Roll the dice!");
panelNorth = new JPanel();
panelNorth.setLayout(new GridLayout(1,3));
lblRules = new JLabel(rules.toString());
add(panelNorth, BorderLayout.NORTH);
panelNorth.add(rdP1);
panelNorth.add(diceRoll);
panelNorth.add(rdP2);
Card card = new Card();
add(player1, BorderLayout.WEST);
add(player2, BorderLayout.EAST);
add(lblRules, BorderLayout.SOUTH);
add(board, BorderLayout.CENTER);
diceRoll.addActionListener(listener);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent diceRoll){
Random random = new Random();
dice = random.nextInt(6)+1;
if(rdP1.isSelected()){
countP1 = countP1+dice;
if(countP1>48){
countP1=countP1-48;
}
}else if(rdP2.isSelected()){
countP2 = countP2+dice;
if(countP2>48){
countP2=countP2-48;
}
}
}
}
}
It's simple; just use references.
Instance your classes and pass the reference:
Board board = new Board();
YourClass yourClass = new YourClass(board);
This way you can set Board attributes from the class YourClass.
It's really easy, you could have learned how to do this just by reading basic Java books.
trying to solve a problem and i cant get why it wont work. I'm sorry if I confuse you with my norwegian comments and variables.
First, here is my form.java file.
import java.awt.FlowLayout;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
public class Form implements ActionListener {
String[] ansatt_type = {"Sjef","Mellomleder","Assistent"};
String totlønn;
// KOMPONENTER FOR GUI START
JList ansatte;
DefaultListModel model;
JLabel label1 = new JLabel ();
JComboBox ansatt_id = new JComboBox (ansatt_type);
JButton add_me = new JButton ();
JLabel lønn = new JLabel ();
// KOMPONENTER FOR GUI SLUTT
public Form () {
// LAGER RAMME START
JFrame ramme = new JFrame ();
ramme.setBounds(0,0,275,400);
ramme.setTitle("Ansatt kontroll");
ramme.setLayout(new FlowLayout ());
ramme.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// LEGGER TIL TEXT LABEL1
label1.setText("Liste over ansatte: ");
ramme.add(label1);
// LEGGER TIL DEFAULTLISTMODEL
model = new DefaultListModel();
ansatte = new JList(model);
ansatte.setBounds(0, 0, 200, 200);
model.addElement("KU");
ramme.add(ansatte);
// LEGGER TIL DROPDWON LIST;
ramme.add(ansatt_id);
// LEGGER TIL ANSATT KNAPP
add_me.setText("Legg til ny ansatt");
ramme.add(add_me);
add_me.addActionListener(this);
// LEGGER TIL SAMLEDE LØNNSKOSTNADER
totlønn = "Totale lønnskostnader er : eksempeltall";
lønn.setText(totlønn);
ramme.add(lønn);
ramme.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, "Du har valgt:
"+ansatt_id.getSelectedItem()+"!" +
" Du blir nå videreført og kan legge til en ny ansatt");
if(ansatt_id.getSelectedItem() == "Sjef"){
System.out.println("Valgt Sjef");
Sjef sj = new Sjef ();
model.addElement(sj);
}
if(ansatt_id.getSelectedItem() == "Mellomleder"){
System.out.println("Valgt Mellomleder");
}
if(ansatt_id.getSelectedItem() == "Assistent"){
System.out.println("Valgt Assistent");
}
}
}
I also have a class file called Ansatt.java who several class fiels extends from. I'l show you one.
First my Ansatt.java file ;
import javax.swing.JOptionPane;
public class Ansatt extends Form {
public String Navn;
public int Lønn;
public String Type;
public Ansatt () {
Navn = JOptionPane.showInputDialog(null, "Skriv inn navn på ny ansatt: ");
System.out.println("Ansatt lag til i liste");
}
public String toString(){
return Navn + " " + Type;
}
}
And the extended class Sjef.java
public class Sjef extends Ansatt {
public Sjef () {
super();
this.Lønn = 40000;
this.Type = "Sjef";
}
}
Everything works, except the ModelList wont update, I have a working example, who is almost identical but it just doesent work in this one!
Your problem is the String comparison in your ActionListener:
ansatt_id.getSelectedItem() == "Sjef"
will most likely not return true. You should use
"Sjef".equals( ansatt_id.getSelectedItem() )
Same for the other comparisons.