FIRST AND PROBABLY FINAL COMMIT?!?!!?!?!?!?

This commit is contained in:
Libkyy
2022-05-25 16:57:51 +02:00
commit 373a4007ce
22 changed files with 1143 additions and 0 deletions

29
.gitignore vendored Normal file
View File

@@ -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

8
.idea/.gitignore generated vendored Normal file
View File

@@ -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

13
.idea/artifacts/ExtraShapes_jar.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<component name="ArtifactManager">
<artifact type="jar" name="ExtraShapes:jar">
<output-path>$PROJECT_DIR$/out/artifacts/ExtraShapes_jar</output-path>
<root id="archive" name="ExtraShapes.jar">
<element id="module-output" name="ExtraShapes" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/reflections/reflections/0.10.2/reflections-0.10.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/javassist/javassist/3.28.0-GA/javassist-3.28.0-GA.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar" path-in-jar="/" />
</root>
</artifact>
</component>

9
.idea/libraries/MORE_SHAPES.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="MORE_SHAPES">
<CLASSES>
<root url="jar://$PROJECT_DIR$/MORE_SHAPES.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

13
.idea/libraries/reflections.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="reflections" type="repository">
<properties maven-id="org.reflections:reflections:0.10.2" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/reflections/reflections/0.10.2/reflections-0.10.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/javassist/javassist/3.28.0-GA/javassist-3.28.0-GA.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

6
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17_PREVIEW" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/ExtraShapes.iml" filepath="$PROJECT_DIR$/ExtraShapes.iml" />
</modules>
</component>
</project>

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

29
ExtraShapes.iml Normal file
View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="reflections" level="project" />
<orderEntry type="module-library">
<library name="JUnit5.8.1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter/5.8.1/junit-jupiter-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.8.1/junit-jupiter-api-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.8.1/junit-platform-commons-1.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-params/5.8.1/junit-jupiter-params-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-engine/5.8.1/junit-jupiter-engine-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-engine/1.8.1/junit-platform-engine-1.8.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="MORE_SHAPES" level="project" />
</component>
</module>

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: DrawingApp.App

160
src/App.java Normal file
View File

