JButton size & location - java

Hello fellow programmers! I'm starting to learn java, and as a project, i put in my mind to make a visual calculator. My problem is that i can't set an exact location or size for my button, and i would like some help please!
import javax.swing.*;
import java.awt.*;
public class Calculator{
public static void main(String[] args) {
//Frame & sizes
JFrame f = new JFrame("Calculator");
f.setSize(400, 500);
f.setLocation(300,200);
//Text area
final JTextArea textArea = new JTextArea(10, 40);
f.getContentPane().add(BorderLayout.NORTH, textArea);
//Buttons
final JButton button1 = new JButton("1");
button1.setBounds(160, 100, 410, 100);
}
}

There is a lot of additional set-up you need to do, for a tutorial please refer to this article. They do a great job walking you through the steps, I simply pasted the final solution if you want to try it out on your end. To replicate simply create a new Java class called JavaCalculator and run the main method, hopefully this helps!
JavaCalculator:
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Container;
public class JavaCalculator implements ActionListener{
JFrame guiFrame;
JPanel buttonPanel;
JTextField numberCalc;
int calcOperation = 0;
int currentCalc;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new JavaCalculator();
}
});
}
public JavaCalculator()
{
guiFrame = new JFrame();
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Simple Calculator");
guiFrame.setSize(300,300);
guiFrame.setLocationRelativeTo(null);
numberCalc = new JTextField();
numberCalc.setHorizontalAlignment(JTextField.RIGHT);
numberCalc.setEditable(false);
guiFrame.add(numberCalc, BorderLayout.NORTH);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4,4));
guiFrame.add(buttonPanel, BorderLayout.CENTER);
for (int i=0;i<10;i++)
{
addNumberButton(buttonPanel, String.valueOf(i));
}
addActionButton(buttonPanel, 1, "+");
addActionButton(buttonPanel, 2, "-");
addActionButton(buttonPanel, 3, "*");
addActionButton(buttonPanel, 4, "/");
addActionButton(buttonPanel, 5, "^2");
JButton equalsButton = new JButton("=");
equalsButton.setActionCommand("=");
equalsButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if (!numberCalc.getText().isEmpty())
{
int number = Integer.parseInt(numberCalc.getText());
if (calcOperation == 1)
{
int calculate = currentCalc + number;
numberCalc.setText(Integer.toString(calculate));
}
else if (calcOperation == 2)
{
int calculate = currentCalc - number;
numberCalc.setText(Integer.toString(calculate));
}
else if (calcOperation == 3)
{
int calculate = currentCalc * number;
numberCalc.setText(Integer.toString(calculate));
}
else if (calcOperation == 4)
{
int calculate = currentCalc / number;
numberCalc.setText(Integer.toString(calculate));
}
else if (calcOperation == 5)
{
int calculate = currentCalc * currentCalc;
numberCalc.setText(Integer.toString(calculate));
}
}
}
});
buttonPanel.add(equalsButton);
guiFrame.setVisible(true);
}
private void addNumberButton(Container parent, String name)
{
JButton but = new JButton(name);
but.setActionCommand(name);
but.addActionListener(this);
parent.add(but);
}
private void addActionButton(Container parent, int action, String text)
{
JButton but = new JButton(text);
but.setActionCommand(text);
OperatorAction addAction = new OperatorAction(1);
but.addActionListener(addAction);
parent.add(but);
}
public void actionPerformed(ActionEvent event)
{
String action = event.getActionCommand();
numberCalc.setText(action);
}
private class OperatorAction implements ActionListener
{
private int operator;
public OperatorAction(int operation)
{
operator = operation;
}
public void actionPerformed(ActionEvent event)
{
currentCalc = Integer.parseInt(numberCalc.getText());
calcOperation = operator;
}
}
}

Related

