Reputation: 43
I've been making a GUI calculator, but I've run into a ditch. I know my code is only restricted to the '2' button, but that's because I've cut out all the numbers so the code can be shorter to be put on here. When I press two, I know the Actionlistener is activated because the System.out.println will print out 2. But it won't appear on my Text Field, where did I go wrong?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Random;
import java.awt.FlowLayout;
public class CalculatorY {
public static JPanel panel = new JPanel(new GridLayout(5, 5));
public static JButton one, two, three, four, five, six, seven, eight, nine, zero, equal;
public static JTextField result;
public static boolean add, sub, mult, div;
public static void main(String[] args) {
JFrame frame = new JFrame("Rohini and Sonika's Calculator");
result = new JTextField(null,90);
two = new JButton("2");
equal = new JButton("=");
two.addActionListener(new button());
panel.setLayout(new GridLayout(5, 5, 5, 25));
panel.setLayout(new FlowLayout());
panel.add(result, BorderLayout.NORTH);
panel.add(two);
frame.setVisible(true);
frame.setSize(200, 400);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
}
public static class button implements ActionListener {
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
String text = result.getText();
int textLength = text.length();
String letterValueOne = null;
String letterValueTwo = null;
boolean operation = false;
if (operation == false) {
if (letterValueOne == null) {
letterValueOne = "2";
System.out.println(letterValueOne);
result.setText(letterValueOne);
} else {
letterValueOne = letterValueOne + "2";
result.setText(letterValueOne);
}
} else {
if (letterValueTwo == null) {
letterValueTwo = "2";
} else {
letterValueTwo = letterValueTwo + "2";
}
}
}
}
}
Upvotes: 2
Views: 968
Reputation: 285430
Yours is a layout/size/placement issue. Myself, I would do things a bit differently including:
For example,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class CalcEg {
private static final float BTN_FONT_SIZE = 20f;
private static final String[][] BTN_LABELS = {
{ "sqr", "sqrt", "exp", "clr" },
{ "7", "8", "9", "-" },
{ "4", "5", "6", "+" },
{ "1", "2", "3", "/" },
{ "0", ".", " ", "=" }
};
private static final int GAP = 4;
private static final String NUMBERS = "0123456789.";
private JPanel mainPanel = new JPanel(new BorderLayout(GAP, GAP));
private JPanel buttonPanel = new JPanel();
private JTextField display = new JTextField();
private Map<String, Runnable> operationMap = new HashMap<>();
public CalcEg() {
int rows = BTN_LABELS.length;
int cols = BTN_LABELS[0].length;
buttonPanel.setLayout(new GridLayout(rows, cols, GAP, GAP));
for (String[] btnLabelRow : BTN_LABELS) {
for (String btnLabel : btnLabelRow) {
if (btnLabel.trim().isEmpty()) {
buttonPanel.add(new JLabel());
} else {
JButton btn = createButton(btnLabel);
if (NUMBERS.contains(btnLabel)) {
Action action = new NumberButtonAction(btnLabel);
btn.setAction(action);
} else {
Action action = new OperationBtnAction(btnLabel);
btn.setAction(action);
}
buttonPanel.add(btn);
}
}
}
display.setFont(display.getFont().deriveFont(BTN_FONT_SIZE));
display.setEditable(false);
display.setFocusable(false);
display.setBackground(Color.white);
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.add(buttonPanel, BorderLayout.CENTER);
mainPanel.add(display, BorderLayout.PAGE_START);
fillOperationMap();
}
private void fillOperationMap() {
operationMap.put("sqr", () -> {
String displayText = display.getText();
try {
double value = Double.parseDouble(displayText);
value *= value;
display.setText(Double.toString(value));
} catch (NumberFormatException e) {
String message = "Invalid entry";
String title = "Number Entry Error";
JOptionPane.showMessageDialog(mainPanel, message, title, JOptionPane.ERROR_MESSAGE);
}
});
operationMap.put("sqrt", () -> {
String displayText = display.getText();
try {
double value = Double.parseDouble(displayText);
value = Math.sqrt(value);
display.setText(Double.toString(value));
} catch (NumberFormatException e) {
String message = "Invalid entry";
String title = "Number Entry Error";
JOptionPane.showMessageDialog(mainPanel, message, title, JOptionPane.ERROR_MESSAGE);
}
});
operationMap.put("exp", () -> {
String displayText = display.getText();
try {
double value = Double.parseDouble(displayText);
value = Math.exp(value);
display.setText(Double.toString(value));
} catch (NumberFormatException e) {
String message = "Invalid entry";
String title = "Number Entry Error";
JOptionPane.showMessageDialog(mainPanel, message, title, JOptionPane.ERROR_MESSAGE);
}
});
operationMap.put("clr", () -> {
display.setText("");
});
operationMap.put("+", () -> {
//....
});
}
private JButton createButton(String btnLabel) {
JButton button = new JButton(btnLabel);
button.setFont(button.getFont().deriveFont(BTN_FONT_SIZE));
return button;
}
public JComponent getMainComponent() {
return mainPanel;
}
private class NumberButtonAction extends AbstractAction {
public NumberButtonAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
String displayText = display.getText();
displayText += getValue(NAME);
try {
Double.parseDouble(displayText);
} catch (NumberFormatException e1) {
String message = "Invalid entry";
String title = "Number Entry Error";
JOptionPane.showMessageDialog(mainPanel, message, title, JOptionPane.ERROR_MESSAGE);
return;
}
display.setText(displayText);
}
}
private class OperationBtnAction extends AbstractAction {
public OperationBtnAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
Runnable operation = operationMap.get(getValue(NAME));
if (operation != null) {
operation.run();
}
// TODO: implement all math operations based on the name of the button
}
}
private static void createAndShowGui() {
CalcEg mainPanel = new CalcEg();
JFrame frame = new JFrame("CalcEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Which would create this GUI:
Upvotes: 1
Reputation: 216
It actually appears on your textField, you simply don't see it, if it's a small window. change
result = new JTextField(null,90);
to
result = new JTextField(null,10);
Then you should see the "2". Another problem:I don't know if this error exists because you removed unnecessary code but Eclipse shows me that e.g.
if (letterValueTwo == null) {
letterValueTwo = "2";
} else {
HERE//letterValueTwo = letterValueTwo + "2";
}
"//Here" can't be reached, because you first assign letterValueTwo == null and that's why your else branch will be never executed.
Upvotes: 0
Reputation: 58929
It does put a 2 in the text field! You can see this by clicking in the text-field, pressing Ctrl-A, then Ctrl-C, then pasting somewhere else.
new JTextField(null, 90)
creates a text field that is wide enough to hold 90 characters, but this is wider than the frame (at least on my system) so it gets cut off at the sides. If you maximize the frame, you should see the 2.
Some possible solutions are:
Make the frame bigger. Note that you can't predict how wide "90 columns" might be on some other computer, so you can't know how big is big enough.
Make the text field smaller. This has the same problem.
Call frame.pack();
at the end. This makes the frame big enough to hold all the components in it. FlowLayout
will arrange them in a line; you might want to go back to using BorderLayout
.
Upvotes: 4