I'm relatively new to OOP and learning. I'm stuck in figuring out how do I possibly change the contents of my pane.
What I want to happen is If I click a different unit, the contents of the two pane would be changed according to the unit I chose.
I only coded the conversions for length and temperature. I'm leaving the rest as an exercise for the OP.
Explanation
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section.
When I create a Swing GUI, I use the model-view-controller (MVC) pattern. This pattern allows me to separate my concerns and focus on one part of the application at a time.
The model is the most important part of any Swing application. A good model makes coding the view and the controllers so much easier.
- A Swing model is made up of one or more plain Java getter/setter classes.
- A Swing view is made up of one
JFrame
and as manyJPanels
andJDialogs
as necessary. - A Swing controller is an
Action
orListener
that modifies the model and updates the view.
A Swing application usually has multiple controller classes.
Model
I created two model classes for this application.
The Measurement
class holds a text String, a multiplier, and an adder.
Let's take the formulas for temperature conversion.
f = (c * 9/5) 32
c = (f - 32) / 9/5
The general formula for any measurement conversion is
to value = (from value * multiplier) adder
So, for the lengths, I converted the from value to millimeters and converted millimeters to the to value. I did a similar thing for the temperatures, where I converted the from value to celsius and converted celsius to the to value.
This way, I cut down on the code necessary to do the conversions. All the OP has to do is plug in the rest of the multipliers and adders in the UnitConversionModel
class.
The UnitConversionModel
class holds a Map
with a String
key and a List<Measurement>
object. This Map
allows me to easily fill the JComboBoxes
and gives me the values for the conversions.
View
I generated a view based loosely on the OP's pictures. The model made constructing the view simpler.
Controller
I coded two controller classes.
The ComboBoxListener
class fills in the from conversion units and the to conversion units in the conversion units JComboBoxes
.
The ButtonListener
class does the unit conversion.
Code
Here's the complete runnable code. I made the additional classes inner classes so I could post the code as one block.
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.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class UnitConversionTool implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new UnitConversionTool());
}
private JComboBox<Measurement> fromMeasurementComboBox,
toMeasurementComboBox;
private JComboBox<String> measurementTypeComboBox;
private JTextField fromMeasurementField, toMeasurementField;
private UnitConversionModel model;
public UnitConversionTool() {
this.model = new UnitConversionModel();
}
@Override
public void run() {
JFrame frame = new JFrame("Unit Conversion Tool");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
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.NONE;
gbc.insets = new Insets(0, 5, 5, 5);
String[] measurementTypes = model.getMeasurementTypes();
gbc.gridwidth = 2;
gbc.gridx = 0;
gbc.gridy = 0;
measurementTypeComboBox = new JComboBox<>(measurementTypes);
String measurementType = measurementTypes[measurementTypes.length - 1];
measurementTypeComboBox.setSelectedItem(measurementType);
measurementTypeComboBox
.addActionListener(new ComboBoxListener(this, model));
panel.add(measurementTypeComboBox, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 1;
gbc.gridy ;
gbc.weightx = 1.0;
panel.add(new JLabel("From"), gbc);
Measurement[] measurementUnits = model
.getMeasurementList(measurementType);
gbc.gridx ;
fromMeasurementComboBox = new JComboBox<>(measurementUnits);
panel.add(fromMeasurementComboBox, gbc);
gbc.gridx ;
fromMeasurementField = new JTextField(10);
panel.add(fromMeasurementField, gbc);
gbc.gridx ;
panel.add(new JLabel("to"), gbc);
gbc.gridx ;
toMeasurementComboBox = new JComboBox<>(measurementUnits);
panel.add(toMeasurementComboBox, gbc);
gbc.gridx ;
toMeasurementField = new JTextField(10);
toMeasurementField.setEditable(false);
panel.add(toMeasurementField, gbc);
gbc.gridwidth = 6;
gbc.gridx = 0;
gbc.gridy ;
JButton button = new JButton("Convert");
button.addActionListener(new ButtonListener(this, model));
panel.add(button, gbc);
return panel;
}
public JComboBox<Measurement> getFromMeasurementComboBox() {
return fromMeasurementComboBox;
}
public JComboBox<Measurement> getToMeasurementComboBox() {
return toMeasurementComboBox;
}
public JComboBox<String> getMeasurementTypeComboBox() {
return measurementTypeComboBox;
}
public JTextField getFromMeasurementField() {
return fromMeasurementField;
}
public JTextField getToMeasurementField() {
return toMeasurementField;
}
public class ComboBoxListener implements ActionListener {
private final UnitConversionTool view;
private final UnitConversionModel model;
public ComboBoxListener(UnitConversionTool view,
UnitConversionModel model) {
this.view = view;
this.model = model;
}
@Override
public void actionPerformed(ActionEvent event) {
String selectedMeasurementType = (String) view
.getMeasurementTypeComboBox().getSelectedItem();
Measurement[] measurementUnits = model
.getMeasurementList(selectedMeasurementType);
int count = view.getFromMeasurementComboBox().getItemCount();
for (int index = count - 1; index >= 0; index--) {
view.getFromMeasurementComboBox().removeItemAt(index);
view.getToMeasurementComboBox().removeItemAt(index);
}
for (Measurement m : measurementUnits) {
view.getFromMeasurementComboBox().addItem(m);
view.getToMeasurementComboBox().addItem(m);
}
}
}
public class ButtonListener implements ActionListener {
private final UnitConversionTool view;
private final UnitConversionModel model;
public ButtonListener(UnitConversionTool view,
UnitConversionModel model) {
this.view = view;
this.model = model;
}
@Override
public void actionPerformed(ActionEvent event) {
Measurement fromMeasurement = (Measurement) view
.getFromMeasurementComboBox().getSelectedItem();
Measurement toMeasurement = (Measurement) view
.getToMeasurementComboBox().getSelectedItem();
double fromValue = Double
.valueOf(view.getFromMeasurementField().getText());
double toValue = (fromValue fromMeasurement.getAdder())
* fromMeasurement.getMultiplier();
toValue = toValue / toMeasurement.getMultiplier()
- toMeasurement.getAdder();
String text = String.format("%.2f", toValue);
view.getToMeasurementField().setText(text);
}
}
public class UnitConversionModel {
private final Map<String, List<Measurement>> measurementMap;
private final Measurement[] lengthMeasurements = {
new Measurement("meter", 1000, 0),
new Measurement("kilometer", 1_000_000, 0),
new Measurement("centimeter", 10, 0),
new Measurement("millimeter", 1, 0),
new Measurement("mile", 1.609344e 6, 0),
new Measurement("yard", 914.4, 0),
new Measurement("foot", 304.8, 0) };
private final Measurement[] temperatureMeasurements = {
new Measurement("celsius", 1, 0),
new Measurement("kelvin", 1, -273.15),
new Measurement("fahrenheit", 5.0 / 9.0, -32) };
private final Measurement[] areaMeasurements = {
new Measurement("acre", 0, 0), new Measurement("hectare", 0, 0),
new Measurement("sq mile", 0, 0),
new Measurement("sq yard", 0, 0),
new Measurement("sq foot", 0, 0),
new Measurement("sq inch", 0, 0) };
private final Measurement[] volumeMeasurements = {
new Measurement("liter", 0, 0),
new Measurement("milliliter", 0, 0),
new Measurement("gallon", 0, 0), new Measurement("quart", 0, 0),
new Measurement("pint", 0, 0), new Measurement("cup", 0, 0),
new Measurement("fluid ounce", 0, 0) };
private final Measurement[] weightMeasurements = {
new Measurement("gram", 0, 0),
new Measurement("kilogram", 0, 0),
new Measurement("milligram", 0, 0),
new Measurement("metric ton", 0, 0),
new Measurement("pound", 0, 0), new Measurement("ounce", 0, 0),
new Measurement("carat", 0, 0) };
private final Measurement[] timeMeasurements = {
new Measurement("second", 0, 0),
new Measurement("millisecond", 0, 0),
new Measurement("minute", 0, 0), new Measurement("hour", 0, 0),
new Measurement("day", 0, 0), new Measurement("week", 0, 0),
new Measurement("month", 0, 0), new Measurement("year", 0, 0) };
private final String[] measurementTypes = { "Length", "Temperature",
"Area", "Volume", "Weight", "Time" };
private final Measurement[][] measurements = { lengthMeasurements,
temperatureMeasurements, areaMeasurements, volumeMeasurements,
weightMeasurements, timeMeasurements };
public UnitConversionModel() {
this.measurementMap = new LinkedHashMap<>();
for (int index = 0; index < measurementTypes.length; index ) {
String s = measurementTypes[index];
Measurement[] measurementUnits = measurements[index];
List<Measurement> measurementList = new ArrayList<>();
for (Measurement m : measurementUnits) {
measurementList.add(m);
}
measurementMap.put(s, measurementList);
}
}
public String[] getMeasurementTypes() {
return measurementTypes;
}
public Measurement[] getMeasurementList(String measurement) {
List<Measurement> measurementList = measurementMap.get(measurement);
return measurementList
.toArray(new Measurement[measurementList.size()]);
}
}
public class Measurement {
private final double adder, multiplier;
private final String text;
public Measurement(String text, double multiplier, double adder) {
this.text = text;
this.multiplier = multiplier;
this.adder = adder;
}
public double getAdder() {
return adder;
}
public double getMultiplier() {
return multiplier;
}
@Override
public String toString() {
return text;
}
}
}
CodePudding user response:
I got it working by adding this code I found from a similar post:
c3 = new JComboBox<>(choices);
c.add(c3);
choose = new JComboBox<>(choicelen);
c.add(choose);
choose1 = new JComboBox<>(choicelen1);
c.add(choose1);
c3.addActionListener(new Listener());
class Listener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (c3.getSelectedItem().equals("Length")) {
choose.setModel(new JComboBox<>(choicelen).getModel());
choose1.setModel(new JComboBox<>(choicelen1).getModel());
}
else if (c3.getSelectedItem().equals("Temperature")) {
choose.setModel(new JComboBox<>(choicetem).getModel());
choose1.setModel(new JComboBox<>(choicetem1).getModel());
}
else if (c3.getSelectedItem().equals("Area")) {
choose.setModel(new JComboBox<>(choicearea).getModel());
choose1.setModel(new JComboBox<>(choicearea1).getModel());
}
else if (c3.getSelectedItem().equals("Volume")) {
choose.setModel(new JComboBox<>(choicevol).getModel());
choose1.setModel(new JComboBox<>(choicevol1).getModel());
}
else if (c3.getSelectedItem().equals("Weight")) {
choose.setModel(new JComboBox<>(choicewt).getModel());
choose1.setModel(new JComboBox<>(choicewt1).getModel());
}
else if (c3.getSelectedItem().equals("Time")) {
choose.setModel(new JComboBox<>(choicetime).getModel());
choose1.setModel(new JComboBox<>(choicetime1).getModel());
}
}
}
Thank you guys!