Change the text of a JLabel with the source of a MouseListener [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm developing a java component for my sudoku project. This component represents a sudoku box that can have two states: a digit or candidates (I use a CardLayout). So far, all works. I am now trying to add some MouseListener on my Labels. When I click on a candidate, I would like to change the value of the state with a simple number, then change the display (cardlayout.show (...)). The problem here is that the source of the event seems to be detected, but the change is not done ... Here is my code (Problem in CaseComponent > createController > candidate[i].addMouseListener():
package sudoku;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CaseComponent extends JPanel {
private static final long serialVersionUID = 1L;
private static final String CANDIDATES = "candidate";
private static final String DIGIT = "digit";
private GridBagConstraints gridBagConstraint;
private JLabel[] candidates;
private JLabel digit;
public CaseComponent(Color caseColor){
super();
setLayout(new CardLayout());
setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
setPreferredSize(new Dimension(60, 60));
setBackground(caseColor);
createView();
placeComponents();
createController();
}
private void createView() {
gridBagConstraint = new GridBagConstraints();
candidates = new JLabel[9];
for (int i = 0; i < 9; i++) {
candidates[i] = new JLabel(""+(i + 1));
}
digit = new JLabel();
}
private void placeComponents() {
JPanel p = new JPanel(new GridLayout(3, 3)); {
for (int i = 0; i < 9; i++) {
JPanel q = new JPanel(); {
q.add(candidates[i]);
}
q.setOpaque(false);
p.add(q);
}
}
p.setOpaque(false);
add(p, DIGIT);
p = new JPanel(new GridBagLayout()); {
p.add(digit, gridBagConstraint);
p.setOpaque(false);
}
add(p, CANDIDATES);
}
private void createController() {
digit.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
candidateDisplay();
}
}
});
for (int i = 0; i < 9; i++) {
candidates[i].addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
JLabel source = (JLabel) e.getSource();
if (SwingUtilities.isLeftMouseButton(e)) {
System.out.println("IN");
digitDisplay();
digit.setText(source.getText());
}
}
});
}
}
private void digitDisplay() {
CardLayout cl = (CardLayout) getLayout();
cl.show(this, DIGIT);
}
private void candidateDisplay() {
CardLayout cl = (CardLayout) getLayout();
cl.show(this, CANDIDATES);
}
}
package sudoku;
import java.awt.BorderLayout;
import java.awt.Color;
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.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Sudoku {
// ATTRIBUTS
private JFrame mainFrame;
private Timer timer;
private JButton pauseButton;
private JButton resumeButton;
private JButton penaltyButton;
private JLabel chronoInfo;
private Chronometer chrono;
public Sudoku() {
createModel();
createView();
placeComponents();
createController();
}
// COMMANDES
/**
* Rend l'application visible au centre de l'écran.
*/
public void display() {
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
// OUTILS
private void createModel() {
chrono = new Chronometer();
}
private void createView() {
mainFrame = new JFrame("Sudoku");
resumeButton = new JButton("Reprendre");
resumeButton.setEnabled(false);
pauseButton = new JButton("Pause");
penaltyButton = new JButton("Penalité");
chronoInfo = new JLabel("00:00");
}
private void placeComponents() {
JPanel p = new JPanel(); {
p.add(resumeButton);
p.add(pauseButton);
p.add(penaltyButton);
}
mainFrame.add(p, BorderLayout.NORTH);
p = new JPanel(); {
p.add(chronoInfo);
}
mainFrame.add(p, BorderLayout.SOUTH);
p = new JPanel(); {
JPanel q = new JPanel(new GridLayout(3,3)); {
for (int i = 0; i < 9; i++) {
Color caseColor = i % 2 == 0 ? Color.WHITE : Color.GRAY;
JPanel r = new JPanel(new GridLayout(3,3)); {
for (int j = 0; j < 9; j++) {
r.add(new CaseComponent(caseColor));
}
}
r.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
q.add(r);
}
}
q.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
p.add(q);
}
mainFrame.add(p);
}
private void createController() {
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final int delay = 1000;
timer = new Timer(delay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
chrono.increment();
chronoInfo.setText(chrono.toString());
}
});
timer.start();
resumeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.start();
chrono.setPaused(false);
}
});
pauseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
chrono.setPaused(true);
}
});
penaltyButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
chrono.penalty();
chronoInfo.setText(chrono.toString());
}
});
chrono.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
resumeButton.setEnabled(chrono.isPaused());
pauseButton.setEnabled(!chrono.isPaused());
}
});
}
// POINT D'ENTREE
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Sudoku().display();
}
});
}
}
package sudoku;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
public class Chronometer {
// ATTRIBUTS
private static final int MAX_SECONDS = 60;
private final EventListenerList listeners;
private final ChangeEvent changeEvent;
private int seconds;
private int minutes;
private boolean paused;
// CONSTRUCTEUR
public Chronometer() {
listeners = new EventListenerList();
changeEvent = new ChangeEvent(this);
seconds = 0;
minutes = 0;
paused = false;
}
// REQUETES
public int getSeconds() {
return seconds;
}
public int getMinutes() {
return minutes;
}
public boolean isPaused() {
return paused;
}
public ChangeListener[] getChangeListeners() {
return listeners.getListeners(ChangeListener.class);
}
// COMMANDES
public void setSeconds(int s) {
seconds = s;
}
public void setMinutes(int m) {
minutes = m;
}
public void setPaused(boolean b) {
paused = b;
fireStateChanged();
}
public void increment() {
seconds++;
if (seconds == MAX_SECONDS) {
seconds = 0;
minutes++;
}
}
public void penalty() {
seconds += 10;
if (seconds >= MAX_SECONDS) {
minutes++;
seconds -= MAX_SECONDS;
}
}
public void reset() {
seconds = 0;
minutes = 0;
fireStateChanged();
}
public void addChangeListener(ChangeListener listener) {
if (listener == null) {
return;
}
listeners.add(ChangeListener.class, listener);
}
public void removeChangeListener(ChangeListener listener) {
if (listener == null) {
return;
}
listeners.remove(ChangeListener.class, listener);
}
public String toString() {
return String.format("%02d:%02d", minutes, seconds);
}
// OUTILS
protected void fireStateChanged() {
ChangeListener[] listnrs = getChangeListeners();
for (ChangeListener lst : listnrs) {
lst.stateChanged(changeEvent);
}
}
}
I thank you in advance !
Now that looks like a nice program! I took a quick look and I believe I found the problem. In your placeComponents method you swapped the candidates and digit keys of your layout. I also remove unnecessary brackets.
private void placeComponents() {
JPanel p = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < 9; i++) {
JPanel q = new JPanel(); {
q.add(candidates[i]);
}
q.setOpaque(false);
p.add(q);
}
p.setOpaque(false);
add(p, CANDIDATES); // was DIGIT
p = new JPanel(new GridBagLayout()); {
p.add(digit, gridBagConstraint);
p.setOpaque(false);
}
add(p, DIGIT); // was CANDIDATES
}