@@ -0,0 +1,160 @@
import Shapes.Shape;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
public class App
{
public static JFrame frame;
public static void main(String[] args)
{
// Create a new frame
frame = new JFrame("Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setSize(900, 900);
// Create a new drawing board
DrawingBoard drawingBoard = new DrawingBoard();
drawingBoard.setEditPanel(frame);
//Create Shape Buttons
ArrayList<Button> shapeButtonList;
shapeButtonList = createShapeButtons(drawingBoard);
drawingBoard.setShapeButtons(shapeButtonList);
frame.add(drawingBoard, BorderLayout.CENTER);
// Create the buttons
Button undoButton = new Button("Undo");
undoButton.addActionListener(e -> drawingBoard.undo());
Button redoButton = new Button("Redo");
redoButton.addActionListener(e -> drawingBoard.redo());
Button restartButton = new Button("Restart");
restartButton.addActionListener(e -> drawingBoard.clearAll());
Button exitButton = new Button("Exit");
exitButton.addActionListener(e -> System.exit(0));
Button refreshButton = new Button("Refresh");
refreshButton.addActionListener(e -> drawingBoard.refresh(drawingBoard.getCanvas()));
Button installShape = new Button("Install Shape");
installShape.addActionListener(e ->
{
JDialog dialog = new JDialog(frame, "Install Shape", true);
JPanel panel = new JPanel();
JButton apply = new JButton("Apply");
JButton cancel = new JButton("Cancel");
JTextField shapeName = new JTextField(10);
apply.addActionListener(b ->{
drawingBoard.installPluginShape(Select_Class_From_Jar_file(shapeName.getText()));
drawingBoard.setShapeButtons(createShapeButtons(drawingBoard));
});
cancel.addActionListener(b -> dialog.dispose());
panel.add(new JLabel("Shape Name:"));
panel.add(shapeName);
panel.add(apply);
panel.add(cancel);
dialog.add(panel);
dialog.setSize(300, 300);
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
frame.repaint();
});
// Create a new panel for the edit buttons
Panel EditButtons = new Panel();
EditButtons.setLayout(new GridLayout(0, 2));
//Add buttons to panel
EditButtons.add(undoButton);
EditButtons.add(redoButton);
EditButtons.add(refreshButton);
EditButtons.add(restartButton);
EditButtons.add(installShape);
EditButtons.add(exitButton);
// Add the edit buttons to the frame
frame.add(EditButtons, BorderLayout.WEST);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static ArrayList<Button> createShapeButtons(DrawingBoard drawingBoard)
{
ArrayList<Class<? extends Shape>> supportedShapes = (ArrayList<Class<? extends Shape>>) drawingBoard.getSupportedShapes();
ArrayList<Button> buttons = new ArrayList<>();
for (Class<? extends Shape> shape : supportedShapes)
{
Button button = new Button(shape.getSimpleName());
button.addActionListener(e ->
{
try
{
Shape newShape = shape.getConstructor().newInstance();
newShape.setColor(drawingBoard.get_selected_color());
drawingBoard.ShapeForm(newShape, frame);
frame.update(frame.getGraphics());
drawingBoard.update(drawingBoard.getCanvas());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e1)
{
e1.printStackTrace();
}
drawingBoard.refresh(drawingBoard.getCanvas());
});
buttons.add(button);
}
return buttons;
}
public static Class<?extends Shape> LoadClassFromJar(String jarPath, String className)
{
try
{
URLClassLoader classLoader = new URLClassLoader(new URL[]{new File(jarPath).toURI().toURL()});
Class<?> cls = Class.forName(className, true, classLoader);
System.out.println(cls.getName());
return cls.asSubclass(Shape.class);
} catch (MalformedURLException | ClassNotFoundException e)
{
e.printStackTrace();
}
return null;
}
public static Class<? extends Shape> Select_Class_From_Jar_file(String classname)
{
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
fileChooser.setFileFilter(new FileNameExtensionFilter("Jar Files", "jar"));
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION)
{
File selectedFile = fileChooser.getSelectedFile();
System.out.println("Selected file: " + selectedFile.getAbsolutePath());
return LoadClassFromJar(selectedFile.getAbsolutePath(), classname);
}
return null;
}
}

268
src/DrawingBoard.java Normal file
View File

@@ -0,0 +1,268 @@
import Shapes.Shape;
import org.reflections.Reflections;
import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.*;
public class DrawingBoard extends Panel implements DrawingEngine
{
private final ArrayList<Shape> shapes;
private final JComboBox<String> color_selection;
public final JComboBox<Shape> shape_selection;
private final ArrayList<Class<? extends Shape>> supportedShapes;
private final Label canvas;
private final Panel ShapeButtons;
private final Panel EditPanel;
private final Stack<Shape> undoStack;
private final Stack<Shape> redoStack;
DrawingBoard()
{
super();
setLayout(new BorderLayout());
setVisible(true);
setBackground(Color.white);
shapes = new ArrayList<>();
canvas = new Label();
canvas.setSize(500, 500);
add(canvas, BorderLayout.CENTER);
ShapeButtons = new Panel(new GridLayout(1, 0));
undoStack = new Stack<>();
redoStack = new Stack<>();
Reflections reflections = new Reflections("DrawingApp");
Set<Class<? extends Shape>> ShapeSet = reflections.getSubTypesOf(Shape.class);
supportedShapes = new ArrayList<>(ShapeSet);
shape_selection = new JComboBox<>();
color_selection = new JComboBox<>();
color_selection.addItem("Black");
color_selection.addItem("Blue");
color_selection.addItem("Red");
color_selection.addItem("Green");
color_selection.addItem("Yellow");
color_selection.addItem("Orange");
color_selection.addItem("Pink");
color_selection.addItem("White");
EditPanel = new Panel(new GridLayout(0, 2));
}
public Graphics getCanvas()
{
return canvas.getGraphics();
}
//Create Label and TextField for each property of shape
public void ShapeForm(Shape shape, Frame frame)
{
JDialog dialog = new JDialog(frame, "Create " + shape.getClass().getSimpleName(), true);
Map<String, Double> properties = shape.getProperties();
Panel panel = new Panel();
panel.setLayout(new GridLayout(0, 2));
String[] keys = properties.keySet().toArray(new String[0]);
for (String key : keys)
{
Label label = new Label(key);
TextField textField = new TextField(properties.get(key).toString());
panel.add(label);
panel.add(textField);
}
Button apply = new Button("Apply");
Button cancel = new Button("Cancel");
cancel.addActionListener(e -> dialog.dispose());
apply.addActionListener(e ->
{
for (int i = 1; i < panel.getComponentCount(); i += 2)
{
if (panel.getComponent(i) instanceof TextField textField)
{
Label label = (Label) panel.getComponent(i - 1);
//pls edit this later ffs
shape.getProperties().put(label.getText(), Double.parseDouble(textField.getText()));
}
}
addShape(shape);
dialog.dispose();
shape.draw(getCanvas());
});
panel.add(apply);
panel.add(cancel);
panel.setVisible(true);
dialog.add(panel);
dialog.setSize(300, 300);
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public void undo()
{
if (!undoStack.isEmpty())
{
Shape shape = undoStack.pop();
shapes.remove(shape);
refresh(getCanvas());
redoStack.push(shape);
}
}
public void redo()
{
if (!redoStack.isEmpty())
{
Shape shape = redoStack.pop();
addShape(shape);
}
}
public void clearAll()
{
shapes.clear();
getCanvas().clearRect(0, 0, 50000, 50000);
refresh(getCanvas());
undoStack.clear();
redoStack.clear();
}
public void setShapeButtons(ArrayList<Button> buttons)
{
for (Button button : buttons)
{
ShapeButtons.add(button);
}
add(ShapeButtons, BorderLayout.NORTH);
}
public void setEditPanel(Frame frame)
{
Button Edit = new Button("Edit");
Edit.addActionListener(e ->
{
if (shape_selection.getSelectedItem() != null)
{
Shape shape = (Shape) shape_selection.getSelectedItem();
ShapeForm(shape, frame);
refresh(getCanvas());
}
});
Button Colorise = new Button("Colorise");
Colorise.addActionListener(e ->
{
if (shape_selection.getSelectedItem() != null)
{
Shape shape = (Shape) shape_selection.getSelectedItem();
shape.setColor(get_selected_color());
refresh(getCanvas());
}
});
Button Delete = new Button("Delete");
Delete.addActionListener(e ->
{
if (shape_selection.getSelectedItem() != null)
{
Shape shape = (Shape) shape_selection.getSelectedItem();
shapes.remove(shape);
refresh(getCanvas());
}
});
EditPanel.add(shape_selection);
EditPanel.add(color_selection);
EditPanel.add(Edit);
EditPanel.add(Colorise);
EditPanel.add(Delete);
add(EditPanel, BorderLayout.SOUTH);
}
public Shape get_selected_shape()
{
return shape_selection.getItemAt(shape_selection.getSelectedIndex());
}
public Color get_selected_color()
{
String color = (String) color_selection.getSelectedItem();
return switch (color)
{
case "Blue" -> Color.BLUE;
case "Red" -> Color.RED;
case "Green" -> Color.GREEN;
case "Yellow" -> Color.YELLOW;
case "Orange" -> Color.ORANGE;
case "Pink" -> Color.PINK;
case "White" -> Color.WHITE;
default -> Color.BLACK;
};
}
@Override
public void addShape(Shape shape)
{
shapes.add(shape);
shape.draw(getCanvas());
shape_selection.addItem(shape);
undoStack.push(shape);
canvas.repaint();
}
@Override
public void removeShape(Shape shape)
{
shapes.remove(shape);
shape_selection.removeItem(shape);
redoStack.push(shape);
refresh(getCanvas());
}
public void colorShape(Shape shape, Color color)
{
shape.setColor(color);
shape.draw(getCanvas());
refresh(getCanvas());
}
@Override
public Shape[] getShapes()
{
Shape[] shapes = new Shape[this.shapes.size()];
for (int i = 0; i < this.shapes.size(); i++)
{
shapes[i] = this.shapes.get(i);
}
return shapes;
}
@Override
public void refresh(Graphics canvas)
{
//clear canvas
canvas.clearRect(0, 0, 500000, 50000);
//draw all shapes
for (Shape shape : shapes)
{
shape.draw(canvas);
this.canvas.repaint();
}
}
@Override
public List<Class<? extends Shape>> getSupportedShapes()
{
return supportedShapes;
}
@Override
public void installPluginShape(Class<? extends Shape> shapeClass)
{
supportedShapes.add(shapeClass);
}
}

36
src/DrawingBoardTest.java Normal file
View File

@@ -0,0 +1,36 @@
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class DrawingBoardTest
{
@Test
void getShapes()
{
DrawingBoard drawingBoard = new DrawingBoard();
assertEquals(0, drawingBoard.getShapes().length);
// drawingBoard.addShape(new Line());
assertEquals(1, drawingBoard.getShapes().length);
}
@Test
void getSupportedShapes()
{
DrawingBoard drawingBoard = new DrawingBoard();
assertEquals(4, drawingBoard.getSupportedShapes().size());
System.out.println(drawingBoard.getSupportedShapes());
}
@Test
void installShapes()
{
DrawingBoard drawingBoard = new DrawingBoard();
assertEquals(4, drawingBoard.getSupportedShapes().size());
assertEquals(6, drawingBoard.getSupportedShapes().size());
}
@Test
void installPluginShape()
{
}
}

22
src/DrawingEngine.java Normal file
View File

@@ -0,0 +1,22 @@
import Shapes.Shape;
public interface DrawingEngine
{
/* manage shapes objects */
void addShape(Shape shape);
void removeShape(Shape shape);
/* return the created shapes objects */
Shape[] getShapes();
/* redraw all shapes on the canvas */
void refresh(java.awt.Graphics canvas);
/* return the classes (types) of supported shapes that can
* be dynamically loaded at runtime (see Part 3) */
java.util.List<Class<? extends Shape>> getSupportedShapes();
/* add to the supported shapes the new shape class (see Part 3) */
void installPluginShape(Class<? extends Shape> shapeClass);
}

3
src/META-INF/MANIFEST.MF Normal file
View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: App

106
src/Shapes/Circle.java Normal file
View File

@@ -0,0 +1,106 @@
package DrawingApp;
import Shapes.Shape;
import java.awt.*;
import java.util.Map;
public class Circle implements Shape
{
private Point position;
private Map<String, Double> properties;
private Color color;
private Color fillColor;
public Circle()
{
position = new Point(0,0);
properties = new java.util.HashMap<String, Double>();
color = Color.BLACK;
fillColor = Color.BLACK;
properties.put("x", 0.0);
properties.put("y", 0.0);
properties.put("radius", 100.0);
}
public Circle(Color color, Color fillColor, int x, int y, int radius)
{
this.position = new Point(x,y);
properties = new java.util.HashMap<String, Double>();
properties.put("x", (double) x);
properties.put("y", (double) y);
properties.put("radius", (double) radius);
this.color = color;
this.fillColor = fillColor;
}
public void setPosition(Point position)
{
this.position = position;
}
public Point getPosition()
{
return position;
}
public void setProperties(Map<String, Double> properties)
{
this.properties = properties;
}
public Map<String, Double> getProperties()
{
return properties;
}
public void setColor(Color color)
{
this.color = color;
}
@Override
public Color getColor()
{
return color;
}
@Override
public void setFillColor(Color color)
{
this.fillColor = color;
}
@Override
public Color getFillColor()
{
return fillColor;
}
@Override
public void draw(Graphics canvas)
{
canvas.setColor(color);
double x = properties.get("x");
double y = properties.get("y");
double radius = properties.get("radius");
canvas.drawOval((int) x, (int) y, (int) radius, (int) radius);
}
@Override
public Object clone() throws CloneNotSupportedException
{
Circle clone = new Circle();
clone.setPosition(position);
clone.setProperties(properties);
clone.setColor(color);
clone.setFillColor(fillColor);
return clone;
}
//To STring
@Override
public String toString()
{
return "Circle";
}
}

101
src/Shapes/Line.java Normal file
View File

@@ -0,0 +1,101 @@
package DrawingApp;
import Shapes.Shape;
import java.awt.*;
import java.util.Map;
public class Line implements Shape
{
private Point position;
private Map<String, Double> properties;
private Color color;
private Color fillColor;
public Line()
{
position = new Point(0,0);
properties = new java.util.HashMap<String, Double>();
color = Color.BLACK;
fillColor = Color.BLACK;
properties.put("x1", 0.0);
properties.put("y1", 0.0);
properties.put("x2", 100.0);
properties.put("y2", 100.0);
}
public Line(Color color, Color fillColor, int x, int y, int x2, int y2)
{
this.position = new Point(x,y);
properties = new java.util.HashMap<String, Double>();
properties.put("x1", (double) x);
properties.put("y1", (double) y);
properties.put("x2", (double) x2);
properties.put("y2", (double) y2);
this.color = color;
this.fillColor = fillColor;
}
public void setPosition(Point position)
{
this.position = position;
}
public Point getPosition()
{
return position;
}
public void setProperties(Map<String, Double> properties)
{
this.properties = properties;
}
public Map<String, Double> getProperties()
{
return properties;
}
public void setColor(Color color)
{
this.color = color;
}
public Color getColor()
{
return color;
}
public void setFillColor(Color fillColor)
{
this.fillColor = fillColor;
}
public Color getFillColor()
{
return fillColor;
}
@Override
public void draw(Graphics canvas)
{
canvas.setColor(color);
double x1 = properties.get("x1");
double y1 = properties.get("y1");
double x2 = properties.get("x2");
double y2 = properties.get("y2");
canvas.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
}
@Override
public Object clone() throws CloneNotSupportedException
{
return this;
}
//To String
@Override
public String toString()
{
return "Line";
}
}

111
src/Shapes/Rectangle.java Normal file
View File

@@ -0,0 +1,111 @@
package DrawingApp;
import Shapes.Shape;
import java.awt.*;
import java.util.Map;
public class Rectangle implements Shape
{
protected Point position;
private Map<String, Double> properties;
protected Color color;
protected Color fillColor;
public Rectangle()
{
position = new Point(0,0);
properties = new java.util.HashMap<String, Double>();
color = Color.BLACK;
fillColor = Color.BLACK;
properties.put("x", 10.0);
properties.put("y", 10.0);
properties.put("width", 100.0);
properties.put("height", 100.0);
position = new Point(0,0);
}
public Rectangle(Color color, Color fillColor, int x, int y, int width, int height)
{
this.position = new Point(x,y);
properties = new java.util.HashMap<String, Double>();
properties.put("x", (double) x);
properties.put("y", (double) y);
properties.put("width", (double) width);
properties.put("height", (double) height);
this.color = color;
this.fillColor = fillColor;
position = new Point(x,y);
}
@Override
public void setPosition(Point position)
{
this.position = position;
}
@Override
public Point getPosition()
{
return position;
}
@Override
public void setProperties(Map<String, Double> properties)
{
this.properties = properties;
}
@Override
public Map<String, Double> getProperties()
{
return properties;
}
@Override
public void setColor(Color color)
{
this.color = color;
}
@Override
public Color getColor()
{
return color;
}
@Override
public void setFillColor(Color color)
{
this.fillColor = color;
}
@Override
public Color getFillColor()
{
return fillColor;
}
@Override
public void draw(Graphics canvas)
{
canvas.setColor(color);
double x = properties.get("x");
double y = properties.get("y");
double width = properties.get("width");
double height = properties.get("height");
canvas.drawRect((int) x, (int) y, (int) width, (int) height);
}
@Override
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
//To string
@Override
public String toString()
{
return "Rectangle";
}
}

29
src/Shapes/Shape.java Normal file
View File

@@ -0,0 +1,29 @@
package Shapes;
public interface Shape
{
/* set position */
void setPosition(java.awt.Point position);
java.awt.Point getPosition();
/* update shape specific properties (e.g., radius) */
void setProperties(java.util.Map<String, Double> properties);
java.util.Map<String, Double> getProperties();
/* colorize */
void setColor(java.awt.Color color);
java.awt.Color getColor();
void setFillColor(java.awt.Color color);
java.awt.Color getFillColor();
/* redraw the shape on the canvas */
void draw(java.awt.Graphics canvas);
/* create a deep clone of the shape */
Object clone() throws CloneNotSupportedException;
}

11
src/Shapes/Shapes.iml Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" packagePrefix="DrawingApp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

48
src/Shapes/Square.java Normal file
View File

@@ -0,0 +1,48 @@
package DrawingApp;
import java.awt.*;
import java.util.Map;
public class Square extends DrawingApp.Rectangle
{
private Map<String,Double> properties;
public Square(Color color, Color fillColor, int x, int y, int Length) {
properties = new java.util.HashMap<String, Double>();
properties.put("x", (double) x);
properties.put("y", (double) y);
properties.put("Length", (double) Length);
position = new Point(x,y);
this.color = color;
this.fillColor = fillColor;
}
public Square() {
this(Color.BLACK, Color.BLACK, 0, 0, 100);
}
public void draw(Graphics canvas)
{
canvas.setColor(color);
double x = properties.get("x");
double y = properties.get("y");
double Length = properties.get("Length");
canvas.drawRect((int) x, (int) y, (int) Length, (int) Length);
}
@Override
public void setProperties(Map<String, Double> properties)
{
this.properties = properties;
}
public Map<String,Double> getProperties()
{
return properties;
}
@Override
public String toString()
{
return "Square";
}
}