Reputation: 3
Hi all this is my first post!
I'm using this calculator project as tool to teach my self java.
I am generally trying to reproduce Microsoft Windows 7 Calculator program.
So far so good, all the buttons work the way they are supposed to, apart from the more complex button functions in Microsoft Calculator everything is pretty much identical.
Here is my problem, Upon implementing an actionlistener/event for the JMenuBar with the following code
String menuText = ((JMenuItem) evt.getSource()).getText();
if(menuText.equals("info")){
System.out.println("it works");
JOptionPane.showMessageDialog(null, "aha it works");
everything collapses around me!
here is the full code
public class Calculator extends JFrame implements ActionListener {
JButton backSpace, clear, one, two, three, four, five, six, seven, eight,
nine, zero, period, devision, modulas, subtraction, addition,
negative, equals;
Font myFont = new Font("ARIAL", Font.BOLD, 40);
JTextArea answerBox = new JTextArea("");
static double numberOne = 0;
static double numberTwo = 0;
static double result;
static String operator = null;
public Calculator() {
super("Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
// set up components
addition = new JButton("+");
backSpace = new JButton("BACKSPACE");
clear = new JButton("CLEAR");
one = new JButton("1");
two = new JButton("2");
three = new JButton("3");
four = new JButton("4");
five = new JButton("5");
six = new JButton("6");
seven = new JButton("7");
eight = new JButton("8");
nine = new JButton("9");
zero = new JButton("0");
period = new JButton(".");
devision = new JButton("/");
modulas = new JButton("*");
subtraction = new JButton("-");
negative = new JButton("-N");
equals = new JButton("=");
// set up answerbox
answerBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
answerBox.setFont(myFont);
answerBox.setEditable(false);
// set up actionListener
backSpace.addActionListener(this);
clear.addActionListener(this);
one.addActionListener(this);
two.addActionListener(this);
three.addActionListener(this);
four.addActionListener(this);
five.addActionListener(this);
six.addActionListener(this);
seven.addActionListener(this);
eight.addActionListener(this);
nine.addActionListener(this);
zero.addActionListener(this);
period.addActionListener(this);
devision.addActionListener(this);
addition.addActionListener(this);
modulas.addActionListener(this);
subtraction.addActionListener(this);
negative.addActionListener(this);
equals.addActionListener(this);
// menu
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("About");
JMenuItem info = new JMenuItem("Info");
info.addActionListener(this);
menu.add(info);
menuBar.add(menu);
setJMenuBar(menuBar);
// set up layout
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
JPanel pane = new JPanel();
pane.setLayout(gridBag);
// default
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.WEST;
constraints.gridy = 0;
constraints.gridx = 0;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.weightx = 10;
constraints.weighty = 10;
constraints.insets = new Insets(2, 2, 2, 2);
// answer box
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 6;
answerBox.append("0");
gridBag.setConstraints(answerBox, constraints);
pane.add(answerBox);
// backSPace
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 3;
gridBag.setConstraints(backSpace, constraints);
pane.add(backSpace);
// clear
constraints.anchor = GridBagConstraints.EAST;
constraints.gridx = 3;
constraints.gridy = 1;
constraints.weightx = 10;
gridBag.setConstraints(clear, constraints);
pane.add(clear);
// nine
constraints.gridwidth = 1;
constraints.weightx = 1;
constraints.gridx = 0;
constraints.gridy = 3;
gridBag.setConstraints(nine, constraints);
pane.add(nine);
// eight
constraints.gridx = 1;
constraints.gridy = 3;
gridBag.setConstraints(eight, constraints);
pane.add(eight);
// seven
constraints.gridx = 2;
constraints.gridy = 3;
gridBag.setConstraints(seven, constraints);
pane.add(seven);
// devision
constraints.gridwidth = 1;
constraints.weightx = 1;
constraints.gridx = 3;
constraints.gridy = 3;
constraints.anchor = GridBagConstraints.SOUTH;
gridBag.setConstraints(devision, constraints);
pane.add(devision);
// EQUALS
constraints.gridx = 4;
constraints.gridy = 3;
constraints.gridwidth = 2;
constraints.gridheight = 4;
constraints.weighty = 30;
constraints.anchor = GridBagConstraints.SOUTH;
gridBag.setConstraints(equals, constraints);
pane.add(equals);
// six
constraints.weighty = 10;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.gridx = 0;
constraints.gridy = 4;
gridBag.setConstraints(six, constraints);
pane.add(six);
// five
constraints.gridx = 1;
constraints.gridy = 4;
gridBag.setConstraints(five, constraints);
pane.add(five);
// four
constraints.gridwidth = 1;
constraints.gridx = 2;
constraints.gridy = 4;
gridBag.setConstraints(four, constraints);
pane.add(four);
// Addition
constraints.gridwidth = 1;
constraints.weightx = 1;
constraints.gridx = 3;
constraints.gridy = 4;
gridBag.setConstraints(addition, constraints);
pane.add(addition);
// three
constraints.gridx = 0;
constraints.gridy = 5;
gridBag.setConstraints(three, constraints);
pane.add(three);
// two
constraints.gridx = 1;
constraints.gridy = 5;
gridBag.setConstraints(two, constraints);
pane.add(two);
// one
constraints.gridx = 2;
constraints.gridy = 5;
gridBag.setConstraints(one, constraints);
pane.add(one);
// subtraction
constraints.gridx = 3;
constraints.gridy = 5;
gridBag.setConstraints(subtraction, constraints);
pane.add(subtraction);
// zero
constraints.gridx = 0;
constraints.gridy = 6;
constraints.gridwidth = 2;
gridBag.setConstraints(zero, constraints);
pane.add(zero);
// period
constraints.gridx = 2;
constraints.gridy = 6;
constraints.gridwidth = 1;
gridBag.setConstraints(period, constraints);
pane.add(period);
// multiplication
constraints.gridx = 3;
constraints.gridy = 6;
constraints.gridwidth = 1;
gridBag.setConstraints(modulas, constraints);
pane.add(modulas);
pack();
add(pane);
}
public static void main(String[] args) {
Calculator frame = new Calculator();
frame.setSize(300, 350);
}
public void actionPerformed(ActionEvent evt){
Object source = evt.getSource();
String menuText = ((JMenuItem) evt.getSource()).getText();
if(menuText.equals("info")){
System.out.println("it works");
JOptionPane.showMessageDialog(null, "aha it works");
}
else if(source == one){
answerBox.append("1");
}else if (source == two){
answerBox.append("2");
}
else if (source == three){
answerBox.append("3");
}
else if (source == four){
answerBox.append("4");
}
else if (source == five){
answerBox.append("5");
}
else if (source == six){
answerBox.append("6");
}
else if (source == seven){
answerBox.append("7");
}
else if (source == eight){
answerBox.append("8");
}
else if (source == nine){
answerBox.append("9");
}
else if (source == zero){
answerBox.append("0");
}
else if (source == addition){
numberOne=Double.parseDouble(answerBox.getText());
operator="+";
answerBox.setText("");
}
else if (source == subtraction){
numberOne=Double.parseDouble(answerBox.getText());
operator="-";
answerBox.setText("");
}
else if (source == modulas){
numberOne=Double.parseDouble(answerBox.getText());
operator="*";
answerBox.setText("");
}
else if (source == devision){
numberOne=Double.parseDouble(answerBox.getText());
operator="/";
answerBox.setText("");
}
else if (source == period){
answerBox.append(".");
}
else if(source == equals){
numberTwo=Double.parseDouble(answerBox.getText());
if(operator.equals("+"))
result=numberOne+numberTwo;
else if(operator.equals("-"))
result=numberOne-numberTwo;
else if(operator.equals("*"))
result=numberOne-numberTwo;
else if(operator.equals("/"))
result=numberOne/numberTwo;
answerBox.setText(" "+result);
operator="=";
}
else if(source == clear){
numberOne=0;
numberTwo=0;
answerBox.setText("");
}
}
}
Upvotes: 0
Views: 749
Reputation: 347184
Several things jump out at me...
You can't rely on the source type being a given instance of a class...
Object source = evt.getSource();
String menuText = ((JMenuItem) evt.getSource()).getText();
This is likely to cause you a ClassCastException
Also, Info
!= info
You define your menu item as ....
JMenuItem info = new JMenuItem("Info");
But you test it's text content with...
if(menuText.equals("info")){
String
comparison in Java is case sensitive (unless you use equalsIgnoresCase
)
You should be supply and using the actionCommand
properties.
For example...
JMenuItem info = new JMenuItem("Info");
info.setActionComand("infoMenu");
Then in you actionPeformed
method you could do something like...
if("infoMenu".equals(evt.getActionCommand())){...}
I would also suggest you take a look at the How to use Actions, these are very powerful, isolated actions, which can be applied to multiple different parts of the application, including menus, buttons and the key bindings API
Upvotes: 1
Reputation: 997
Before you cast evt.getSource to JMenuItem you have to check of source is a JMenuItem. Change your method actionPerformed in the beginning like my example and it works (You have to ask for 'Info' not for 'info'). +1 for camickr - different actionListener is the way for better code quality.
@Override
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source.getClass() == JMenuItem.class) {
String menuText = ((JMenuItem) evt.getSource()).getText();
if (menuText.equals("info")) {
System.out.println("it works");
JOptionPane.showMessageDialog(null, "aha it works");
}
}
else if (source == one) {
answerBox.append("1");
}
Upvotes: 1
Reputation: 324098
String menuText = ((JMenuItem) evt.getSource()).getText();
I'm guessing you are getting a ClassCastException on the above statement.
That code assumes the event is generated by a JMenuItem. The problem is that you are using the same ActionListener for you JButtons and your JMenuItems so you can't assume the source object is a JMenuItem.
It is not a good idea to implement all your code in a single ActionListener. You can share an ActionListener for like functions. For example in the following code the pressing of the digit buttons is always the same so you can use the same listener:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class ButtonCalculator extends JPanel
{
private JButton[] buttons;
private JTextField display;
public ButtonCalculator()
{
Action numberAction = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
display.replaceSelection(e.getActionCommand());
}
};
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
buttons = new JButton[10];
for (int i = 0; i < buttons.length; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
buttons[i] = button;
buttonPanel.add( button );
// Support Key Bindings
KeyStroke pressed = KeyStroke.getKeyStroke(text);
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(pressed, text);
button.getActionMap().put(text, numberAction);
}
setLayout( new BorderLayout() );
add(display, BorderLayout.NORTH);
add(buttonPanel, BorderLayout.SOUTH);
}
private static void createAndShowUI()
{
UIManager.put("Button.margin", new Insets(5, 10, 5, 10) );
JFrame frame = new JFrame("Button Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new ButtonCalculator() );
frame.setResizable( false );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
For your other Actions ("+" , "-" ...) you should create separate listeners.
Upvotes: 3