Add multiple instances of the same button

I am creating a simple calculator for a school assignment but I can't get it to work for multiple digits
package calculator;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Container;
public class Calculator implements ActionListener{
JFrame guiFrame;
JPanel buttonPanel;
JTextField numberCalc;
int calcOperation = 0;
int currentCalc;
public static void main(String[] args) {
//Use the event dispatch thread for Swing components
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new Calculator();
}
});
}
public Calculator()
{
guiFrame = new JFrame();
//make sure the program exits when the frame closes
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Simple Calculator");
guiFrame.setSize(300,300);
//This will center the JFrame in the middle of the screen
guiFrame.setLocationRelativeTo(null);
numberCalc = new JTextField();
numberCalc.setHorizontalAlignment(JTextField.RIGHT);
numberCalc.setEditable(false);
guiFrame.add(numberCalc, BorderLayout.NORTH);
buttonPanel = new JPanel();
//Make a Grid that has three rows and four columns
buttonPanel.setLayout(new GridLayout(4,4));
guiFrame.add(buttonPanel, BorderLayout.CENTER);
//Add the number buttons
for (int i=1;i<10;i++)
{
addButton(buttonPanel, String.valueOf(i));
}
JButton addButton = new JButton("+");
addButton.setActionCommand("+");
OperatorAction subAction = new OperatorAction(1);
addButton.addActionListener(subAction);
JButton subButton = new JButton("-");
subButton.setActionCommand("-");
OperatorAction addAction = new OperatorAction(2);
subButton.addActionListener(addAction);
JButton multiplyButton = new JButton("*");
multiplyButton.setActionCommand("*");
OperatorAction multiAction = new OperatorAction(3);
multiplyButton.addActionListener(multiAction);
JButton divideButton = new JButton("/");
divideButton.setActionCommand("/");
OperatorAction diviAction = new OperatorAction(4);
divideButton.addActionListener(diviAction);
JButton clearButton = new JButton("ce");
clearButton.setActionCommand("ce");
OperatorAction clearAction = new OperatorAction(5);
clearButton.addActionListener(clearAction);
JButton blankButton = new JButton(" ");
JButton equalsButton = new JButton("=");
equalsButton.setActionCommand("=");
equalsButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
if (!numberCalc.getText().isEmpty())
{
int number = Integer.parseInt(numberCalc.getText());
if (calcOperation == 1)
{
int calculate = currentCalc + number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 2)
{
int calculate = currentCalc - number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 3)
{
int calculate = currentCalc * number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 4)
{
int calculate = currentCalc / number;
numberCalc.setText(Integer.toString(calculate));
}
if (calcOperation == 5)
{
int calculate = 0;
numberCalc.setText(Integer.toString(calculate));
}
}
}
});
buttonPanel.add(addButton);
buttonPanel.add(subButton);
buttonPanel.add(equalsButton);
buttonPanel.add(divideButton);
buttonPanel.add(multiplyButton);
buttonPanel.add(clearButton);
buttonPanel.add(blankButton);
guiFrame.setVisible(true);
}
//All the buttons are following the same pattern
//so create them all in one place.
private void addButton(Container parent, String name)
{
JButton but = new JButton(name);
but.setActionCommand(name);
but.addActionListener(this);
parent.add(but);
}
//As all the buttons are doing the same thing it's
//easier to make the class implement the ActionListener
//interface and control the button clicks from one place
#Override
public void actionPerformed(ActionEvent event)
{
//get the Action Command text from the button
String action = event.getActionCommand();
//set the text using the Action Command text
numberCalc.setText(action);
}
private class OperatorAction implements ActionListener
{
private int operator;
public OperatorAction(int operation)
{
operator = operation;
}
public void actionPerformed(ActionEvent event)
{
currentCalc = Integer.parseInt(numberCalc.getText());
calcOperation = operator;
}
}
}
However when I run the code It will not allow me to enter in numbers with more than one digit. Also the ce button I created will not reset to zero.
I have included an image of the output.
Thanks in advance.
Output of calculator
The ActionListener is not correct
#Override
public void actionPerformed(ActionEvent event)
{
//get the Action Command text from the button
String action = event.getActionCommand();
//set the text using the Action Command text
numberCalc.setText(action);
}
This will set the numberCalc text to the value of the button, not append the value.
Use numberCalc.setText(NumberCalc.getText() + action); to append the text
Also, for OperatorAction, you don't update any GUI component
public void actionPerformed(ActionEvent event)
{
currentCalc = Integer.parseInt(numberCalc.getText());
calcOperation = operator;
}
You should clear numberCalc to wait for the next value or you will end up with 1 + 12 instead of 1 + 2.
If the button is clearButton, you need to change the logic and reset everything currentCalc, numberCalc, calcOperation, ...

