Files
new-shapes/src/main/java/ovh/gasser/newshapes/App.java
2026-03-19 21:45:54 +01:00

167 lines
6.2 KiB
Java

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<Shape> 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);
}
}