I am pretty new to java when compared to python, having only really using it for about 5 months, and up until 2 months ago only using it for android development. I want to learn more about java especially since I basically just skipped strait to the android dev stuff, and learned only what I needed for whatever project I was working on in that. To help me learn, I decided to learn to make a GUI with swing and a simple calculator. I did it in an hour or two, not counting learning swing, and for a very first non-android java program I'm pretty happy with it
the problem i'm having tho, is that when you input 2 numbers, click a button to perform a calculation, then change the numbers and do it again, the program will still use the original numbers, despite them no longer being there
It does read when there are no numbers or a missing number in the input, but just won't use the new numbers for any calculations.
here is the entire program, sorry for the poorly named variables and generally bad code
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class calc implements ActionListener {
private JLabel num1;
private JLabel num2;
private JLabel lans;
private JFrame frame;
private JButton add;
private JButton sub;
private JButton mult;
private JButton div;
private JPanel panel;
private JTextField tnum1;
private JTextField tnum2;
public calc() {
panel = new JPanel();
frame = new JFrame();
frame.setSize(300, 300);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(panel);
panel.setLayout(null);
num1 = new JLabel("1st Number");
num1.setBounds(20, 20, 80, 25);
panel.add(num1);
num2 = new JLabel("2nd Number");
num2.setBounds(20, 50, 80, 25);
panel.add(num2);
tnum1 = new JTextField();
tnum1.setBounds(100, 20, 80, 25);
panel.add(tnum1);
tnum2 = new JTextField();
tnum2.setBounds(100, 50, 80, 25);
panel.add(tnum2);
add = new JButton("+");
add.setBounds(20, 100, 50, 40);
add.addActionListener(this);
panel.add(add);
sub = new JButton("-");
sub.setBounds(80, 100, 50, 40);
sub.addActionListener(this);
panel.add(sub);
mult = new JButton("×");
mult.setBounds(140, 100, 50, 40);
mult.addActionListener(this);
panel.add(mult);
div = new JButton("÷");
div.setBounds(200, 100, 50, 40);
div.addActionListener(this);
panel.add(div);
lans = new JLabel("");
lans.setBounds(120, 150, 150, 25);
panel.add(lans);
frame.setVisible(true);
}
public static void main(String[] args) {
new calc();
}
#Override
public void actionPerformed(ActionEvent e) {
if (!tnum1.getText().isEmpty() && !tnum2.getText().isEmpty()) {
String snum1 = tnum1.getText();
String snum2 = tnum1.getText();
Double fnum1 = Double.valueOf(snum1);
Double fnum2 = Double.valueOf(snum2);
if (e.getSource() == add) {
Double nans = fnum1 + fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == sub) {
Double nans = fnum1 - fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == mult) {
Double nans = fnum1 * fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == div) {
Double nans = fnum1 / fnum2;
lans.setText(String.valueOf(nans));
}
} else if (!tnum1.getText().isEmpty()) {
lans.setText("No number 2");
} else if (!tnum2.getText().isEmpty()) {
lans.setText("No number 1");
} else {
lans.setText("enter 2 numbers");
}
}
}
yea I know the variables are a bit confusing, but i'm not super familiar with naming conventions yet and i figured since this was a program that I was only using to learn a few select things I didn't really need to use them, especially since I was not planning on actually posting this anywhere.
Edit: im blind, took the first number twice instead of taking both numbers
so I think I found your problem. The only thing you need to change is this.
int snum1 = Integer.parseInt(tnum1.getText());
int snum2 = Integer.parseInt(tnum2.getText());
This portion should go in the actionPerformed. I think the only problem you had was that you used the first variable two times and not the first and the second to do your math.
I rearranged your code because I wanted to explain a few principles about Swing development.
Here's the GUI I created.
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method call ensures that all Swing components are created and executed on the Event Dispatch Thread.
Absolute positioning of Swing components is painful to do and not conducive to the various operating systems and monitor resolutions that people use. I used a GridBagLayout for the main JPanel and a FlowLayout for the button JPanel. Sure, the code looks more complicated. But I didn't have to calculate any component size or location. The Swing layout managers do this for me.
I added a couple of JFrame methods to give the GUI a title and position it on the screen according to the operating system.
I broke up the GUI creation code into methods, so I could focus on one part of the GUI at a time.
Here's the code.
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
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.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class SimpleCalculatorGUI implements ActionListener {
private JLabel lans;
private JFrame frame;
private JButton add;
private JButton sub;
private JButton mult;
private JButton div;
private JTextField tnum1;
private JTextField tnum2;
public SimpleCalculatorGUI() {
frame = new JFrame();
frame.setTitle("Calculator");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1d;
JLabel num1 = new JLabel("1st Number");
panel.add(num1, gbc);
gbc.gridx++;
tnum1 = new JTextField(10);
panel.add(tnum1, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel num2 = new JLabel("2nd Number");
panel.add(num2, gbc);
gbc.gridx++;
tnum2 = new JTextField(10);
panel.add(tnum2, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 2;
panel.add(createButtonPanel(), gbc);
gbc.gridy++;
lans = new JLabel(" ");
lans.setHorizontalAlignment(JLabel.CENTER);
panel.add(lans, gbc);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
add = new JButton("+");
add.addActionListener(this);
panel.add(add);
sub = new JButton("-");
sub.addActionListener(this);
panel.add(sub);
mult = new JButton("×");
mult.addActionListener(this);
panel.add(mult);
div = new JButton("÷");
div.addActionListener(this);
panel.add(div);
return panel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new SimpleCalculatorGUI();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
if (!tnum1.getText().isEmpty()
&& !tnum2.getText().isEmpty()) {
String snum1 = tnum1.getText();
String snum2 = tnum2.getText();
Double fnum1 = Double.valueOf(snum1);
Double fnum2 = Double.valueOf(snum2);
if (e.getSource() == add) {
Double nans = fnum1 + fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == sub) {
Double nans = fnum1 - fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == mult) {
Double nans = fnum1 * fnum2;
lans.setText(String.valueOf(nans));
} else if (e.getSource() == div) {
Double nans = fnum1 / fnum2;
lans.setText(String.valueOf(nans));
}
} else if (!tnum1.getText().isEmpty()) {
lans.setText("No number 2");
} else if (!tnum2.getText().isEmpty()) {
lans.setText("No number 1");
} else {
lans.setText("Enter 2 numbers");
}
}
}
the problem with your code is that you used tnum1.getText() tow times instead of tnum2.getText()
you just need to change the third line in actionPerformed(e) to String snum2 = tnum2.getText(); and it will work
Related
After adding an object of class Puzzle to Main everything displays mostly as it should. when I click any of the buttons some indexes of state should swap to the opposite so from true to false or from false to true.
unfortunately button clicking doesn't want to register for any of the buttons from the array yet it does register for a single button that was initialized by itself. How can I fix the problem?
my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
public class Puzzle extends JFrame implements ActionListener
{
int doors = 8;
boolean [] state = new boolean[doors];
JButton [] levers = new JButton[doors];
JButton weird = new JButton("weird lever");
JLabel display = new JLabel();
Puzzle()
{
reset();
this.setSize(new Dimension(1920, 1080));
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setResizable(false);
this.setLayout(null);
this.add(display);
this.add(weird);
int num = levers.length;
int start = 50;
int size = (1920-(num+1)*start)/num;
char label = 'A';
display.setBounds(size*2, 150, 2000, 300);
display.setFont(new Font("Arial Black", Font.PLAIN, 200));
Display();
for(JButton i : levers)
{
i = new JButton(String.valueOf(label));
label++;
i.setBounds(start, 500, size, size);
start+=(size+50);
i.addActionListener(this);
i.setFont(new Font("Arial black", Font.PLAIN, size/2));
i.setFocusable(false);
this.add(i);
}
weird.setFocusable(false);
weird.setBounds(550, 800, 800, 200);
weird.setFont(new Font("Arial Black", Font.PLAIN, size/2));
weird.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e)
{
/*if(e.getSource() == levers[0])
{
state[2] = Swap(state[2]);
Display();
}
if(e.getSource() == levers[1])
{
state[4] = Swap(state[4]);
state[6] = Swap(state[6]);
Display();
}
if(e.getSource() == levers[2])
{
state[2] = Swap(state[2]);
state[3] = Swap(state[3]);
state[6] = Swap(state[6]);
state[7] = Swap(state[7]);
Display();
}
if(e.getSource() == levers[3])
{
state[0] = Swap(state[0]);
state[2] = Swap(state[2]);
state[7] = Swap(state[7]);
Display();
}
if(e.getSource() == levers[4])
{
state[1] = Swap(state[1]);
state[3] = Swap(state[3]);
state[4] = Swap(state[4]);
state[5] = Swap(state[5]);
Display();
}
if(e.getSource() == levers[5])
{
state[0] = Swap(state[0]);
state[2] = Swap(state[2]);
state[6] = Swap(state[6]);
Display();
}
if(e.getSource() == levers[6])
{
state[1] = Swap(state[1]);
state[5] = Swap(state[5]);
Display();
}
if(e.getSource() == levers[7])
{
state[1] = Swap(state[1]);
state[2] = Swap(state[2]);
state[4] = Swap(state[4]);
state[5] = Swap(state[5]);
Display();
}
*/
if(e.getSource() == levers[0])
{
display.setText("A works");
}
if(e.getSource() == weird)
{
display.setText("test");
}
}
boolean Swap(boolean n)
{
return !n;
}
void Display()
{
StringBuilder toDisplay = new StringBuilder();
for (boolean j : state)
{
if (j)
{
toDisplay.append("| ");
} else
toDisplay.append("_ ");
}
display.setText(toDisplay.toString());
}
void reset ()
{
Arrays.fill(state, true);
}
}```
button clicking doesn't want to register for any of the buttons from the array yet it does register for a single button
System.out.println( levers[0] );
if(e.getSource() == levers[0])
{
display.setText("A works");
}
Add some debug code to your ActionListener and you will see that the value of levers[0] is "null".
for(JButton i : levers)
{
i = new JButton(String.valueOf(label));
label++;
i.setBounds(start, 500, size, size);
start+=(size+50);
i.addActionListener(this);
i.setFont(new Font("Arial black", Font.PLAIN, size/2));
i.setFocusable(false);
this.add(i);
}
You create the button, but you never add the instance of each button to the Array.
for(JButton i : levers)
Why would you use "i" as the variable name. Typically "i" is used as an index. Use a proper variable name, like "button". However, in this case you don't want to use a "for each" loop.
Instead you want a normal for loop so you can index your Array to add each button as you create it:
//for(JButton i : levers)
for (int i = 0; i < doors; i++)
{
JButton button = new JButton(String.valueOf(label));
levers[i] = button;
...
Other issues:
method names should NOT start with an upper case character.
components should be added to the frame BEFORE the frame is made visible.
components should be created on the Event Dispatch Thread (EDT).
Don't use a null layout and setBounds(). Swing was designed to be used with layout managers.
Don't hardcode screen sizes. Instead you can use frame.setExtendedState(JFrame.MAXIMIZED_BOTH);, so it will work for all screen sizes.
Introduction
Your code was too complex for me to understand. I like simple code. Short methods and simple classes.
Here's the GUI I came up with.
Here's the GUI after I clicked a couple of letter JButtons
Explanation
Oracle has a nifty tutorial, Creating a GUI With JFC/Swing, which will show you how to create a Swing GUI. Skip the Netbeans section.
Your code was missing a main method, so I added one. I started the Swing application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
The first thing I did was create a PuzzleModel class to hold the boolean array. It's a good idea to separate your model from your view and controller classes. This pattern is the model / view / controller (MVC) pattern.
A Swing JFrame can contain many JPanels. I created a segment JPanel to hold a JLabel and a JButton aligned vertically. I used the GridBagLayout to align the JLabel and JButton. Swing layout managers help you to avoid absolute positioning and the problems that come with absolute positioning.
I created a main JPanel to hold 8 segment JPanels. These JPanels are aligned with a FlowLayout.
As you can see, my JFrame is smaller than yours. You create as small a JFrame as possible. If the user wants to make it bigger, that's what the rectangle in the upper right corner is for.
Swing is meant to be designed from the inside out. You don't specify a JFrame size and try to make the components fit. You create the components and let Swing determine the size of the JFrame. If you want the JFrame I created to be bigger, increase the font sizes. Hint: A fraction or multiple of 72 points looks better on most displays.
I created two ActionListener classes, one for the alphabet JButtons and one for the lever JButton. This makes it easier to focus on the alphabet JButtons. All you have to do in the ActionListener is swap the appropriate isVertical boolean values when each JButton is left-clicked. I just flipped the corresponding boolean as a demonstration.
Code
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PuzzleGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new PuzzleGUI());
}
private JLabel[] leverLabel;
private final PuzzleModel model;
public PuzzleGUI() {
this.model = new PuzzleModel();
}
#Override
public void run() {
JFrame frame = new JFrame("Weird Lever");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
System.out.println(frame.getSize());
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
char c = 'A';
boolean[] isVertical = model.getIsVertical();
leverLabel = new JLabel[isVertical.length];
for (int i = 0; i < isVertical.length; i++) {
String labelText = (isVertical[i]) ? "|" : "-";
panel.add(createLeverButtonPanel(labelText, Character.toString(c), i));
c = (char) (((int) c) + 1);
}
return panel;
}
public void updateMainPanel() {
boolean[] isVertical = model.getIsVertical();
for (int i = 0; i < isVertical.length; i++) {
String labelText = (isVertical[i]) ? "|" : "-";
leverLabel[i].setText(labelText);
}
}
private JPanel createLeverButtonPanel(String labelText, String buttonText, int index) {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
Font font1 = new Font("Arial Black", Font.PLAIN, 144);
Font font2 = new Font("Arial Black", Font.PLAIN, 72);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
leverLabel[index] = new JLabel(labelText);
leverLabel[index].setFont(font1);
panel.add(leverLabel[index], gbc);
gbc.gridy++;
JButton button = new JButton(buttonText);
button.addActionListener(new AlphabetButtonListener());
button.setFont(font2);
panel.add(button, gbc);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
Font font2 = new Font("Arial Black", Font.PLAIN, 48);
JButton button = new JButton("Weird Lever");
button.addActionListener(new LeverButtonListener());
button.setFont(font2);
panel.add(button);
return panel;
}
public class AlphabetButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
JButton button = (JButton) event.getSource();
String text = button.getText();
char c = text.charAt(0);
int index = ((int) c - 'A');
model.swap(index);
updateMainPanel();
}
}
public class LeverButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
}
}
public class PuzzleModel {
private boolean[] isVertical;
public PuzzleModel() {
int doors = 8;
this.isVertical = new boolean[doors];
reset();
}
private void reset() {
Arrays.fill(isVertical, true);
}
public void swap(int index) {
isVertical[index] = !isVertical[index];
}
public boolean[] getIsVertical() {
return isVertical;
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI_Borrower extends JFrame implements ActionListener {
JPanel panel = new JPanel();
JLabel lblName = new JLabel("Name:");
JLabel lblProg = new JLabel("Program:");
JLabel lblId = new JLabel("Library ID: ");
JLabel lblTitle = new JLabel("Add Borrower");
JTextField txtName = new JTextField(10);
JTextField txtProg = new JTextField(10);
JTextField txtId = new JTextField(10);
static int counter = 19000;
JButton btnSubmit = new JButton("Submit");
public GUI_Borrower() {
super("Add Borrower");
makeFrame();
showFrame();
}
public void makeFrame() {
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
add(lblTitle);
add(lblName);
add(txtName);
add(lblProg);
add(txtProg);
add(lblId);
add(txtId);
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(btnSubmit);
btnSubmit.addActionListener(this);
}
public void showFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (ae.getActionCommand().equals("Confirm")) {
txtName.setText("");
txtProg.setText("");
btnSubmit.setText("Submit");
} else if (source == btnSubmit) {
if (txtName.getText().equals("") && txtProg.getText().equals("")) {
txtId.setText("No entry of both");
} else if (txtName.getText().equals("")) {
txtId.setText("No entry of Name");
} else if (txtProg.getText().equals("")) {
txtId.setText("No entry of Program");
} else {
counter++;
txtId.setText("" + counter);
btnSubmit.setText("Confirm");
}
}
}
public static void main(String[] args) {
new GUI_Borrower();
}
}
I tried adding BoxLayout because all the text fields and labels are on one line. So I tried box Layout and failed.
Can anyone show me how to make it like the title one line, label Different line, button different line?
Like this:
As camickr says in his comment, you generally use a GridBagLayout to create a form.
I reworked your code because I hope to show a better way to code a GUI panel.
Here's the GUI.
The major changes I made include:
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.
I organized the GUI code into three methods so I could focus on one part of the GUI at a time. The JFrame is created in the run method. The title JPanel is created in the createTitlePanel method. The form JPanel is created in the createFormPanel method. The code for the JFrame will rarely change from Swing application to Swing application.
I use Swing components. I don't extend Swing components, or any Java class, unless I intend to override one of the class methods.
The createFormPanel class uses the GridBagLayout to organize the labels and text fields in columns. You can think of the GridBagLayout as a flexible grid. The cells of the grid don't have to be the same size. The Oracle tutorial, How to Use GridBagLayout, has another example.
I put the ActionListener in a separate class. I made it an inner class in this example so I could paste the code as one file. Generally, you should put separate classes in separate files. It makes each class shorter and easier to understand.
Here's the runnable, example code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
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.JTextField;
import javax.swing.SwingUtilities;
public class BorrowerGUI implements Runnable {
private static int ID_COUNTER = 19000;
public static void main(String[] args) {
SwingUtilities.invokeLater(new BorrowerGUI());
}
private JButton btnSubmit;
private JTextField txtName;
private JTextField txtProg;
private JTextField txtId;
#Override
public void run() {
JFrame frame = new JFrame("Add Borrower");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTitlePanel(), BorderLayout.BEFORE_FIRST_LINE);
frame.add(createFormPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTitlePanel() {
JPanel panel = new JPanel(new FlowLayout());
JLabel lblTitle = new JLabel("Add Borrower");
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
panel.add(lblTitle);
return panel;
}
private JPanel createFormPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel lblName = new JLabel("Name:");
panel.add(lblName, gbc);
gbc.gridx++;
txtName = new JTextField(20);
panel.add(txtName, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel lblProg = new JLabel("Program:");
panel.add(lblProg, gbc);
gbc.gridx++;
txtProg = new JTextField(20);
panel.add(txtProg, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel lblId = new JLabel("Library ID:");
panel.add(lblId, gbc);
gbc.gridx++;
txtId = new JTextField(20);
txtId.setEditable(false);
panel.add(txtId, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 2;
btnSubmit = new JButton("Submit");
btnSubmit.addActionListener(new SubmitListener());
panel.add(btnSubmit, gbc);
return panel;
}
public class SubmitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (ae.getActionCommand().equals("Confirm")) {
txtName.setText("");
txtName.requestFocus();
txtProg.setText("");
txtId.setText("");
btnSubmit.setText("Submit");
} else if (source == btnSubmit) {
if (txtName.getText().equals("") &&
txtProg.getText().equals("")) {
txtId.setText("No entry of both");
} else if (txtName.getText().equals("")) {
txtId.setText("No entry of Name");
} else if (txtProg.getText().equals("")) {
txtId.setText("No entry of Program");
} else {
ID_COUNTER++;
txtId.setText("" + ID_COUNTER);
btnSubmit.setText("Confirm");
}
}
}
}
}
Edited to add: If you want the title JLabel to be right-justified, you'll have to switch to a BorderLayout. I added an empty border so the text wouldn't be on the right edge of the JFrame.
Here's the changed method.
private JPanel createTitlePanel(String title) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
JLabel lblTitle = new JLabel(title);
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
panel.add(lblTitle, BorderLayout.AFTER_LINE_ENDS);
return panel;
}
Can someone please tell me what's wrong with this code?
I need it to pop up a frame and fill the frame with certain field a namer field and an intake field and also display a button at the bottom of the grid.
Any help would be welcomed, Thanks!!
import java.awt.*;
import javax.swing.*;
public class FrameDemo
//To create the gui and show it.
{
public static void createAndShowGUI()
{
//create and set up the window.
JFrame frame = new JFrame("RungeKutta");
GridLayout first = new GridLayout(1,14);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create, name and Populate TextField
JTextField PL = new JTextField("Pendulum Length", 20);
//Set TextField to Uneditable. Each will have Empty Field Below For Variables
PL.setEditable(false);
//Set Textfield for user entered dat
JTextField PLv = new JTextField();
//Allow handler for user input on Empty Textfield?
JTextField AD = new JTextField("Angular Displacement", 20);
AD.setEditable(false);
JTextField ADv = new JTextField();
JTextField AV = new JTextField("Angular Velocity", 20);
AV.setEditable(false);
JTextField Avv = new JTextField();
JTextField TS= new JTextField("Time Steps", 20);
TS.setEditable(false);
JTextField TSv = new JTextField();
JTextField MT = new JTextField("Max Time", 20);
MT.setEditable(false);
JTextField MTv = new JTextField();
JTextField V = new JTextField("Viscosity (0-1)", 20);
V.setEditable(false);
JTextField Vv = new JTextField();
//Create Button to Restart
JButton BNewGraph = new JButton("Draw New Graph"); //Button to restart entire drawing process
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(600,500));
frame.getContentPane().add(PL, first);
frame.getContentPane().add(PLv, first);
frame.getContentPane().add(AD, first);
frame.getContentPane().add(ADv, first);
frame.getContentPane().add(AV, first);
frame.getContentPane().add(Avv, first);
frame.getContentPane().add(TS, first);
frame.getContentPane().add(TSv, first);
frame.getContentPane().add(MT, first);
frame.getContentPane().add(MTv, first);
frame.getContentPane().add(V, first);
frame.getContentPane().add(Vv, first);
frame.getContentPane().add(BNewGraph, first);
//display the window
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
//add job to event scheduler
//create and show GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
This is not how you use GridLayout:
frame.getContentPane().add(PL, first);
Instead you'd set the container's layout using the layout manager:
frame.getContentPane().setLayout(first);
and then add components to the container:
frame.getContentPane().add(PL);
frame.getContentPane().add(PLv);
frame.getContentPane().add(AD);
frame.getContentPane().add(ADv);
frame.getContentPane().add(AV);
frame.getContentPane().add(Avv);
frame.getContentPane().add(TS);
frame.getContentPane().add(TSv);
frame.getContentPane().add(MT);
frame.getContentPane().add(MTv);
// and so on for all the components.
You will want to read the tutorial on how to use GridLayout which you can find here: GridLayout Tutorial.
As an aside, note that this:
frame.getContentPane().add(PL);
can be shortened to this:
frame.add(PL);
Also you will want to study and learn Java naming conventions: class names begin with an upper case letter and all method and variables with lower case letters. Also avoid variable names like pl or plv, or ad or adv, and instead use names that are a little bit longer and have meaning, names that make your code self-commenting. So instead of AD, consider angularDisplacementField for the JTextfield's name.
Myself, I'd use a GridBagLayout and do something like:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.*;
public class GuiDemo extends JPanel {
// or better -- use an enum for this
public static final String[] FIELD_LABELS = {
"Pendulum Length", "Angular Displacement", "Angular Velocity",
"Time Steps", "Max Time", "Viscocity (0-1)"
};
private static final int TEXT_FIELD_COLUMNS = 10;
private static final int GAP = 3;
private static final Insets RIGHT_GAP_INSETS = new Insets(GAP, GAP, GAP, 3 * GAP);
private static final Insets BALANCED_INSETS = new Insets(GAP, GAP, GAP, GAP);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public GuiDemo() {
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
int row = 0;
// to make sure that no focusAccelerator is re-used
Set<Character> focusAccelSet = new HashSet<>();
for (String fieldLabelLText : FIELD_LABELS) {
JLabel fieldLabel = new JLabel(fieldLabelLText);
JTextField textField = new JTextField(TEXT_FIELD_COLUMNS);
labelFieldPanel.add(fieldLabel, getGbc(row, 0));
labelFieldPanel.add(textField, getGbc(row, 1));
labelFieldMap.put(fieldLabelLText, textField);
for (char c : fieldLabelLText.toCharArray()) {
if (!focusAccelSet.contains(c)) {
textField.setFocusAccelerator(c);
fieldLabel.setDisplayedMnemonic(c);
focusAccelSet.add(c);
break;
}
}
row++;
}
JButton button = new JButton(new DrawGraphAction("Draw New Graph"));
labelFieldPanel.add(button, getGbc(row, 0, 2, 1));
setLayout(new BorderLayout(GAP, GAP));
add(labelFieldPanel, BorderLayout.CENTER);
}
private class DrawGraphAction extends AbstractAction {
public DrawGraphAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO calculation method
}
}
public static GridBagConstraints getGbc(int row, int column) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = column;
gbc.gridy = row;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
if (column == 0) {
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = RIGHT_GAP_INSETS;
} else {
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = BALANCED_INSETS;
}
return gbc;
}
public static GridBagConstraints getGbc(int row, int column, int width, int height) {
GridBagConstraints gbc = getGbc(row, column);
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.insets = BALANCED_INSETS;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Gui Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GuiDemo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I am trying to have a frame that has a JLabel on it. I have succeeded in adding it to the frame but the text shows up in a narrow column instead of taking up more space in the window. How do I fix this? I tried using the html with no luck.
EDIT: The intro panel is the one I am having trouble with.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Window implements ActionListener{
JFrame frame = new JFrame("Loan Program");
JFrame intro = new JFrame("Welcome To The Loan Program!");
JPanel panel = new JPanel(new GridBagLayout());
JPanel panel2 = new JPanel(new GridBagLayout());
JPanel panel3 = new JPanel(new GridBagLayout());
JPanel descriptionPanel = new JPanel(new GridBagLayout());
JPanel descriptionPanel1 = new JPanel(new GridBagLayout());
GridBagConstraints g = new GridBagConstraints();
JButton calculate;
JButton cancel;
JButton reset;
JButton introOk;
JLabel loanAmount;
JLabel loanInterest;
JLabel loanPeriod;
JLabel monthlyRepayment;
JLabel introLabel;
JTextField laField;
JTextField liField;
JTextField lpField;
JTextField mrField;
DecimalFormat df = new DecimalFormat("#.##");
public Window() {
g.insets = new Insets(10, 10, 20, 10); //For the spacing between elements
//Initalizing components
introLabel = new JLabel();
introOk = new JButton("Ok");
//Setting up text for intro panel
String text = "<html><h1 align='center'>Loan Program 1.0</h1>";
text = text + "This program lets you calculate the various aspects of loans <br />";
text = text + "If you are leaving a field empty then use 0 for its place <br />";
text = text + "<h1 align='center'>Text Fields To Enter</h1>";
text = text + "Monthly Payment: Enter values for: Loan Period, Loan Amount, and Loan Interest. Enter 0 for Monthly Payment. <br />";
text = text + "Loan Period: Enter Values for: Loan Amount, Loan Interest, and Monthly Payment. Enter 0 for Loan Period. <br />";
//Setting text to the label
introLabel.setText(text);
//Positioning introLabel
descriptionPanel.add(introLabel, g);
//Positioning button
descriptionPanel1.add(introOk, g);
//Actionlistener for buttont to dipose current frame.
introOk.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
intro.dispose();
}
});
intro.add(descriptionPanel);
intro.add(descriptionPanel1, BorderLayout.SOUTH);
//Initializing buttons here and adding them to panel
calculate = new JButton("Calculate");
reset = new JButton("Reset");
cancel = new JButton("Cancel");
panel.add(calculate, g);
panel.add(reset, g);
panel.add(cancel, g);
//Adding the Actionlistener for buttons
calculate.addActionListener(this);
reset.addActionListener(this);
cancel.addActionListener(this);
//Initializing the labels
loanAmount = new JLabel("Loan Amount:");
loanInterest = new JLabel("Loan Interest:");
loanPeriod = new JLabel("Loan Period:");
monthlyRepayment = new JLabel("Monthly Payment:");
//Positioning loanAmount label
g.gridx = 0;
g.gridy = 0;
panel2.add(loanAmount, g);
//Positioning loanInterest label
g.gridx = 0;
g.gridy = 2;
panel2.add(loanInterest, g);
//Positioning loanPeriod label
g.gridx = 0;
g.gridy = 3;
panel2.add(loanPeriod, g);
//Positioning monthlyRepayment label
g.gridx = 0;
g.gridy = 4;
panel2.add(monthlyRepayment, g);
//Initializing the text fields
laField = new JTextField("", 20);
liField = new JTextField("", 20);
lpField = new JTextField("", 20);
mrField = new JTextField("", 20);
//Positioning laField
g.gridx = 1;
g.gridy = 0;
panel2.add(laField, g);
//Positioning liField
g.gridx = 1;
g.gridy = 2;
panel2.add(liField, g);
//Positioning lpField
g.gridx = 1;
g.gridy = 3;
panel2.add(lpField, g);
//Positioning mrField
g.gridx = 1;
g.gridy = 4;
panel2.add(mrField, g);
//Adding panels to the frame using boarderlayout
frame.add(panel, BorderLayout.SOUTH);
frame.add(panel2, BorderLayout.WEST);
// Creating the window
frame.setSize(500, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//popup window for intro
intro.setSize(500, 500);
intro.setVisible(true);
intro.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if(o == cancel) {
//Initializing components for the window
JFrame frame1 = new JFrame("Are you sure?");
JPanel panel = new JPanel(new GridBagLayout());
JPanel panel2 = new JPanel(new GridBagLayout());
JLabel label = new JLabel("Are you sure you want to exit?");
JButton yes = new JButton("Yes");
JButton no = new JButton("No");
//Positioning Label
g.gridx = 0;
g.gridy = 0;
panel.add(label, g);
//Positioning yes button
g.gridx = 0;
g.gridy = 0;
g.gridwidth = 1;
panel2.add(yes, g);
//Positioning no button
g.gridx = 1;
g.gridy = 0;
panel2.add(no, g);
//Action to close program when yes is clicked
yes.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//Action to close current window if no is clicked
no.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame1.dispose();
}
});
//Adding the panels to frame with borderlayout
frame1.add(panel, BorderLayout.NORTH);
frame1.add(panel2, BorderLayout.SOUTH);
//Setting up frame
frame1.setSize(300, 300);
frame1.setVisible(true);;
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Adding actionListener once again for second level of menu
//No to close the current window
Object b = e.getSource();
if(b == no) {
System.out.println("heres");
frame1.dispose();
}
//Yes to close the program completely
if(b == yes) {
System.exit(0);
}
}
//New instance of window to reset it
if(o == reset) {
frame.dispose();
new Window();
}
//Calculate buttons actions
if(o == calculate) {
//Test values to see if they are being passed
System.out.println(laField.getText() + "\n" + liField.getText() + "/n" + lpField.getText() + "\n" + mrField.getText());
//If statement for monthly payment with the correct fields filled out
if(laField.getText() != null && liField.getText() != null && lpField.getText() != null && mrField.getText() == "0") {
//Strings and double and ints to convert from text field number.
String sRate, sMonths, sPrincipal;
sRate = liField.getText();
sMonths = lpField.getText();
sPrincipal = laField.getText();
double rate = Double.parseDouble(sRate);
int months = Integer.parseInt(sMonths);
double principal = Double.parseDouble(sPrincipal);
//Setting up components for new window
JFrame frame = new JFrame("Monthly Payment");
JPanel panel = new JPanel(new GridBagLayout());
JPanel panel2 = new JPanel(new GridBagLayout());
JLabel label = new JLabel("The monthly payment is: " + df.format(calculateMonthlyRepayment(rate, months, principal)));
JButton button = new JButton("Ok");
//Action listener for okay button to just close current frame.
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.dispose();
}
});
//Padding for element
g.insets = new Insets(5, 5, 5, 5);
//Adding components to panel
panel.add(label, g);
panel2.add(button, g);
//Adding panels to frame
frame.add(panel, BorderLayout.CENTER);
frame.add(panel2, BorderLayout.SOUTH);
//Intializing frame
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//If statement for period calculation checks to see proper fields filled
if(mrField.getText() != null && liField.getText() != null && laField.getText() != null && lpField.getText() == "0"); {
//String and doubles to convert to numbers from text box
String sMonthlyPayment, sloanAmount, sinterestRate;
sMonthlyPayment = mrField.getText();
sloanAmount = laField.getText();
sinterestRate = liField.getText();
double monthlyPayment = Double.parseDouble(sMonthlyPayment);
double loanAmount = Double.parseDouble(sloanAmount);
double interestRate = Double.parseDouble(sinterestRate);
//Initializing the components
JFrame frame = new JFrame("Total Loan Period");
JPanel panel = new JPanel(new GridBagLayout());
JPanel panel2 = new JPanel(new GridBagLayout());
JLabel label = new JLabel("Total number of periods is : " + calculatePeriod(monthlyPayment, interestRate, loanAmount));
JButton button = new JButton("Ok");
//Button listener to close current frame
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.dispose();
}
});
//Padding for the components
g.insets = new Insets(5, 5, 5, 5);
//Adding componeents to panel with gridbag
panel.add(label, g);
panel2.add(button, g);
//Adding panels to frame
frame.add(panel, BorderLayout.CENTER);
frame.add(panel2, BorderLayout.SOUTH);
//Initializing the frame
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
}
public double calculateMonthlyRepayment(double rate, int months, double principal) {
String input = mrField.getText();
double totalMr = Double.parseDouble(input);
double mrpayment = (rate + ((rate)/((Math.pow(1 + rate, months) - 1)))) * principal;
return mrpayment;
}
double calculatePeriod(double monthlyPayment, double interestRate, double loanAmount) {
return (Math.log(monthlyPayment) - Math.log(monthlyPayment - (loanAmount * interestRate))) / Math.log(1 + interestRate);
}
}
First, a recommendation, please try using a gui designer like window builder or matisse. they really ease your daily work and limit the badness of code on defining layout constraints.
if you experience troubles with the layout and non appearing or misaligned components, it´s usually a sign of wrong usage of your desired layout manager. There are excellent posts about it throughout stackoverflow.
Your most significant error in the code is reusing the GridBagConstraints, which is a bad idea because
As you might have guessed from the above example, it is possible to reuse the same GridBagConstraints instance for multiple components, even if the components have different constraints. However, it is recommended that you do not reuse GridBagConstraints, as this can very easily lead to you introducing subtle bugs if you forget to reset the fields for each new instance.
so try to share your constraints only if they are the same for each component, e.g. constraints for the labels and another one for the textfield columns.
There also lies your error on narrow columns. if you also want to specify a desired width for all labels, set the gridwidth on the label contstraint. this applies to the textfield constraint, too.
Check out the GridBagLayout Example again, for better understanding of its usage.
Some more advises:
Naming your class Window maybe mislead others because they could assume they are using java.awt.window, which is totally different from your class and can be overseen as you see it only on the import statement.
Any gui element must be called from the EDT, so invoke your class using the SwingUtilities, like
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Window();
}
});
dont forget to call pack() to let the layout manager do its work based on your constraints.
Try also to avoid using tons of frames, instead use dialogs. Frames should only be used if its needed to have them in a separate context, like they would be totally indepedent from each other.
An example for you to start with:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class GridExample extends JFrame{
public GridExample() {
initComponents();
pack();
setTitle("GridExample");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null); //Center, could also be setLocationByPlatform(true);
}
#Override
public Dimension preferredSize() {
return new Dimension(500,300);
}
private void initComponents() {
getContentPane().setLayout(new BorderLayout(0, 0));
JPanel mainPanel = new JPanel();
getContentPane().add(mainPanel, BorderLayout.CENTER);
GridBagLayout gbl_mainPanel = new GridBagLayout();
gbl_mainPanel.columnWidths = new int[]{0, 0, 0, 0};
gbl_mainPanel.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
gbl_mainPanel.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
gbl_mainPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
mainPanel.setLayout(gbl_mainPanel);
JLabel lblLoanAmount = new JLabel("Loan Amount:");
GridBagConstraints gbc_lblLoanAmount = new GridBagConstraints();
gbc_lblLoanAmount.fill = GridBagConstraints.HORIZONTAL;
gbc_lblLoanAmount.insets = new Insets(0, 0, 5, 5);
gbc_lblLoanAmount.gridx = 0;
gbc_lblLoanAmount.gridy = 0;
mainPanel.add(lblLoanAmount, gbc_lblLoanAmount);
txtLoanAmount = new JTextField();
GridBagConstraints gbc_txtLoanAmount = new GridBagConstraints();
gbc_txtLoanAmount.gridwidth = 2;
gbc_txtLoanAmount.insets = new Insets(0, 0, 5, 0);
gbc_txtLoanAmount.fill = GridBagConstraints.HORIZONTAL;
gbc_txtLoanAmount.gridx = 1;
gbc_txtLoanAmount.gridy = 0;
mainPanel.add(txtLoanAmount, gbc_txtLoanAmount);
txtLoanAmount.setColumns(10);
JLabel lblLoanInterest = new JLabel("Loan Interest:");
GridBagConstraints gbc_lblLoanInterest = new GridBagConstraints();
gbc_lblLoanInterest.insets = new Insets(0, 0, 5, 5);
gbc_lblLoanInterest.fill = GridBagConstraints.BOTH;
gbc_lblLoanInterest.gridx = 0;
gbc_lblLoanInterest.gridy = 1;
mainPanel.add(lblLoanInterest, gbc_lblLoanInterest);
txtLoanInterest = new JTextField();
GridBagConstraints gbc_txtLoanInterest = new GridBagConstraints();
gbc_txtLoanInterest.gridwidth = 2;
gbc_txtLoanInterest.anchor = GridBagConstraints.NORTH;
gbc_txtLoanInterest.insets = new Insets(0, 0, 5, 0);
gbc_txtLoanInterest.fill = GridBagConstraints.HORIZONTAL;
gbc_txtLoanInterest.gridx = 1;
gbc_txtLoanInterest.gridy = 1;
mainPanel.add(txtLoanInterest, gbc_txtLoanInterest);
txtLoanInterest.setColumns(10);
JLabel lblLoanPeriod = new JLabel("Loan Period:");
GridBagConstraints gbc_lblLoanPeriod = new GridBagConstraints();
gbc_lblLoanPeriod.fill = GridBagConstraints.HORIZONTAL;
gbc_lblLoanPeriod.insets = new Insets(0, 0, 5, 5);
gbc_lblLoanPeriod.gridx = 0;
gbc_lblLoanPeriod.gridy = 2;
mainPanel.add(lblLoanPeriod, gbc_lblLoanPeriod);
txtLoanPeriod = new JTextField();
GridBagConstraints gbc_txtLoanPeriod = new GridBagConstraints();
gbc_txtLoanPeriod.gridwidth = 2;
gbc_txtLoanPeriod.anchor = GridBagConstraints.NORTH;
gbc_txtLoanPeriod.insets = new Insets(0, 0, 5, 0);
gbc_txtLoanPeriod.fill = GridBagConstraints.HORIZONTAL;
gbc_txtLoanPeriod.gridx = 1;
gbc_txtLoanPeriod.gridy = 2;
mainPanel.add(txtLoanPeriod, gbc_txtLoanPeriod);
txtLoanPeriod.setColumns(10);
JLabel lblMonthlyPayment = new JLabel("Monthly Payment:");
GridBagConstraints gbc_lblMonthlyPayment = new GridBagConstraints();
gbc_lblMonthlyPayment.fill = GridBagConstraints.HORIZONTAL;
gbc_lblMonthlyPayment.insets = new Insets(0, 0, 5, 5);
gbc_lblMonthlyPayment.gridx = 0;
gbc_lblMonthlyPayment.gridy = 3;
mainPanel.add(lblMonthlyPayment, gbc_lblMonthlyPayment);
txtMonthlyPament = new JTextField();
GridBagConstraints gbc_txtMonthlyPament = new GridBagConstraints();
gbc_txtMonthlyPament.gridwidth = 2;
gbc_txtMonthlyPament.insets = new Insets(0, 0, 5, 0);
gbc_txtMonthlyPament.anchor = GridBagConstraints.NORTH;
gbc_txtMonthlyPament.fill = GridBagConstraints.HORIZONTAL;
gbc_txtMonthlyPament.gridx = 1;
gbc_txtMonthlyPament.gridy = 3;
mainPanel.add(txtMonthlyPament, gbc_txtMonthlyPament);
txtMonthlyPament.setColumns(10);
JButton btnCalculate = new JButton("Calculate");
btnCalculate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
calculate();
}
private void calculate() {
//do the math here
txtResult.setText("Calculate pressed!");
}
});
JLabel lblResult = new JLabel("Result:");
GridBagConstraints gbc_lblResult = new GridBagConstraints();
gbc_lblResult.fill = GridBagConstraints.HORIZONTAL;
gbc_lblResult.insets = new Insets(0, 0, 0, 5);
gbc_lblResult.gridx = 0;
gbc_lblResult.gridy = 4;
mainPanel.add(lblResult, gbc_lblResult);
txtResult = new JTextField();
GridBagConstraints gbc_txtResult = new GridBagConstraints();
gbc_txtResult.insets = new Insets(0, 0, 0, 5);
gbc_txtResult.fill = GridBagConstraints.HORIZONTAL;
gbc_txtResult.gridx = 1;
gbc_txtResult.gridy = 4;
mainPanel.add(txtResult, gbc_txtResult);
txtResult.setColumns(10);
GridBagConstraints gbc_btnCalculate = new GridBagConstraints();
gbc_btnCalculate.gridx = 2;
gbc_btnCalculate.gridy = 4;
mainPanel.add(btnCalculate, gbc_btnCalculate);
}
private static final long serialVersionUID = 1L;
private JTextField txtLoanAmount;
private JTextField txtLoanInterest;
private JTextField txtLoanPeriod;
private JTextField txtMonthlyPament;
private JTextField txtResult;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GridExample g = new GridExample();
String text = "<html><h1 align='center'>Loan Program 1.0</h1>";
text = text + "This program lets you calculate the various aspects of loans <br />";
text = text + "If you are leaving a field empty then use 0 for its place <br />";
text = text + "<h1 align='center'>Text Fields To Enter</h1>";
text = text + "Monthly Payment: Enter values for: Loan Period, Loan Amount, and Loan Interest. Enter 0 for Monthly Payment. <br />";
text = text + "Loan Period: Enter Values for: Loan Amount, Loan Interest, and Monthly Payment. Enter 0 for Loan Period. <br />";
g.setVisible(true);
JOptionPane.showMessageDialog(g, new JLabel(text));
}
});
}
}
I'm trying to design a Mile to Nautical Mile calculator in Java.
I was able to create and run it okay through the console, but i'm having trouble learning how to do it in JFrames.
what im basically wanting to do is:
Have two text fields and a button, one text field miles and one for nautical miles, when you enter the amount into one then press the button the result will display in the other field.
I've pasted my code below
Not really sure what to do next
package Mile_Conversion;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class OwnWindow implements ActionListener{
public static void main(String[] args) {
MyJFrame();
}
public static void MyJFrame() {
//JLabel
JLabel start = new JLabel("Enter the amount below to calculate");
start.setBounds(/*x*/70, -65/*Y*/, 270, 150); // x, y, width, height x across, y down
JLabel milecon = new JLabel("Miles");
milecon.setBounds(154, 55, 50, 150);
JLabel nautcon = new JLabel("Nautical Miles");
nautcon.setBounds(135, -15, 150, 150);
//JTextField
JTextField miles = new JTextField();
miles.setBounds(100, 140, 150, 25);
JTextField nautical = new JTextField();
nautical.setBounds(100, 70, 150, 25);
double mile, nautmile;
/*
mile = nautmile * 0.868;
nautmile = mile * 1.150;
*/
//JButton
JButton convert = new JButton("Convert");
convert.setBounds(250, 200, 90, 25);
//JFrame
JFrame window = new JFrame("Milage Conversion");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(400, 300);
window.setVisible(true);
window.setLayout(null);
window.setResizable(false);
window.add(start);
window.add(miles);
window.add(nautical);
window.add(convert);
window.add(milecon);
window.add(nautcon);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Welcome to the wonderful world of variable fonts, resolutions and DPI, where what it looks like on your screen will never match any one elses (okay, that's an exaggeration, but it feels like it :P)
In this world, layout managers are you friend. They will save you many, many, many hours of frustration and torment.
I'd recommend you have a read through;
Using Layout Managers
A Visual Guide to Layout Managers
This is my take on what you are trying to do...
public class TestConvertDistance {
public static void main(String[] args) {
new TestConvertDistance();
}
public TestConvertDistance() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DistancePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class DistancePane extends JPanel {
private JLabel lblInstruct;
private JLabel lblMiles;
private JLabel lblNauticalMiles;
private JTextField fldMiles;
private JTextField fldNauticalMiles;
private JButton btnCalculate;
public DistancePane() {
lblInstruct = new JLabel("Enter the amount below to calculate");
lblMiles = new JLabel("Miles");
lblNauticalMiles = new JLabel("Nautical Miles");
fldMiles = new JTextField(8);
fldNauticalMiles = new JTextField(8);
btnCalculate = new JButton("Convert");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(lblInstruct, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = 1;
add(lblMiles, gbc);
gbc.gridy++;
add(lblNauticalMiles, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
add(fldMiles, gbc);
gbc.gridy++;
add(fldNauticalMiles, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btnCalculate, gbc);
btnCalculate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Do your calculation here...
}
});
}
}
}
Note, I've used GridBagLayout, this is one of the most powerful and complicated layout managers in the core API, so don't get worried if at first it seems confusion ;)
write your code for conversion inside actionPerformed method:
Take input from first JTextField miles
Parse it to int or float( as JTextFields getText() method returns String)
Do the conversion
set the converted value to the other JTextField nautical using nautical.setText(); method
Here is my version of it. It probably isn't perfect and doesn't have any exception handling:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class OwnWindow implements ActionListener
{
JLabel start;
JLabel milecon;
JLabel nautcon;
JTextField miles;
JTextField nautical;
JButton convert;
JFrame window;
double mile, nautmile;
public static void main(String[] args)
{
OwnWindow obj = new OwnWindow();
}
public OwnWindow()
{
start = new JLabel("Enter the amount below to calculate");
start.setBounds(/*x*/70, -65/*Y*/, 270, 150); // x, y, width, height x across, y down
milecon = new JLabel("Miles");
milecon.setBounds(154, 55, 50, 150);
nautcon = new JLabel("Nautical Miles");
nautcon.setBounds(135, -15, 150, 150);
miles = new JTextField();
miles.setBounds(100, 140, 150, 25);
nautical = new JTextField();
nautical.setBounds(100, 70, 150, 25);
convert = new JButton("Convert");
convert.setBounds(250, 200, 90, 25);
convert.addActionListener(this);
window = new JFrame("Milage Conversion");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(400, 300);
window.setVisible(true);
window.setLayout(null);
window.setResizable(false);
window.add(start);
window.add(miles);
window.add(nautical);
window.add(convert);
window.add(milecon);
window.add(nautcon);
}
#Override
public void actionPerformed(ActionEvent e)
{
String strNaut = nautical.getText();
String strMile = miles.getText();
//this means the user wants to convert nautical to normal
if(strNaut.length() > 0)
{
nautmile = Double.parseDouble(strNaut);
miles.setText(nautmile*0.868 + "");
}
else if(strMile.length() > 0)
{
mile = Double.parseDouble(strMile);
nautical.setText(mile*1.150 + "");
}
}
}