import java.awt.*; import java.awt.event.*; 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()); JLabel barLabel = new JLabel(); barLabel.setIcon(new BarIcon()); barLabel.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int mouseX = e.getX(); int mouseY = e.getY(); double max = a.stream().max(Double::compare).orElse(1.0); double barHeight = ICON_HEIGHT / (double) a.size(); // Find the nearest bar to the mouse click int index = (int) (mouseY / barHeight); if (index >= 0 && index < a.size()) { double newValue = max * mouseX / ICON_WIDTH; dataModel.update(index, newValue); } } }); add(barLabel); 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 class BarIcon implements 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.stream().max(Double::compare).orElse(1.0); double barHeight = getIconHeight() / (double) a.size(); int i = 0; for (Double value : a) { double barLength = getIconWidth() * value / max; Rectangle2D.Double rectangle = new Rectangle2D.Double( 0, barHeight * i, barLength, barHeight); i++; g2.fill(rectangle); } } } private ArrayList a; private DataModel dataModel; private static final int ICON_WIDTH = 200; private static final int ICON_HEIGHT = 200; }