package ovh.gasser.newshapes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ovh.gasser.newshapes.attributes.ColorAttributes; import ovh.gasser.newshapes.shapes.*; import ovh.gasser.newshapes.shapes.Shape; import ovh.gasser.newshapes.ui.ShapesView; import ovh.gasser.newshapes.ui.listeners.MenuAddListener; import ovh.gasser.newshapes.ui.listeners.MenuEditListener; import javax.swing.*; import java.awt.*; import java.io.FileNotFoundException; public class App { private final static Logger logger = LoggerFactory.getLogger(App.class); public static final Dimension WIN_SIZE = new Dimension(800, 600); private SCollection model; private JCheckBoxMenuItem editFill; private JCheckBoxMenuItem editBorder; private App() throws HeadlessException { final JFrame frame = new JFrame("Reactive shapes"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); buildModel(); final ShapesView view = new ShapesView(this.model); view.setPreferredSize(WIN_SIZE); view.setFocusable(true); var res = view.requestFocusInWindow(); assert res; frame.getContentPane().add(view, BorderLayout.CENTER); frame.setContentPane(view); frame.pack(); frame.setVisible(true); this.buildMenuBar(frame, view); view.addSelectionChangeListener(this::updateMenuState); } private void buildModel() { model = SCollection.of( STriangle.create(200, 200, 50, Color.YELLOW, Color.BLACK), SRectangle.create(10, 10, 40, 60, Color.RED), SRectangle.create(70, 10, 40, 60), SCollection.of( SRectangle.create(100, 200, 40, 60, Color.MAGENTA), SRectangle.create(150, 200, 40, 60, Color.MAGENTA), SCircle.create(200, 250, 30) ) ); } private void buildMenuBar(JFrame frame, ShapesView sview) { var menubar = new JMenuBar(); // About JMenu helpMenu = new JMenu("Help"); JMenuItem aboutItem = new JMenuItem("About"); aboutItem.addActionListener(evt -> JOptionPane.showMessageDialog(frame, "This project was created by Alexandre Colicchio and Thibaud Gasser", "About this project", JOptionPane.INFORMATION_MESSAGE)); helpMenu.add(aboutItem); menubar.add(buildFileMenu(sview)); menubar.add(buildEditMenu(sview)); menubar.add(helpMenu); frame.setJMenuBar(menubar); } private JMenu buildFileMenu(ShapesView sview) { JMenu menuFile = new JMenu("File"); JMenuItem addRectItem = new JMenuItem("Add SRectangle"); JMenuItem addCircleItem = new JMenuItem("Add SCircle"); JMenuItem addTextItem = new JMenuItem("Add Text"); JMenuItem htmlExportItem = new JMenuItem("Export to HTML"); JMenuItem svgExportItem = new JMenuItem("Export to SVG"); JMenuItem exitItem = new JMenuItem("Exit"); addRectItem.addActionListener(new MenuAddListener("SRectangle", model, sview)); addCircleItem.addActionListener(new MenuAddListener("SCircle", model, sview)); addTextItem.addActionListener(evt -> sview.getController().enterTextMode()); htmlExportItem.addActionListener(evt -> { try { new HTMLExporter(model).export(); } catch (FileNotFoundException e) { logger.error("Could not export as html: {}", e.getMessage()); } }); svgExportItem.addActionListener(evt -> { try { new SVGExporter(model).export(); } catch (FileNotFoundException e) { logger.error("Could not export as html: {}", e.getMessage()); } }); exitItem.addActionListener(evt -> System.exit(0)); menuFile.add(addRectItem); menuFile.add(addCircleItem); menuFile.add(addTextItem); menuFile.addSeparator(); menuFile.add(htmlExportItem); menuFile.add(svgExportItem); menuFile.add(exitItem); return menuFile; } private JMenu buildEditMenu(ShapesView sview) { MenuEditListener editListener = new MenuEditListener(model, sview, sview.getController()); JMenu menuEdit = new JMenu("Edit"); JMenuItem editColor = new JMenuItem("Change color"); JMenuItem editBorderColor = new JMenuItem("Change border color"); JMenuItem deleteItem = new JMenuItem("Delete"); editFill = new JCheckBoxMenuItem("Fill Shape"); editBorder = new JCheckBoxMenuItem("Draw border"); editColor.addActionListener(editListener); editBorderColor.addActionListener(editListener); deleteItem.addActionListener(editListener); editFill.addActionListener(editListener); editBorder.addActionListener(editListener); menuEdit.add(editColor); menuEdit.add(editBorderColor); menuEdit.add(deleteItem); menuEdit.addSeparator(); menuEdit.add(editBorder); menuEdit.add(editFill); return menuEdit; } private void updateMenuState(Iterable selectedShapes) { boolean hasToggleableShapes = false; boolean allFilled = true; boolean allStroked = true; for (Shape s : selectedShapes) { if (s instanceof SText) { continue; } ColorAttributes attrs = (ColorAttributes) s.getAttributes(ColorAttributes.ID); if (attrs != null) { hasToggleableShapes = true; allFilled = allFilled && attrs.filled; allStroked = allStroked && attrs.stroked; } } updateMenuItem(editFill, hasToggleableShapes, allFilled); updateMenuItem(editBorder, hasToggleableShapes, allStroked); } private void updateMenuItem(JCheckBoxMenuItem menuItem, boolean hasAttributes, boolean allSelected) { if (!hasAttributes) { menuItem.setSelected(false); menuItem.setEnabled(false); } else { menuItem.setSelected(allSelected); menuItem.setEnabled(true); } } public static void main(String[] args) { SwingUtilities.invokeLater(App::new); } }