Basically , I'm trying to make a program that makes the Finch follow the object. I have made two classes : NewOption52 and FollowClass. Class NewOption52 contains a method which determines the properties of the GUI. Class FollowClass contains a main method which calls GUI method from class NewOption52 and it also contains several methods which dictates the Finch's behavior alongside with appending text to JTextArea feed.
When I connect the Finch and run the program , a GUI should appear and inside JTextArea should have text which says ""Please Place An Object in front of Finch And Then Tap Finch to Activate!\n". It didn't happen when I run the program.
Class NewOption52 :
import edu.cmu.ri.createlab.terk.robot.finch.Finch;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.*;
public class NewOption52 {
public static NewOption52 Op = new NewOption52();
public static JTextArea feed;
public static JButton halt;
public static JButton exit;
public static JFrame x ;
static protected Finch Grubert = new Finch();
//Method for determining the GUI
static void GUI()
{
final JFrame x = new JFrame("Finch Mission : Follow an Object!") ;
// How the window should be closed
x.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Adding a layout manager
x.setLayout(new FlowLayout());
x.setResizable(false);
x.setLocationRelativeTo(null);
// Adding components ( significantly a JTextArea being a feedback box ) and adding ActionListeners to each button
halt = new JButton("Halt!");
x.add(halt);
halt.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
feed.append("You have halted the program\n");
Grubert.stopWheels();
Grubert.setLED(0, 0, 0);
JOptionPane.showMessageDialog(x,"You have halted the program , click OK to go back and please wait for 3 seconds for Finch to start again");
Grubert.sleep(3000);
x.repaint();
}
});
exit = new JButton("Exit");
x.add(exit);
exit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Grubert.quit();
System.exit(0);
}
});
feed = new JTextArea(30,60);
JScrollPane feedscroll = new JScrollPane(feed);
x.add(feedscroll);
// Arrange components neatly inside the window
x.pack();
// Making the window visible once Window is called
x.setVisible(true);
}
}
Class FollowClass :
import edu.cmu.ri.createlab.terk.robot.finch.Finch;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class FollowClass {
private static Finch Grubert = null;
private static int TapCount = 0;
public static JTextArea feed;
public static JButton halt;
public static JButton exit;
public static JFrame x ;
//public Finch Grubert = new Finch();
public static void main(String[] args)
{
//refers to first method to start program
NewOption52.GUI();
}
public static void Finch()
{
Grubert = new Finch();
ProgramFollow();
}
private static void ProgramFollow() {
// Loop to wait for Finch to be tapped and an obstacle detected in front of the Finch
boolean StartProgram = true;
NewOption52.feed.append("Please Place An Object in front of Finch And Then Tap Finch to Activate!\n");
while (StartProgram)
{
// Conditional statement for same thing as mentioned above
if (Grubert.isTapped()==true && Grubert.isObstacleLeftSide()==true && Grubert.isObstacleRightSide()==true)
{
feed.append("Finch is activated! Object is detected!\n");
Grubert.setLED(red,0,0);
Grubert.setWheelVelocities(leftVelocity, rightVelocity);
// Triggers RunAgain to true so the program doesnt stop in one run in order for Finch to move continuosuly
boolean RunAgain=true;
while(RunAgain)
{
// Calling Movement method for Finch movements
Movement();
// Inside while RunAgain loop , there is the incremental function called TapCount to determine how many times the Finch has been tapped
if (Grubert.isTapped()==true)
{
TapCount++;
feed.append("You have tapped the Finch. If TapCount = 3 , the program will terminate only if the object is not moving\n");
feed.append("Number of Taps:" + TapCount + "\n");
if (TapCount==3 && Grubert.isObstacleLeftSide()==false && Grubert.isObstacleRightSide()==false)
{
Grubert.stopWheels();
Grubert.setLED(0, 0, 0);
TapCount = 1;
JOptionPane.showMessageDialog(x,"You have tapped the Finch twice when the object is moving. Please click OK and wait for 3 seconds. Make sure the object is not moving in order for program to terminate when you have tapped it twice");
Grubert.sleep(3000);
}
if (TapCount==3 && Grubert.isObstacleLeftSide()==true && Grubert.isObstacleRightSide()==true)
{
Grubert.quit();
System.exit(0);
}
}
}
}
}
}
// Method for Finch movements
private static void Movement()
{
if (Grubert.isObstacleLeftSide()==false && Grubert.isObstacleRightSide()==false)
{
// send message to the feedback box ("Object is Detected! Following it now!");
feed.append("Following the Object now!\n");
StraightMovement();
}
else if (Grubert.isObstacleLeftSide()==true && Grubert.isObstacleRightSide()==false)
{
feed.append("Object detected on the left side\n");
LeftMovement();
}
else if (Grubert.isObstacleLeftSide()==false && Grubert.isObstacleRightSide()==true)
{
feed.append("Object detected on the right side\n");
RightMovement();
}
else if (Grubert.isObstacleLeftSide()==true && Grubert.isObstacleRightSide()==true)
{
StopMovement();
}
}
// Area of variables declaration for easy value modifications
static int Buzz = 500;
static int BuzzDuration = 10;
static int red = 255;
static int green = 255;
static int leftVelocity = 100;
static int rightVelocity = 100;
static int leftTurnV = -50;
static int rightTurnV = -50;;
// Area of variables declaration for easy value modifications
private static void StraightMovement()
{
Grubert.setLED(0, green, 0);
Grubert.setWheelVelocities(leftVelocity, rightVelocity);
Grubert.buzz(Buzz, BuzzDuration);
}
private static void LeftMovement()
{
Grubert.setLED(0, green, 0);
Grubert.setWheelVelocities(leftTurnV, rightVelocity);
Grubert.buzz(Buzz, BuzzDuration);
}
private static void RightMovement()
{
Grubert.setLED(0, green, 0);
Grubert.setWheelVelocities(leftVelocity, rightTurnV);
Grubert.buzz(Buzz, BuzzDuration);
}
private static void StopMovement()
{
Grubert.setLED(red, 0 , 0);
Grubert.stopWheels();
}
}
Related
package gameprojekt;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
//The GameWindow class holds the window
public class Game extends JFrame {
/*Global variable declaration*/
private int width;
private int height;
private int windowXPos;
private int windowYPos;
public static String p1 = "Player1";
public static String p2 = "Player2";
public static int playerScore = 0;
public static int oponentScore = 0;
public static int player1X;
public static int Player1Y;
public static int player2X;
public static int Player2Y;
private static boolean running = true;
public static int status = 0;
public static JFrame frame = new JFrame("Pong");
//public TestDrawPanel testPanel = new TestDrawPanel();
public static int getStatus() {
return status;
}
public static void setStatus(int status) {
Game.status = status;
}
// ------------------------------------------------------------
/**
* Creates a new JFrame window with the given size and
* center it based on the screen resolution
*/
public static final long serialVersionUID = 1L;
public Game() {
/*Local variable declaration*/
//JFrame frame = new JFrame("Pong");
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
width = (int)dim.getWidth();
height = (int)dim.getHeight();
windowXPos = width / 2 - (width / 2) / 2;
windowYPos = height / 2 - (height / 2) / 2;
// ------------------------------------------------------------
// Set size, half of the screen resolution
frame.setSize(width/2, height/2);
// Allign the window to the users resolution
frame.setLocation(windowXPos, windowYPos);
frame.setVisible(true);
frame.setResizable(false);
// By exiting the window using "X" all relevant data is closed
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
/* zum Testen auskommentiert
#Override
public void paint(Graphics g) {
System.out.println("test");
this.drawPlayer(g);
}*/
/**
* Draw the Player on the given location and with the given size
* #param g Graphics object
*/
public void drawPlayer(Graphics g) {
}
private static void gameLoop() {
Menue m = new Menue();
m.loadMenue(frame);
while (running) {
if (m.isStartPressed()) {
System.out.println("test");
}
}
}
/**
* Create the game and initialize the gameplay
*/
public static void main(String[] args) {
/*Variable declaration*/
// ------------------------------------------------------------
Game game = new Game();
game.gameLoop();
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package gameprojekt;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
*
*/
public class Menue {
/* Global variable declaration */
private int widthMenue;
private int heightMenue;
private String start = "Start";
private String highscores = "Highscores";
private boolean startPressed = false;
public JButton bStart = new JButton(start);
public JButton bScore = new JButton(highscores);
// ----------------------------------------------------
public boolean isStartPressed() {
return startPressed;
}
public void setStartPressed(boolean startPressed) {
this.startPressed = startPressed;
}
public int getWidthMenue() {
return widthMenue;
}
public void setwidthMenue(int widthMenue) {
this.widthMenue = widthMenue;
}
public int getheightMenue() {
return heightMenue;
}
public void setheightMenue(int heightMenue) {
this.heightMenue = heightMenue;
}
public void loadMenue(JFrame j) {
JPanel menue = new JPanel();
LayoutManager border = new BorderLayout();
menue.setLayout(border);
menue.setBackground(Color.black);
bStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setStartPressed(true);
}
});
menue.add(bStart, BorderLayout.LINE_START);
menue.add(bScore, BorderLayout.LINE_END);
j.getContentPane().add(menue);
}
}
Hi I'm having a problem that the variable startPressed seems to be getting ignored. If the button start is pressed the variable startPressed is set to true but the if statement in this while loop doesn't react to the new value:
while (running) {
if (m.isStartPressed()) {
System.out.println("test");
}
}
If I add System.out.println or Thread.sleep inside the loop then the if statement recognizes the value and is giving me the output.
I thought maybe there is a main problem in the programming structure or Java is too slow. Any ideas?
Thanks!
Your main problem is that your startPressed variable is not made volatile, and thus changing it in one thread may not be reflected in another thread. Change this and you'll see that your start button changes this variable appropriately:
private volatile boolean startPressed = false;
Your game loop shouldn't be as it flies in the face of Swing threading rules. Why not use a Swing Timer (my preference) or if you need your own roll-your own loop, then doing so in a background thread. Also consider making startPressed a "bound" variable, one that when changed tells any property change listeners that its state has been changed. This would be better than constantly polling its value.
Another comment: your code overuses statics and would be much better organized if you got rid of most of your static modifiers.
When you do something like
while(running) {
...
}
it means, that this loop is executed over and over again, nothing stops it, it gets executed as fast as your PC can do it. And therefore, it tends to block everything else. So yes, your program structure is the problem. Try to execute your game-loop in a separate thread. This thread can then update your view from time to time. Maybe think about to pause this thread from time to time or to schedule it in some way, so your view is only update every second (or whatever you want).
I have made a program which makes a GUI called Window() and instructs my Finch robot to follow an object. When I run the program , there is no text added to JTextArea. It should say Please Tap Finch to Activate.
My program tells me that this line is the source of error:
NewOption5.feed.append("Please Tap Finch to Activate!");
Console :
Connecting to Finch...this may take a few seconds...
Exception in thread "main" java.lang.NullPointerException
at NewOption5.ProgramFollow(NewOption5.java:58)
at NewOption5.main(NewOption5.java:12)
Code :
import edu.cmu.ri.createlab.terk.robot.finch.Finch;
import java.awt.*;
import javax.swing.*;
public class NewOption5 {
static JTextArea feed;
static Finch myFinch = new Finch();
public static void main(String[] args) {
//Calling Window
// myFinch = new Finch();
Window();
ProgramFollow();
}
// Method for creating a GUI
//static Finch myFinch = new Finch();
public static void Window()
{
// Create the window
JFrame x = new JFrame("Finch Mission : Follow an Object!");
// How the window should be closed
x.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Adding a layout manager
x.setLayout(new FlowLayout());
// Adding components ( significantly a JTextArea being a feedback box )
x.add(new JButton("Halt!"));
x.add(new JButton("Exit"));
final JTextArea feed = new JTextArea(30,50);
JScrollPane feedscroll = new JScrollPane(feed);
x.add(feedscroll);
// Arrange components neatly inside the window
x.pack();
// Making the window visible once Window is called
x.setVisible(true);
// ProgramFollow();
}
public static void ProgramFollow() {
// Loop to wait for Finch to be tapped and an obstacle detected in front of the Finch
boolean StartProgram;
NewOption5.feed.append("Please Tap Finch to Activate!");
while (StartProgram = true)
{
// Sending message to the feedback box
feed.append("Please Tap Finch to Activate!");
// Conditional statement for same thing as mentioned above
if (myFinch.isTapped()==true && myFinch.isObstacleLeftSide()==true && myFinch.isObstacleRightSide()==true)
{
NewOption5.feed.append("Finch is activated! Object is detected");
myFinch.setLED(red,0,0);
myFinch.setWheelVelocities(leftVelocity, rightVelocity);
// Triggers RunAgain to true so the program doesnt stop in one run in order for Finch to move continuosuly
boolean RunAgain=true;
while(RunAgain)
{
// Calling Movement method for Finch movements
Movement();
// Inside while(RunAgain loop , there is a conditional statment which makes the Finch terminate the program after tapping it twice
if (myFinch.isTapped()==true && myFinch.isTapped()==true)
{
}
}
}
}
}
// Method for Finch movements
public static void Movement()
{
if (myFinch.isObstacleLeftSide()==false && myFinch.isObstacleRightSide()==false)
{
// send message to the feedback box ("Object is Detected! Following it now!");
NewOption5.feed.append("Following the Object now!");
StraightMovement();
}
else if (myFinch.isObstacleLeftSide()==true && myFinch.isObstacleRightSide()==false)
{
NewOption5.feed.append("Object detected on the left side");
LeftMovement();
}
else if (myFinch.isObstacleLeftSide()==false && myFinch.isObstacleRightSide()==true)
{
NewOption5.feed.append("Object detected on the right side");
RightMovement();
}
else if (myFinch.isObstacleLeftSide()==true && myFinch.isObstacleRightSide()==true)
{
NewOption5.feed.append("Stopped now");
StopMovement();
}
}
// Area of variables declaration for easy value modifications
static int Buzz = 340;
static int BuzzDuration = 10;
static int red = 255;
static int green = 255;
static int leftVelocity = 100;
static int rightVelocity = 100;
static int leftTurnV = -50;
static int rightTurnV = -50;;
// Area of variables declaration for easy value modifications
public static void StraightMovement()
{
myFinch.setLED(0, green, 0);
myFinch.setWheelVelocities(leftVelocity, rightVelocity);
myFinch.buzz(Buzz, BuzzDuration);
}
public static void LeftMovement()
{
myFinch.setLED(0, green, 0);
myFinch.setWheelVelocities(leftTurnV, rightVelocity);
myFinch.buzz(Buzz, BuzzDuration);
}
public static void RightMovement()
{
myFinch.setLED(0, green, 0);
myFinch.setWheelVelocities(leftVelocity, rightTurnV);
myFinch.buzz(Buzz, BuzzDuration);
}
public static void StopMovement()
{
myFinch.setLED(red, 0 , 0);
myFinch.stopWheels();
myFinch.buzz(Buzz, BuzzDuration);
}
}
You do not initialize feed correctly.
final JTextArea feed = new JTextArea(30,50);
This does not initialize the field feed but instead creates a new local variable of the same name.
Try turning final JTextArea feed = new JTextArea(30,50); into feed = new JTextArea(30,50);.
I am coding a little game in which i have taken a grid of JButtons in a JFrame and i want to refresh the colors of the buttons contained in a JFrame,which is already visible.As explained below
void foo(){
mainFrame.setVisible(true);//mainFrame is defined at class level.
//color update code for the buttons.
mainFrame.setVisible(true);
}
Result i am getting is not as expected and my screen gets freeze .Isn't it the right way to achieve what i wanted?
EDIT
ok i am explaining it in detail what i want to achieve.i have a class,as:-
import javax.swing.*;
import java.awt.*;
import java.util.*;
class Brick extends JButton{
public void setRandomColors(){
int random = (int) (Math.random()*50);
if(random%13==0){
this.setBackground(Color.MAGENTA);
}
else if(random%10==0){
this.setBackground(Color.red);
}
else if(random%9==0){
this.setBackground(Color.yellow);
}
else if(random%7==0){
this.setBackground(Color.orange);
}
else if(random%2==0){
this.setBackground(Color.cyan);
}
else{
this.setBackground(Color.PINK);
}
}
public void setBlackColor(){
this.setBackground(Color.black);
}
}
class Grid {
JFrame mainGrid = new JFrame();
ArrayList<Brick> bunchOfBricks = new ArrayList<>();
int gridLength = 8;//gridlenth is equals to gridweight as i have considered a Square grid.
int totalBricks = gridLength*gridLength;
public void formBunchOfBricks(){
for(int i=0;i<totalBricks;i++){
bunchOfBricks.add(new Brick());
}
}
public void formColoredGrid(){
Brick aBrick;
mainGrid.setLayout(new GridLayout(8,8));
for(int i=0;i<totalBricks;++i){
aBrick = (bunchOfBricks.get(i));
aBrick.setRandomColors();
mainGrid.add(aBrick);
}
mainGrid.setVisible(true);//its ok upto here iam getting randomly colored Frame of Bricks or so called JButtons.
delay(15);//Sorry for this one,i warn you not to laugh after looking its defination.
}
/*
I want following function to do following things:-
1.it should firstly display the Grid whose all buttons are black Colored.
2.After some time the original colored,first Row of grid formed by formColoredGrid should be displayed and all the rest Rows should be black.
3.Then second row turns colored and all other rows should be black......and so on upto last row of Grid.
*/
public void movingRows(){
setGridBlack();
delay(1);//see in upper method,for this horrible thing.
for(int i=0;i<gridLength;++i){
setGridBlack();
for (int j=0;j<gridLength;++j){
Brick aBrick = bunchOfBricks.get((gridLength*i)+j);
aBrick.setRandomColors();//Bricks are colored Row by Row.
}
delay(5);//already commented this nonsense.
mainGrid.setVisible(true);//using setVisible again,although this frame is already visible,when i called formColoredGrid.
setGridBlack();
}
//oh! disappointing,i have almost broken my arm slamming it on table that why the function result in a screen full of black buttons.
}
public void setGridBlack(){
for(int i=0;i<totalBricks;i++){
bunchOfBricks.get(i).setBlackColor();
}
}
public void delay(int a){
for ( int i=0;i<90000000;++i){
for(int j=0;j<a;++j){
}
}
}
public static void main(String args[]){
Grid g1 = new Grid();
g1.formBunchOfBricks();
g1.formColoredGrid();
g1.movingRows();
}
}
Please Help me what is the way out?
Your problem is in code not shown here:
//color update code for the buttons.
You're likely running a loop that never ends on the Swing event thread, possibly a never-ending while loop that polls the state of something(a guess), freezing your GUI. Solution: don't do this; don't use a continuous polling loop. Instead, change the colors based on responses to events as Swing is event-driven.
For better more specific help, please show the offending code and tell us more about your program.
Edit
If you're trying to show colored rows, one by one marching down the board, then my guess is right, you'll want to use a Swing Timer, one that uses an int index to indicate which row is being displayed in color. You'd increment the index inside of the Timer's ActionPerformed class, and then when all rows have been displayed stop the Timer. For example something like so:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyGrid extends JPanel {
private static final int GRID_LENGTH = 8;
private static final Color BTN_BACKGROUND = Color.BLACK;
private static final Color[] COLORS = { Color.MAGENTA, Color.CYAN,
Color.RED, Color.YELLOW, Color.ORANGE, Color.PINK, Color.BLUE,
Color.GREEN };
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final int TIMER_DELAY = 800;
private JButton[][] buttonGrid = new JButton[GRID_LENGTH][GRID_LENGTH];
private Map<JButton, Color> btnColorMap = new HashMap<>();
private Random random = new Random();
public MyGrid() {
setLayout(new GridLayout(GRID_LENGTH, GRID_LENGTH));
for (int row = 0; row < buttonGrid.length; row++) {
for (int col = 0; col < buttonGrid[row].length; col++) {
JButton btn = new JButton();
btn.setBackground(BTN_BACKGROUND);
// !! add action listener here?
add(btn);
buttonGrid[row][col] = btn;
}
}
new Timer(TIMER_DELAY, new TimerListener()).start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void resetAllBtns() {
for (JButton[] row : buttonGrid) {
for (JButton btn : row) {
btn.setBackground(BTN_BACKGROUND);
}
}
}
private class TimerListener implements ActionListener {
private int row = 0;
#Override
public void actionPerformed(ActionEvent e) {
resetAllBtns(); // make all buttons black
if (row != buttonGrid.length) {
for (int c = 0; c < buttonGrid[row].length; c++) {
int colorIndex = random.nextInt(COLORS.length);
Color randomColor = COLORS[colorIndex];
buttonGrid[row][c].setBackground(randomColor);
// !! not sure if you need this
btnColorMap.put(buttonGrid[row][c], randomColor);
}
row++;
} else {
// else we've run out of rows -- stop the timer
((Timer) e.getSource()).stop();
}
}
}
private static void createAndShowGui() {
MyGrid mainPanel = new MyGrid();
JFrame frame = new JFrame("MyGrid");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Please have a look at the Swing Timer Tutorial as well.
Edit 2
You ask:
but what is the reason of failure of this program,is it the useless delay function?
Your delay method does nothing but busy calculations on the Swing event thread:
public void delay(int a) {
for (int i = 0; i < 90000000; ++i) {
for (int j = 0; j < a; ++j) {
}
}
}
It's little different from a crude attempt at calling Thread.sleep(...), and is crude because you can't explicitly control how long it will run as you can with thread sleep. Again, the problem is that you're making these calls on the Swing event dispatch thread or EDT, the single thread that is responsible for all Swing drawing and user interactions. Blocking this thread will block your program making it non-running or frozen.
I cannot enter two digit number to be calculator. I also cannot get the clear C operator working as well. My dot sign seems to be not working as well. The code below creates a calculator using java swing and does addition, multiplication,subtraction and divisiion of a single digit number.
//First the necessary packages are imported
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**#return a BODMAS calculator using Javax Swing and awt
* *#author Cihan Altunok
*#version 1
*/
//implementing ActionListener to listen to events. JFrame is also extended to add support to Swing components
public class Calculator extends JFrame implements ActionListener {
//declaring some variables to be used in our program
JFrame guiCalculatorFrame;
JPanel buttonPanel;
JTextArea numberCalculator;
int calculatorOpr=0;
int currentCalculation;
//EventQueue invokeLater is used to ensure the run method is called in the dispatch thread of the EventQueue
//declaring the constructor for the class
public Calculator()
{
//instantiating guiCalculatorFrame
guiCalculatorFrame=new JFrame();
//the red cross sign drawn to exit the window
guiCalculatorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiCalculatorFrame.setTitle("Calculator");
//setting the size of the frame
guiCalculatorFrame.setSize(400,400);
//The setLocationRelativeTo has been set to null to center the window
guiCalculatorFrame.setLocationRelativeTo(null);
//JTextField is created to allow a set of characters to be entered
numberCalculator=new JTextArea();
//setting the alignment of JTextField along the RIGHT axis
numberCalculator.setAlignmentX(JTextField.RIGHT);
//making the textfield not editable
numberCalculator.setEditable(false);
//container containing the components in the north region
guiCalculatorFrame.add(numberCalculator, BorderLayout.NORTH);
//panel is created and we will add buttons to the panel later in the program
buttonPanel=new JPanel();
//setting Layout to GridLayout to lay the components in a rectangular grid
buttonPanel.setLayout(new GridLayout(5,5));
//adding the buttons to the frame. Putting the buttons in the center
guiCalculatorFrame.add(buttonPanel,BorderLayout.CENTER);
// a following for loop is done to add the numberButtons
for (int i=0;i<10;i++)
{
addNumberButton(buttonPanel,String.valueOf(i));
}
//next the five mathematical operators are added
addActionButton(buttonPanel,1,"+");
addActionButton(buttonPanel,2,"-");
addActionButton(buttonPanel,3,"*");
addActionButton(buttonPanel,4,"/");
addActionButton(buttonPanel,5,"^2");
addActionButton(buttonPanel,6,"C");
addActionButton(buttonPanel,7,"^");
addActionButton(buttonPanel,8,".");
//equalSign Button is created
JButton equalsSignButton=new JButton("=");
//the action command for the equal sign button is set
equalsSignButton.setActionCommand("=");
equalsSignButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
//checking if the numberCalculator field is a valid mathematical operator
{
if (!numberCalculator.getText().isEmpty())
{
//turning text into integer
int number=Integer.parseInt(numberCalculator.getText());
// doing a series of if statements for the list of operations
if (calculatorOpr==1)
{
int calculate=currentCalculation+number;
numberCalculator.setText(Integer.toString(calculate));
}
else if (calculatorOpr==2)
{
int calculate=currentCalculation-number;
numberCalculator.setText(Integer.toString(calculate));
}
else if (calculatorOpr==3)
{
int calculate=currentCalculation*number;
numberCalculator.setText(Integer.toString(calculate));
}
else if (calculatorOpr==4)
{
int calculate=currentCalculation/number;
numberCalculator.setText(Integer.toString(calculate));
}
else if (calculatorOpr==5)
{
int calculate=currentCalculation*currentCalculation;
numberCalculator.setText(Integer.toString(calculate));
}
else if (calculatorOpr==6)
{
numberCalculator.setText("");
}
else if (calculatorOpr==7)
{
int calculate=(int) Math.sqrt(Integer.parseInt(numberCalculator.getText()));
numberCalculator.setText(Integer.toString(calculate));
}
else if (calculatorOpr==8)
{
numberCalculator.append(".");
}
}
}
});
//adding equals sign to the panel
buttonPanel.add(equalsSignButton);
//setting the visibility to True so the frame can be seen
guiCalculatorFrame.setVisible(true);
}
//passing two paremeters to the addNumberButton method
private void addNumberButton(Container contain, String name) {
JButton buttonOne=new JButton(name);
//setting the action command for the button created above
buttonOne.setActionCommand(name);
buttonOne.addActionListener(this);
//adding buttonOne to the container
contain.add(buttonOne);
}
//passing three parameters to the addActionButton method
private void addActionButton(Container contain, int i, String text) {
JButton buttonOne=new JButton(text);
//setting the action command for the button created above
buttonOne.setActionCommand(text);
//creating a new class
Operators addAction=new Operators(i);
buttonOne.addActionListener(addAction);
//adding buttonOne to the container
contain.add(buttonOne);
}
public void actionPerformed(ActionEvent event) {
//returning the command string associated with this string
String i=event.getActionCommand();
//setting the Text to the specified String
numberCalculator.setText(i);
}
//creating an inner class and implementing ActionListener
private class Operators implements ActionListener
{
private int operators;
//creating a constructor and passing a parameter
public Operators(int operation)
{
operators=operation;
}
public void actionPerformed(ActionEvent event)
{
currentCalculation=Integer.parseInt(numberCalculator.getText());
calculatorOpr=operators;
}
}
}*
The problem was you were overwrting the text field. and the action listener for C button was wrong. This will solve your basic problems, but some work remaining. For instance you are not handling the . at the moment.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Calculator extends JFrame implements ActionListener {
// declaring some variables to be used in our program
JFrame guiCalculatorFrame;
JPanel buttonPanel;
JTextArea numberCalculator;
int calculatorOpr = 0;
int currentCalculation;
boolean isOperatorActive = false;
// EventQueue invokeLater is used to ensure the run method is called in the
// dispatch thread of the EventQueue
// declaring the constructor for the class
public Calculator() {
// instantiating guiCalculatorFrame
guiCalculatorFrame = new JFrame();
// the red cross sign drawn to exit the window
guiCalculatorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiCalculatorFrame.setTitle("Calculator");
// setting the size of the frame
guiCalculatorFrame.setSize(400, 400);
// The setLocationRelativeTo has been set to null to center the window
guiCalculatorFrame.setLocationRelativeTo(null);
// JTextField is created to allow a set of characters to be entered
numberCalculator = new JTextArea();
// setting the alignment of JTextField along the RIGHT axis
numberCalculator.setAlignmentX(JTextField.RIGHT);
// making the textfield not editable
numberCalculator.setEditable(false);
// container containing the components in the north region
guiCalculatorFrame.add(numberCalculator, BorderLayout.NORTH);
// panel is created and we will add buttons to the panel later in the
// program
buttonPanel = new JPanel();
// setting Layout to GridLayout to lay the components in a rectangular
// grid
buttonPanel.setLayout(new GridLayout(5, 5));
// adding the buttons to the frame. Putting the buttons in the center
guiCalculatorFrame.add(buttonPanel, BorderLayout.CENTER);
// a following for loop is done to add the numberButtons
for (int i = 0; i < 10; i++) {
addNumberButton(buttonPanel, String.valueOf(i));
}
// next the five mathematical operators are added
addActionButton(buttonPanel, 1, "+");
addActionButton(buttonPanel, 2, "-");
addActionButton(buttonPanel, 3, "*");
addActionButton(buttonPanel, 4, "/");
addActionButton(buttonPanel, 5, "^2");
addActionButton(buttonPanel, 6, "C");
addActionButton(buttonPanel, 7, "^");
addActionButton(buttonPanel, 8, ".");
// equalSign Button is created
JButton equalsSignButton = new JButton("=");
// the action command for the equal sign button is set
equalsSignButton.setActionCommand("=");
equalsSignButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// checking if the numberCalculator field is a valid mathematical
// operator
isOperatorActive = true;
if (!numberCalculator.getText().isEmpty()) {
// turning text into integer
int number = Integer.parseInt(numberCalculator.getText());
// doing a series of if statements for the list of
// operations
int calculate = 0;
switch (calculatorOpr) {
case 1:
calculate = currentCalculation + number;
numberCalculator.setText(Integer.toString(calculate));
break;
case 2:
calculate = currentCalculation - number;
numberCalculator.setText(Integer.toString(calculate));
break;
case 3:
calculate = currentCalculation * number;
numberCalculator.setText(Integer.toString(calculate));
break;
case 4:
calculate = currentCalculation / number;
numberCalculator.setText(Integer.toString(calculate));
break;
case 5:
calculate = currentCalculation * currentCalculation;
numberCalculator.setText(Integer.toString(calculate));
break;
case 7:
calculate = (int) Math.sqrt(Integer
.parseInt(numberCalculator.getText()));
numberCalculator.setText(Integer.toString(calculate));
break;
case 8:
numberCalculator.append(".");
break;
default:
break;
}
}
}
});
// adding equals sign to the panel
buttonPanel.add(equalsSignButton);
// setting the visibility to True so the frame can be seen
guiCalculatorFrame.setVisible(true);
}
// passing two parameters to the addNumberButton method
private void addNumberButton(Container contain, String name) {
JButton buttonOne = new JButton(name);
// setting the action command for the button created above
buttonOne.setActionCommand(name);
buttonOne.addActionListener(this);
// adding buttonOne to the container
contain.add(buttonOne);
}
// passing three parameters to the addActionButton method
private void addActionButton(Container contain, int i, String text) {
JButton buttonOne = new JButton(text);
// setting the action command for the button created above
buttonOne.setActionCommand(text);
// creating a new class
Operators addAction = new Operators(i);
buttonOne.addActionListener(addAction);
// adding buttonOne to the container
contain.add(buttonOne);
}
public void actionPerformed(ActionEvent event) {
// returning the command string associated with this string
String i = event.getActionCommand();
// setting the Text to the specified String
if(isOperatorActive){
numberCalculator.setText(i);
isOperatorActive = false;
} else {
numberCalculator.setText(numberCalculator.getText() + i);
}
}
// creating an inner class and implementing ActionListener
private class Operators implements ActionListener {
private int operators;
// creating a constructor and passing a parameter
public Operators(int operation) {
operators = operation;
}
public void actionPerformed(ActionEvent event) {
isOperatorActive = true;
switch (operators) {
case 6:
numberCalculator.setText("");
currentCalculation = 0;
calculatorOpr = 0;
break;
case 8:
isOperatorActive = false;
default:
currentCalculation = Integer.parseInt(numberCalculator.getText());
calculatorOpr = operators;
break;
}
}
}
}
import javax.swing.*;
import java.awt.*;
/*
# Author 12CSE54
# Date 29.10.14
*/
public class calculator1 extends JFrame
{
public calculator1() {
initComponents();
}
int a,b,c;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
a=Integer.parseInt(jTextField1.getText());
b=Integer.parseInt(jTextField2.getText());
c=a+b;
jTextField3.setText(String.valueOf(c));
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
a=Integer.parseInt(jTextField1.getText());
b=Integer.parseInt(jTextField2.getText());
c=a-b;
jTextField3.setText(String.valueOf(c));
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
a=Integer.parseInt(jTextField1.getText());
b=Integer.parseInt(jTextField2.getText());
c=a*b;
jTextField3.setText(String.valueOf(c));
}
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
a=Integer.parseInt(jTextField1.getText());
b=Integer.parseInt(jTextField2.getText());
c=a/b;
jTextField3.setText(String.valueOf(c));
}
private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {
jTextField1.setText("");
jTextField2.setText("");
jTextField3.setText("");
}
public static void main(String ar[])
{
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new calculator1().setVisible(true);
}
});
}
I have a problem with the code I am currently trying to run - I am trying to make 3 buttons, put them on a GUI, and then have the first buttons colour be changed to orange, and the buttons next to that colour change to white and green. Every click thereafter will result in the colours moving one button to the right. My code thus far is as follows, it is skipping colours in places and is not behaving at all as I expected. Can anyone offer some help/guidance please ?
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ButtonJava extends JButton implements ActionListener {
private int currentColor=-1;
private int clicks=0;
private static final Color[] COLORS = {
Color.ORANGE,
Color.WHITE,
Color.GREEN };
private static ButtonJava[] buttons;
public ButtonJava( ){
setBackground( Color.YELLOW );
setText( "Pick ME" );
this.addActionListener( this );
}
public static void main(String[] args) {
JFrame frame = new JFrame ("JFrame");
JPanel panel = new JPanel( );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
buttons = new ButtonJava[3];
for(int i = 0;i<buttons.length ; i++){
buttons[i] = new ButtonJava();
panel.add(buttons[i]);
}
frame.getContentPane( ).add( panel );
frame.setSize( 500, 500);
frame.setVisible( true );
}
private void updateButton() {
clicks++;
changeColors();
// setText( );
}
private void changeColors( ) {
for (int i=buttons.length-1;i>=0;i--){
buttons[i].currentColor = nextColor(currentColor);
buttons[i].setBackground(COLORS[buttons[i].currentColor]);
buttons[i].setText(("# of clicks = " + buttons[i].getClicks() ) );
}
}
private Integer getClicks() {
return clicks;
}
private int nextColor( int curCol ) {
final int colLen = COLORS.length;
curCol--;
curCol = (colLen + curCol % colLen) % colLen;
return curCol;
}
private void firstClick( ActionEvent event ) {
int curCol = 0;
for (int i=buttons.length-1;i>=0;i--){
if ( buttons[i] == event.getSource() ) {
buttons[i].currentColor = curCol;
curCol++;
currentColor++;
}
}}
#Override
public void actionPerformed( ActionEvent event ) {
if ( -1 == currentColor ) {
firstClick( event );
}
updateButton( );
}
}
Thank you very much for the help :)
You have a couple issues with the code you posted, but they generally boil down to being clear about what is a member of the class(static) and what is a member of the instance.
For starters, you buttons array only exists inside your main method and can't be accessed by changeColors(). Along those same lines, since changeColors() is an instance method, setBackground() needs to be called directly on the button in your array. as written you are setting the color for one button 3 times.
Additionally, the logic in changeColors() is not properly rotating the currentColor index. You need to both increase the counter and ensure is wraps for the length of the color array. If the arrays are the same size, you need to make sure there is an extra addition to make the colors cycle.
private static void changeColors( ) {
for (int i=0;i<buttons.length;i++){
buttons[i].setBackground(COLORS[currentColor]);
currentColor = nextColor(currentColor);
}
if (buttons.length == COLORS.length) {
currentColor = nextColor(currentColor);
}
}
private static int nextColor(int currentColor) {
return (currentColor+1)% COLORS.length;
}
Edit for new code:
I'm not sure why you re-wrote nextColor(), as what I posted worked. But in general, I feel like you are running into issues because your code is not well partitioned for the tasks you are trying to achieve. You have code related to the specific button instance and code related to controlling all the buttons mixing together.
With the following implementation, the issue of how many times a button was clicked is clearly self-contained in the button class. Then every button press also calls the one method in the owning panel. This method knows how many buttons there are and the color of the first button. And each subsequent button will contain the next color in the list, wrapping when necessary.
public class RotateButtons extends JPanel {
private static final Color[] COLORS = { Color.ORANGE, Color.WHITE, Color.GREEN };
private static final int BUTTON_COUNT = 3;
private JButton[] _buttons;
private int _currentColor = 0;
public static void main(String[] args)
{
JFrame frame = new JFrame("JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RotateButtons());
frame.setSize(500, 500);
frame.setVisible(true);
}
public RotateButtons()
{
_buttons = new JButton[BUTTON_COUNT];
for (int i = 0; i < _buttons.length; i++) {
_buttons[i] = new CountButton();
add(_buttons[i]);
}
}
private void rotateButtons()
{
for (JButton button : _buttons) {
button.setBackground(COLORS[_currentColor]);
_currentColor = nextColor(_currentColor);
}
if (_buttons.length == COLORS.length) {
_currentColor = nextColor(_currentColor);
}
}
private int nextColor(int currentColor)
{
return (currentColor + 1) % COLORS.length;
}
private class CountButton extends JButton {
private int _count = 0;
public CountButton()
{
setBackground(Color.YELLOW);
setText("Pick ME");
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
_count++;
setText("# of clicks = " + _count);
rotateButtons();
}
});
}
}
}
2nd Edit:
Shows just the changes to shift _currentColor by the necessary amount on the first click.
public class RotateButtons extends JPanel {
...
private boolean _firstClick = true;
...
private void rotateButtons(CountButton source)
{
if (_firstClick) {
_firstClick = false;
boolean foundSource = false;
for (int i = 0; i < _buttons.length; i++) {
if (foundSource) {
_currentColor = nextColor(_currentColor);
} else {
foundSource = _buttons[i] == source;
}
}
}
...
}
private class CountButton extends JButton {
...
public CountButton()
{
...
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
...
rotateButtons(CountButton.this);
}
});
}
}
One thing that I noticed is you are using currentColor to assign the color, but the currentColor is initialized to 0 and the only manipulation is currentColor %= 2 which does not change it.
If I'm understanding what you are wanting to achieve, I'm thinking to change currentColor %= 2 to ++currentColor, and setBackground(COLORS[currentColor]); to buttons[i].setBackground(COLORS[(i + currentColor) % 3]);. That way, your colours should cycle around your buttons each time one is clicked.
EDIT: it's probably also worth calling changeColors from within main to initialise your button colours. And, as #unholysampler notes, your array buttons is local to main and should (for example) be refactored as a static member variable, and have changeColors become a static method.