I get a stack overflow error

I'm trying to create a program where you press start and a new JFrame comes up with 3 buttons , you have to switch the button after you click on it using a random , I'm fairly new to java so I don't know what to do. Thank you
package code;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
public class StartListener implements java.awt.event.ActionListener {
private int counter;
private Game Ga;
private JFrame z;
private int x;
public StartListener(Game a, int co){
Ga=a;
counter = co;
}
public void actionPerformed(ActionEvent e) {
Timer time = new Timer(10000,new Time(Ga));
time.start();
z = new JFrame("Sequence game");
FlowLayout fl = new FlowLayout(0, 50, 40);
z.getContentPane().setLayout(fl);
z.setVisible(true);
JButton a = new JButton("A");
Font f = a.getFont();
Font myFont = f.deriveFont(Font.BOLD, f.getSize()*4);
a.setSize(200,100);
a.setVisible(true);
JButton b = new JButton("B");
b.setVisible(true);
b.setSize(200,100);
JButton c = new JButton("C");
c.setVisible(true);
c.setSize(200,100);
z.getContentPane().add(a);
z.getContentPane().add(b);
z.getContentPane().add(c);
z.pack();
Random r = new Random();
x=r.nextInt(3);
figure(a,b,c,x,myFont,f);}
public void figure(JButton a,JButton b, JButton c, int x, Font myFont,Font f){
if(x==0){
a.setEnabled(true);
b.setEnabled(false);
c.setEnabled(false);
a.setFont(myFont);
b.setFont(f);
c.setFont(f);
x =buttonA(a);
figure(a,b,c,x,myFont,f);
;}
else if(x==1){
a.setEnabled(false);
b.setEnabled(true);
c.setEnabled(false);
a.setFont(f);
c.setFont(f);
b.setFont(myFont);
x = buttonB(b);
figure(a,b,c,x,myFont,f);
}
else if(x==2){
a.setEnabled(false);
b.setEnabled(false);
c.setEnabled(true);
a.setFont(f);
b.setFont(f);
c.setFont(myFont);
x = buttonC(c);
figure(a,b,c,x,myFont,f);
}
}
public int buttonA(JButton a){
Random r = new Random();
int rand = 0;
a.addActionListener(new Something(Ga));
rand = r.nextInt(3);
return rand;
}
public int buttonB(JButton b){
Random r = new Random();
int rand = 0;
b.addActionListener(new Something(Ga));
rand=r.nextInt(3);
return rand;
}
public int buttonC(JButton c){
Random r = new Random();
int rand=0;
c.addActionListener(new Something(Ga));
rand = r.nextInt(3);
return rand;
}
}
And here's the code for Something
package code;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Something implements ActionListener {
private Game G;
public Something(Game a){
G = a;
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
G.increment();
}
}
Here's the error :
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.awt.Component.enable(Unknown Source)
at java.awt.Component.setEnabled(Unknown Source)
at javax.swing.JComponent.setEnabled(Unknown Source)
at javax.swing.AbstractButton.setEnabled(Unknown Source)
Your figure method continuously calls itself recursively forever, or until stack space runs out. Solution: get rid of those recursive calls. Also you really don't want to keep adding multiple ActionListeners on to JButtons, all this suggesting that you will want to refactor and perhaps redesign the entire program.
You will want to change the state of a field in the class, and use that field's state to decide what to do within the ActionListener.
For example:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwapButtons extends JPanel {
private static final Font ACTIVE_FONT = new Font(Font.DIALOG, Font.BOLD, 15);
private static final String[] BTN_TEXT = { "Monday", "Tuesday", "Wednesday" };
private static final int EXTRA_WIDTH = 50;
private List<AbstractButton> buttonList = new ArrayList<>();
private int buttonIndex = 0;
public SwapButtons() {
setLayout(new GridLayout(1, 0, 5, 0));
BtnListener btnListener = new BtnListener();
for (int i = 0; i < BTN_TEXT.length; i++) {
JButton button = new JButton(BTN_TEXT[i]);
button.addActionListener(btnListener);
buttonList.add(button); // add to ArrayList
add(button); // add to GUI
}
setActiveButton();
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
#Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
// give preferred size extra width so gui can handle larger fonts
int prefW = superSz.width + EXTRA_WIDTH;
int prefH = superSz.height;
return new Dimension(prefW, prefH);
}
private void setActiveButton() {
// iterate through buttonList, turning on the "active" button
// as determined by the buttonIndex variable
for (int i = 0; i < buttonList.size(); i++) {
if (i == buttonIndex) {
buttonList.get(i).setFont(ACTIVE_FONT);
buttonList.get(i).setEnabled(true);
} else {
buttonList.get(i).setFont(null);
buttonList.get(i).setEnabled(false);
}
}
}
private class BtnListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// show which button pressed
System.out.println("Button Pressed: " + e.getActionCommand());
// advance button index so that next button can be activated
buttonIndex++;
// but change index to 0 if buttonList size is reached
buttonIndex %= buttonList.size();
// activate the next button:
setActiveButton();
}
}
private static void createAndShowGui() {
SwapButtons mainPanel = new SwapButtons();
JFrame frame = new JFrame("Swap Buttons");
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();
}
});
}
}

