diff --git a/midterm2/.gitignore b/midterm2/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/midterm2/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/midterm2/.idea/.gitignore b/midterm2/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/midterm2/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/midterm2/.idea/inspectionProfiles/Project_Default.xml b/midterm2/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/midterm2/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/midterm2/.idea/misc.xml b/midterm2/.idea/misc.xml new file mode 100644 index 0000000..81a8e88 --- /dev/null +++ b/midterm2/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/midterm2/.idea/modules.xml b/midterm2/.idea/modules.xml new file mode 100644 index 0000000..058c6f7 --- /dev/null +++ b/midterm2/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/midterm2/.idea/vcs.xml b/midterm2/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/midterm2/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/midterm2/midterm2.iml b/midterm2/midterm2.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/midterm2/midterm2.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/midterm2/src/BarFrame.java b/midterm2/src/BarFrame.java new file mode 100644 index 0000000..cafca04 --- /dev/null +++ b/midterm2/src/BarFrame.java @@ -0,0 +1,83 @@ +import java.awt.*; +import java.awt.geom.*; +import javax.swing.*; +import javax.swing.event.*; +import java.util.*; + +/** + * A class that implements an Observer object that displays a barchart view of + * a data model. + */ +public class BarFrame extends JFrame implements ChangeListener { + /** + * Constructs a BarFrame object + * + * @param dataModel the data that is displayed in the barchart + */ + public BarFrame(DataModel dataModel) { + this.dataModel = dataModel; + a = dataModel.getData(); + + setLocation(0, 200); + setLayout(new BorderLayout()); + + Icon barIcon = new Icon() { + public int getIconWidth() { + return ICON_WIDTH; + } + + public int getIconHeight() { + return ICON_HEIGHT; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Graphics2D g2 = (Graphics2D) g; + + g2.setColor(Color.red); + + double max = (a.get(0)).doubleValue(); + for (Double v : a) { + double val = v.doubleValue(); + if (val > max) + max = val; + } + + double barHeight = getIconHeight() / a.size(); + + int i = 0; + for (Double v : a) { + double value = v.doubleValue(); + + double barLength = getIconWidth() * value / max; + + Rectangle2D.Double rectangle = new Rectangle2D.Double + (0, barHeight * i, barLength, barHeight); + i++; + g2.fill(rectangle); + } + } + }; + + add(new JLabel(barIcon)); + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + pack(); + setVisible(true); + } + + /** + * Called when the data in the model is changed. + * + * @param e the event representing the change + */ + public void stateChanged(ChangeEvent e) { + a = dataModel.getData(); + repaint(); + } + + private ArrayList a; + private DataModel dataModel; + + private static final int ICON_WIDTH = 200; + private static final int ICON_HEIGHT = 200; +} diff --git a/midterm2/src/DataModel.java b/midterm2/src/DataModel.java new file mode 100644 index 0000000..9df4820 --- /dev/null +++ b/midterm2/src/DataModel.java @@ -0,0 +1,51 @@ +import java.util.ArrayList; +import javax.swing.event.*; + +/** + * A Subject class for the observer pattern. + */ +public class DataModel { + /** + * Constructs a DataModel object + * + * @param d the data to model + */ + public DataModel(ArrayList d) { + data = d; + listeners = new ArrayList(); + } + + /** + * Constructs a DataModel object + * + * @return the data in an ArrayList + */ + public ArrayList getData() { + return (ArrayList) (data.clone()); + } + + /** + * Attach a listener to the Model + * + * @param c the listener + */ + public void attach(ChangeListener c) { + listeners.add(c); + } + + /** + * Change the data in the model at a particular location + * + * @param location the index of the field to change + * @param value the new value + */ + public void update(int location, double value) { + data.set(location, new Double(value)); + for (ChangeListener l : listeners) { + l.stateChanged(new ChangeEvent(this)); + } + } + + ArrayList data; + ArrayList listeners; +} diff --git a/midterm2/src/Main.java b/midterm2/src/Main.java new file mode 100644 index 0000000..8427850 --- /dev/null +++ b/midterm2/src/Main.java @@ -0,0 +1,14 @@ +/** + * Write a program that contains two frames, one with a column of text fields + * containing numbers, and another that draws a bar graph showing the values of + * the numbers. When the user edits one of the numbers, the graph should be + * redrawn. Use the observer pattern. Store the data in a model. Attach the graph + * view as a listener. When a number is updated, the number view should update the + * model, and the model should tell the graph view that a change has occured. As a + * result, the graph view should repaint itself. + */ +public class Main { + public static void main(String[] args) { + + } +} diff --git a/midterm2/src/ObserverTester.java b/midterm2/src/ObserverTester.java new file mode 100644 index 0000000..8ad17e0 --- /dev/null +++ b/midterm2/src/ObserverTester.java @@ -0,0 +1,28 @@ +import java.util.ArrayList; + +/** + * A class for testing an implementation of the Observer pattern. + */ +public class ObserverTester { + /** + * Creates a DataModel and attaches barchart and textfield listeners + * + * @param args unused + */ + public static void main(String[] args) { + ArrayList data = new ArrayList(); + + data.add(33.0); + data.add(44.0); + data.add(22.0); + data.add(22.0); + + DataModel model = new DataModel(data); + + TextFrame frame = new TextFrame(model); + + BarFrame barFrame = new BarFrame(model); + + model.attach(barFrame); + } +} diff --git a/midterm2/src/TextFrame.java b/midterm2/src/TextFrame.java new file mode 100644 index 0000000..0f5ead7 --- /dev/null +++ b/midterm2/src/TextFrame.java @@ -0,0 +1,61 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.ArrayList; + +/** + * A class for displaying the model as a column of textfields in a frame. + */ +public class TextFrame extends JFrame { + /** + * Constructs a JFrame that contains the textfields containing the data + * in the model. + * + * @param d the model to display + */ + public TextFrame(DataModel d) { + dataModel = d; + + final Container contentPane = this.getContentPane(); + setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + + ArrayList a = dataModel.getData(); + fieldList = new JTextField[a.size()]; + + // A listener for action events in the text fields + ActionListener l = new ActionListener() { + public void actionPerformed(ActionEvent e) { + // Figure out which field generated the event + JTextField c = (JTextField) e.getSource(); + int i = 0; + int count = fieldList.length; + while (i < count && fieldList[i] != c) + i++; + + String text = c.getText().trim(); + + try { + double value = Double.parseDouble(text); + dataModel.update(i, value); + } catch (Exception exc) { + c.setText("Error. No update"); + } + } + }; + + final int FIELD_WIDTH = 11; + for (int i = 0; i < a.size(); i++) { + JTextField textField = new JTextField(a.get(i).toString(), FIELD_WIDTH); + textField.addActionListener(l); + add(textField); + fieldList[i] = textField; + } + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + pack(); + setVisible(true); + } + + DataModel dataModel; + JTextField[] fieldList; +}