├── .classpath ├── .project ├── .settings └── org.eclipse.jdt.core.prefs ├── LICENSE ├── README.md └── src └── com └── thecherno └── app ├── ExampleLayer.java ├── Main.java ├── core ├── Screen.java └── Window.java ├── events ├── Event.java ├── EventDispatcher.java ├── EventHandler.java ├── EventListener.java └── types │ ├── MouseButtonEvent.java │ ├── MouseMovedEvent.java │ ├── MousePressedEvent.java │ └── MouseReleasedEvent.java └── layers └── Layer.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Events 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.8 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.8 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EventSystem 2 | Basic event system with dispatcher for the following video tutorial. A tutorial can be found here: https://youtu.be/yD47_hq75q0 3 | -------------------------------------------------------------------------------- /src/com/thecherno/app/ExampleLayer.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.Point; 6 | import java.awt.Rectangle; 7 | import java.util.Random; 8 | 9 | import com.thecherno.app.events.Event; 10 | import com.thecherno.app.events.EventDispatcher; 11 | import com.thecherno.app.events.types.MouseMovedEvent; 12 | import com.thecherno.app.events.types.MousePressedEvent; 13 | import com.thecherno.app.events.types.MouseReleasedEvent; 14 | import com.thecherno.app.layers.Layer; 15 | 16 | public class ExampleLayer extends Layer { 17 | 18 | private String name; 19 | private Color color; 20 | private Rectangle box; 21 | 22 | private int px, py; 23 | private boolean dragging = false; 24 | 25 | private static final Random random = new Random(); 26 | 27 | public ExampleLayer(String name, Color color) { 28 | this.name = name; 29 | this.color = color; 30 | 31 | box = new Rectangle(random.nextInt(300) + 100, random.nextInt(200) + 80, 80, 50); 32 | } 33 | 34 | public void onEvent(Event event) { 35 | EventDispatcher dispatcher = new EventDispatcher(event); 36 | dispatcher.dispatch(Event.Type.MOUSE_PRESSED, (Event e) -> (onMousePressed((MousePressedEvent) e))); 37 | dispatcher.dispatch(Event.Type.MOUSE_RELEASED, (Event e) -> (onMouseReleased((MouseReleasedEvent) e))); 38 | dispatcher.dispatch(Event.Type.MOUSE_MOVED, (Event e) -> (onMouseMoved((MouseMovedEvent) e))); 39 | } 40 | 41 | public boolean onMousePressed(MousePressedEvent e) { 42 | if (box.contains(new Point(e.getX(), e.getY()))) 43 | dragging = true; 44 | 45 | return dragging; 46 | } 47 | 48 | public boolean onMouseReleased(MouseReleasedEvent e) { 49 | dragging = false; 50 | return false; 51 | } 52 | 53 | public boolean onMouseMoved(MouseMovedEvent e) { 54 | int x = e.getX(); 55 | int y = e.getY(); 56 | 57 | if (dragging) { 58 | box.x += x - px; 59 | box.y += y - py; 60 | } 61 | 62 | px = x; 63 | py = y; 64 | 65 | return dragging; 66 | } 67 | 68 | public void onRender(Graphics g) { 69 | g.setColor(color); 70 | g.fillRect(box.x, box.y, box.width, box.height); 71 | 72 | g.setColor(Color.WHITE); 73 | g.drawString(name, box.x + 5, box.y + 15); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/com/thecherno/app/Main.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app; 2 | 3 | import java.awt.Color; 4 | 5 | import com.thecherno.app.core.Window; 6 | 7 | public class Main { 8 | 9 | public static void main(String[] args) { 10 | Window window = new Window("Events", 640, 360); 11 | window.addLayer(new ExampleLayer("Bottom", new Color(0x2233CC))); 12 | window.addLayer(new ExampleLayer("Top", new Color(0xCC2233))); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/com/thecherno/app/core/Screen.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.core; 2 | 3 | import java.awt.Canvas; 4 | import java.awt.Color; 5 | import java.awt.Dimension; 6 | import java.awt.Graphics; 7 | import java.awt.image.BufferStrategy; 8 | 9 | @SuppressWarnings("serial") 10 | public class Screen extends Canvas { 11 | 12 | private BufferStrategy bs; 13 | private Graphics g; 14 | 15 | public Screen(int width, int height) { 16 | setPreferredSize(new Dimension(width, height)); 17 | } 18 | 19 | public void init() { 20 | createBufferStrategy(3); 21 | } 22 | 23 | public void beginRendering() { 24 | bs = getBufferStrategy(); 25 | g = bs.getDrawGraphics(); 26 | } 27 | 28 | public void clear() { 29 | g.setColor(Color.WHITE); 30 | g.fillRect(0, 0, getWidth(), getHeight()); 31 | } 32 | 33 | public Graphics getGraphicsObject() { 34 | return g; 35 | } 36 | 37 | public void endRendering() { 38 | g.dispose(); 39 | bs.show(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/com/thecherno/app/core/Window.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.core; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.event.MouseAdapter; 5 | import java.awt.event.MouseEvent; 6 | import java.awt.event.MouseMotionListener; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import javax.swing.JFrame; 11 | import javax.swing.SwingUtilities; 12 | 13 | import com.thecherno.app.events.Event; 14 | import com.thecherno.app.events.types.MouseMovedEvent; 15 | import com.thecherno.app.events.types.MousePressedEvent; 16 | import com.thecherno.app.events.types.MouseReleasedEvent; 17 | import com.thecherno.app.layers.Layer; 18 | 19 | @SuppressWarnings("serial") 20 | public class Window extends JFrame { 21 | 22 | private Screen screen; 23 | private List layerStack = new ArrayList(); 24 | 25 | public Window(String name, int width, int height) { 26 | screen = new Screen(width, height); 27 | 28 | setTitle(name); 29 | add(screen); 30 | pack(); 31 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 32 | setLocationRelativeTo(null); 33 | setVisible(true); 34 | 35 | screen.addMouseListener(new MouseAdapter() { 36 | 37 | public void mouseReleased(MouseEvent e) { 38 | MouseReleasedEvent event = new MouseReleasedEvent(e.getButton(), e.getX(), e.getY()); 39 | onEvent(event); 40 | } 41 | 42 | public void mousePressed(MouseEvent e) { 43 | MousePressedEvent event = new MousePressedEvent(e.getButton(), e.getX(), e.getY()); 44 | onEvent(event); 45 | } 46 | 47 | }); 48 | 49 | screen.addMouseMotionListener(new MouseMotionListener() { 50 | 51 | public void mouseMoved(MouseEvent e) { 52 | MouseMovedEvent event = new MouseMovedEvent(e.getX(), e.getY(), false); 53 | onEvent(event); 54 | } 55 | 56 | public void mouseDragged(MouseEvent e) { 57 | MouseMovedEvent event = new MouseMovedEvent(e.getX(), e.getY(), true); 58 | onEvent(event); 59 | } 60 | }); 61 | 62 | screen.init(); 63 | run(); 64 | } 65 | 66 | private void run() { 67 | screen.beginRendering(); 68 | screen.clear(); 69 | onRender(screen.getGraphicsObject()); 70 | screen.endRendering(); 71 | try { 72 | Thread.sleep(3); 73 | } catch (InterruptedException e) { 74 | } 75 | 76 | SwingUtilities.invokeLater(() -> run()); 77 | } 78 | 79 | public void onEvent(Event event) { 80 | for (int i = layerStack.size() - 1; i >= 0; i--) 81 | layerStack.get(i).onEvent(event); 82 | } 83 | 84 | private void onRender(Graphics g) { 85 | for (int i = 0; i < layerStack.size(); i++) 86 | layerStack.get(i).onRender(g); 87 | } 88 | 89 | public void addLayer(Layer layer) { 90 | System.out.println(layer); 91 | layerStack.add(layer); 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/Event.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events; 2 | 3 | public class Event { 4 | 5 | public enum Type { 6 | MOUSE_PRESSED, 7 | MOUSE_RELEASED, 8 | MOUSE_MOVED 9 | } 10 | 11 | private Type type; 12 | boolean handled; 13 | 14 | protected Event(Type type) { 15 | this.type = type; 16 | } 17 | 18 | public Type getType() { 19 | return type; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/EventDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events; 2 | 3 | public class EventDispatcher { 4 | 5 | private Event event; 6 | 7 | public EventDispatcher(Event event) { 8 | this.event = event; 9 | } 10 | 11 | public void dispatch(Event.Type type, EventHandler handler) { 12 | if (event.handled) 13 | return; 14 | 15 | if (event.getType() == type) 16 | event.handled = handler.onEvent(event); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/EventHandler.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events; 2 | 3 | public interface EventHandler { 4 | 5 | public boolean onEvent(Event event); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/EventListener.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events; 2 | 3 | public interface EventListener { 4 | 5 | public void onEvent(Event event); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/types/MouseButtonEvent.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events.types; 2 | 3 | import com.thecherno.app.events.Event; 4 | 5 | public class MouseButtonEvent extends Event { 6 | 7 | protected int button; 8 | protected int x, y; 9 | 10 | protected MouseButtonEvent(int button, int x, int y, Type type) { 11 | super(type); 12 | this.button = button; 13 | this.x = x; 14 | this.y = y; 15 | } 16 | 17 | public int getButton() { 18 | return button; 19 | } 20 | 21 | public int getX() { 22 | return x; 23 | } 24 | 25 | public int getY() { 26 | return y; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/types/MouseMovedEvent.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events.types; 2 | 3 | import com.thecherno.app.events.Event; 4 | 5 | public class MouseMovedEvent extends Event { 6 | 7 | private int x, y; 8 | private boolean dragged; 9 | 10 | public MouseMovedEvent(int x, int y, boolean dragged) { 11 | super(Event.Type.MOUSE_MOVED); 12 | this.x = x; 13 | this.y = y; 14 | this.dragged = dragged; 15 | } 16 | 17 | public int getX() { 18 | return x; 19 | } 20 | 21 | public int getY() { 22 | return y; 23 | } 24 | 25 | public boolean getDragged() { 26 | return dragged; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/types/MousePressedEvent.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events.types; 2 | 3 | import com.thecherno.app.events.Event; 4 | 5 | public class MousePressedEvent extends MouseButtonEvent { 6 | 7 | public MousePressedEvent(int button, int x, int y) { 8 | super(button, x, y, Event.Type.MOUSE_PRESSED); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/com/thecherno/app/events/types/MouseReleasedEvent.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.events.types; 2 | 3 | import com.thecherno.app.events.Event; 4 | 5 | public class MouseReleasedEvent extends MouseButtonEvent { 6 | 7 | public MouseReleasedEvent(int button, int x, int y) { 8 | super(button, x, y, Event.Type.MOUSE_RELEASED); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/com/thecherno/app/layers/Layer.java: -------------------------------------------------------------------------------- 1 | package com.thecherno.app.layers; 2 | 3 | import java.awt.Graphics; 4 | 5 | import com.thecherno.app.events.Event; 6 | import com.thecherno.app.events.EventListener; 7 | 8 | public class Layer implements EventListener { 9 | 10 | public void onEvent(Event event) { 11 | } 12 | 13 | public void onUpdate() { 14 | } 15 | 16 | public void onRender(Graphics g) { 17 | } 18 | 19 | } 20 | --------------------------------------------------------------------------------