Java Applet - For Loop to decrement a stack of components

I've created an Applet that creates a row of buttons, up to 15 buttons, when you push the "add to queue" button. I now want to decrement that row using a for loop. I want it to decrement from left to right. I can only get it to decrement from right to left. I know it has to do with the code in my "Remove" method, but I can't seem to figure out how to fix it. As a newbie I would appreciate any help you can provide.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class Main extends javax.swing.JApplet {
private final int width = 60;
private final int height = 24;
private final int maxItems = 15;
private int x = 40 + width;
private int y = 260;
private int count = 1;
private JButton jAdd;
private JButton jRemove;
Vector<JButton> stack = new Vector<JButton>();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
Main inst = new Main();
frame.getContentPane().add(inst);
((JComponent) frame.getContentPane()).setPreferredSize(inst
.getSize());
frame.pack();
frame.setVisible(true);
}
});
}
public Main() {
super();
initGUI();
}
private void initGUI() {
try {
this.setSize(719, 333);
getContentPane().setLayout(null);
{
jAdd = new JButton();
getContentPane().add(jAdd);
jAdd.setText("Add to Queue");
jAdd.setBounds(43, 300, 150, 24);
jAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jAddActionPerformed(evt);
}
});
}
{
jRemove = new JButton();
getContentPane().add(jRemove);
jRemove.setText("Remove from queue");
jRemove.setBounds(950, 300, 150, 24);
jRemove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jRemoveActionPerformed(evt);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void jAddActionPerformed(ActionEvent evt) {
if (count > maxItems) {
JOptionPane.showMessageDialog(null, "The queue is full");
return;
}
JButton b = new JButton();
stack.add(0, b);
getContentPane().add(b);
int textCount = count;
b.setText("" +textCount++);
b.setBounds(x, y, width, height);
x = x + width;
count++;
}
private void jRemoveActionPerformed(ActionEvent evt) {
if (stack.isEmpty()) {
JOptionPane.showMessageDialog(null, "The queue is empty");
return;
}
JButton b = stack.remove(0);
this.remove(b);
for(int originalX = 880; originalX < 880; originalX--){
x = 880 - width;
}
repaint();
count--;
}
}
The issue is this:
stack.add(0, b);
You are always adding the new one to the start of the Vector (index 0). Remove that and you will see the behavior you want.
stack.add(b);

Setting up KeyListeners using the MVC in java

I am trying to make myself a calculator in Java. I figured it would be best to implement the MVC (model view controller) design for my code. I have some of the basics working, the calculator does actually work, the issue is i cannot figure out where i am going wrong with the implementation of listening to keys. At the moment i have the ability to click on the buttons using the action listener and updating the field with a numeric value and the buttons to add, subtract, multiply, divide and also to clear. So really the only thing on my mind at the moment is trying to allow the user (myself) the option to use the number pad on the keyboard to append values to the field, anyways here is my code.
This the view
package Calculator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class CalcFrame extends JFrame{
private Dimension d = new Dimension(300,300);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JButton equals = new JButton("=");
JButton addBtn = new JButton("+");
JButton subtractBtn = new JButton("-");
JButton multiplyBtn = new JButton("*");
JButton divideBtn = new JButton("/");
JTextArea field = new JTextArea(1,20);
JButton numBtn[] = new JButton[11];
String numTxt[] = {"0","1","2","3","4","5","6","7","8","9","C"};
Color newColor = new Color(10,70,40);
int x = 50, y = 0;
public CalcFrame(){
this.setSize(d);
this.setResizable(false);
// frame.setVisible(true);
this.setTitle("Marks Calculator");
this.setIconImage(new ImageIcon(this.getClass().getResource("emblem.png")).getImage());
for(int i = 0; i < numBtn.length; i++){
numBtn[i] = new JButton(numTxt[i]);
numBtn[i].setSize(50, 30);
}
for(int i = 0; i <numBtn.length; i++){
numBtn[0].setLocation(10,180);
numBtn[1].setLocation(10,140);
numBtn[2].setLocation(65,140);
numBtn[3].setLocation(120,140);
numBtn[4].setLocation(175,140);
numBtn[5].setLocation(10,100);
numBtn[6].setLocation(65,100);
numBtn[7].setLocation(120,100);
numBtn[8].setLocation(175,100);
numBtn[9].setLocation(10,60);
numBtn[10].setLocation(175,20);
panel2.add(numBtn[i]);
}
field.setLocation(10, 10);
field.setSize(280,30);
field.setEditable(false);
field.setFocusable(true);
panel1.setSize(300, 50);
panel1.setLayout(null);
this.add(panel1);
panel2.setSize(300, 250);
panel2.setBackground(newColor);
panel2.setLocation(0, 51);
panel2.setLayout(null);
this.add(panel2);
equals.setLocation(230,180);
equals.setSize(50, 30);
panel2.add(equals);
addBtn.setLocation(230, 140);
addBtn.setSize(50,30);
panel2.add(addBtn);
subtractBtn.setLocation(230, 100);
subtractBtn.setSize(50,30);
panel2.add(subtractBtn);
multiplyBtn.setLocation(230, 60);
multiplyBtn.setSize(50,30);
panel2.add(multiplyBtn);
divideBtn.setLocation(230, 20);
divideBtn.setSize(50,30);
panel2.add(divideBtn);
panel1.add(field);
this.setLocationRelativeTo(rootPane);
this.setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void addKeyL(KeyListener keyp){
addKeyListener(keyp);
}
public void addListener(ActionListener listener){
addBtn.addActionListener(listener);
subtractBtn.addActionListener(listener);
equals.addActionListener(listener);
multiplyBtn.addActionListener(listener);
divideBtn.addActionListener(listener);
for(int i = 0; i < numBtn.length; i++){
numBtn[i].addActionListener(listener);
}
}
public int getFieldText(){
return Integer.parseInt(field.getText());
}
public void setFieldText(){
field.setText("");
}
public void setAnswer(int solution){
field.setText(Integer.toString(solution));
}
}
this is the model
package Calculator;
public class Calculations {
private int total;
public void addNumbers(int a, int b){
total = a + b;
}
public void subtractNumbers(int a, int b){
total = a - b;
}
public void multiplyNumbers(int a, int b){
total = a * b;
}
public void divideNumbers(int a, int b){
total = a / b;
}
public int getTotal(){
return total;
}
}
and this is the controller
package Calculator;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class KeyEvents{
private boolean isAdd = false;
private boolean isSubtract = false;
private boolean isDivide = false;
private boolean isMultiply = false;
private CalcFrame view = new CalcFrame();
private Calculations model = new Calculations();
int a = 0, b = 0, answer;
int counter = 0;
public KeyEvents(CalcFrame view, Calculations model){
this.view = view;
this.model = model;
this.view.addListener(new CalcListener());
this.view.addKeyL(new CalcListener());
}
class CalcListener implements ActionListener, KeyListener{
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(view.addBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = true;
isSubtract = false;
isDivide = false;
isMultiply = false;
}
if(e.getSource().equals(view.numBtn[0])){
view.field.append("0");
}
if(e.getSource().equals(view.numBtn[1])){
view.field.append("1");
}
if(e.getSource().equals(view.numBtn[2])){
view.field.append("2");
}
if(e.getSource().equals(view.numBtn[3])){
view.field.append("3");
}
if(e.getSource().equals(view.numBtn[4])){
view.field.append("4");
}
if(e.getSource().equals(view.numBtn[5])){
view.field.append("5");
}
if(e.getSource().equals(view.numBtn[6])){
view.field.append("6");;
}
if(e.getSource().equals(view.numBtn[7])){
view.field.append("7");
}
if(e.getSource().equals(view.numBtn[8])){
view.field.append("8");
}
if(e.getSource().equals(view.numBtn[9])){
view.field.append("9");
}
if(e.getSource().equals(view.numBtn[10])){
view.field.setText("");
}
if(e.getSource().equals(view.subtractBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = false;
isSubtract = true;
isDivide = false;
isMultiply = false;
}
if(e.getSource().equals(view.multiplyBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = false;
isSubtract = false;
isDivide = false;
isMultiply = true;
}
if(e.getSource().equals(view.divideBtn)){
a = view.getFieldText();
view.field.setText("");
isAdd = false;
isSubtract = false;
isDivide = true;
isMultiply = false;
}
if(e.getSource().equals(view.equals)){
b = view.getFieldText();
if(isAdd == true){
view.setFieldText();
model.addNumbers(a, b);
view.setAnswer(model.getTotal());
}
if(isSubtract == true){
view.setFieldText();
model.subtractNumbers(a, b);
view.setAnswer(model.getTotal());
}
if(isMultiply == true){
view.setFieldText();
model.multiplyNumbers(a, b);
view.setAnswer(model.getTotal());
}
if(isDivide == true){
view.setFieldText();
model.divideNumbers(a, b);
view.setAnswer(model.getTotal());
}
}
}
#Override
public void keyTyped(KeyEvent e) {
if(e.getSource().equals(KeyEvent.VK_0)){
System.out.println("sjkdhlkj");
}
if(e.getSource().equals(KeyEvent.VK_1)){
view.field.append("1");
}
if(e.getSource().equals(KeyEvent.VK_2)){
view.field.append("2");
}
if(e.getSource().equals(KeyEvent.VK_3)){
view.field.append("3");
}
if(e.getSource().equals(KeyEvent.VK_4)){
view.field.append("4");
}
if(e.getSource().equals(KeyEvent.VK_5)){
view.field.append("5");
}
if(e.getSource().equals(KeyEvent.VK_6)){
view.field.append("6");
}
if(e.getSource().equals(KeyEvent.VK_7)){
view.field.append("7");
}
if(e.getSource().equals(KeyEvent.VK_8)){
view.field.append("8");
}
if(e.getSource().equals(KeyEvent.VK_9)){
view.field.append("9");
}
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getSource().equals(KeyEvent.VK_0)){
System.out.println("sjkdhlkj");
}
if(e.getSource().equals(KeyEvent.VK_1)){
view.field.append("1");
}
if(e.getSource().equals(KeyEvent.VK_2)){
view.field.append("2");
}
if(e.getSource().equals(KeyEvent.VK_3)){
view.field.append("3");
}
if(e.getSource().equals(KeyEvent.VK_4)){
view.field.append("4");
}
if(e.getSource().equals(KeyEvent.VK_5)){
view.field.append("5");
}
if(e.getSource().equals(KeyEvent.VK_6)){
view.field.append("6");
}
if(e.getSource().equals(KeyEvent.VK_7)){
view.field.append("7");
}
if(e.getSource().equals(KeyEvent.VK_8)){
view.field.append("8");
}
if(e.getSource().equals(KeyEvent.VK_9)){
view.field.append("9");
}
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getSource().equals(KeyEvent.VK_0)){
System.out.println("sjkdhlkj");
}
if(e.getSource().equals(KeyEvent.VK_1)){
view.field.append("1");
}
if(e.getSource().equals(KeyEvent.VK_2)){
view.field.append("2");
}
if(e.getSource().equals(KeyEvent.VK_3)){
view.field.append("3");
}
if(e.getSource().equals(KeyEvent.VK_4)){
view.field.append("4");
}
if(e.getSource().equals(KeyEvent.VK_5)){
view.field.append("5");
}
if(e.getSource().equals(KeyEvent.VK_6)){
view.field.append("6");
}
if(e.getSource().equals(KeyEvent.VK_7)){
view.field.append("7");
}
if(e.getSource().equals(KeyEvent.VK_8)){
view.field.append("8");
}
if(e.getSource().equals(KeyEvent.VK_9)){
view.field.append("9");
}
}
}
}
the tl;dr of this is, i am unable to get keyListener to work correctly, i have tried assigning the keyListener to the field, panel1, panel2 and this. seperately. Assistance is appreciated as always.
~UPDATE~
I decided to give GitHub a try and have just put my code up on to it. I hope it would make my code easier to understand or even forkable so a person can mess around with it.
https://github.com/niroshido/TestCalculator/tree/master/Calculator
Use Key Bindings. A simple example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
button.setPreferredSize( new Dimension(50, 50) );
buttonPanel.add( button );
KeyStroke pressed = KeyStroke.getKeyStroke(text);
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(pressed, text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
// UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You either need to make sure that whatever component you're adding the KeyListener to has the focus, or you should use key bindings instead.

Categories