Skip to content

Commit

Permalink
Merge pull request #73 from creme332/repaint
Browse files Browse the repository at this point in the history
implement layered canvas to fix painting bug
  • Loading branch information
creme332 authored Jun 18, 2024
2 parents 97e9970 + 25802a6 commit 32f7b7b
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 151 deletions.
14 changes: 0 additions & 14 deletions src/main/java/com/github/creme332/controller/CanvasController.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ public void mouseWheelMoved(MouseWheelEvent e) {
handleCanvasZoom(e);
}
});

// Add action listeners for the zoom panel buttons
canvas.getHomeButton().addActionListener(e -> resetCanvasView());
canvas.getZoomInButton().addActionListener(e -> model.updateCanvasZoom(true));
canvas.getZoomOutButton().addActionListener(e -> model.updateCanvasZoom(false));
}

private void handleCanvasZoom(MouseWheelEvent e) {
Expand Down Expand Up @@ -171,15 +166,6 @@ private void handleMousePressed(MouseEvent e) {
canvas.repaint();
}

private void resetCanvasView() {
// show origin at center of canvas
model.setXZero(canvas.getWidth() / 2);
model.setYZero(canvas.getHeight() / 2);

model.resetZoom();
canvas.repaint();
}

@Override
public void propertyChange(PropertyChangeEvent e) {
final String propertyName = e.getPropertyName();
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/com/github/creme332/controller/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public class Controller {
private Frame frame; // frame of app
private MenuBar menuBar;
private Canvas canvas;
private Toolbar toolbar;

private FrameController frameController;

Expand All @@ -23,16 +22,18 @@ public Controller() {
menuBar = new MenuBar(app.getMenuModels());
new MenuBarController(app, menuBar);

toolbar = new Toolbar();
new ToolBarController(toolbar);
CanvasConsole canvasConsole = new CanvasConsole();

canvas = new Canvas(app.getCanvasModel(), toolbar);
new ToolBarController(canvasConsole.getToolbar());
new ZoomPanelController(app.getCanvasModel(), canvasConsole.getZoomPanel());

canvas = new Canvas(app.getCanvasModel());
new CanvasController(app, canvas);

TutorialCenter tutorialCenter = new TutorialCenter();
new TutorialController(tutorialCenter);

frame = new Frame(canvas, menuBar, tutorialCenter);
frame = new Frame(canvas, canvasConsole, menuBar, tutorialCenter);
frameController = new FrameController(app, frame);

new SideMenuController(app, frame.getSideMenuPanel());
Expand All @@ -44,7 +45,6 @@ public Controller() {
e.printStackTrace();
System.exit(1);
}

frameController.playStartAnimation();
}

Expand Down
65 changes: 49 additions & 16 deletions src/main/java/com/github/creme332/controller/FrameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JLayeredPane;

import com.github.creme332.model.AppState;
import com.github.creme332.model.MenuModel;
import com.github.creme332.model.Screen;
Expand All @@ -19,49 +21,77 @@ public class FrameController implements PropertyChangeListener {
private Frame frame;
private AppState app;

public FrameController(AppState app, Frame frame) {
public FrameController(AppState model, Frame frame) {
this.frame = frame;
this.app = app;
this.app = model;

app.addPropertyChangeListener(this);
model.addPropertyChangeListener(this);

frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
// get current frame dimensions
int width = frame.getWidth();
int height = frame.getHeight();

// get menubar dimensions
int menuWidth = frame.getMyMenuBar().getWidth();
int menuHeight = frame.getMyMenuBar().getHeight();
resizeEverything();

int sideWidth = Math.min(400, width / 3);
frame.getMainPanel().setPreferredSize(new Dimension(menuWidth, height - menuHeight));
frame.setPreferredSize(new Dimension(sideWidth, height - menuHeight));
}
});

frame.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
MenuModel[] menuModels = app.getMenuModels();
MenuModel[] menuModels = model.getMenuModels();

// if Esc is pressed, select mode in first menu
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
app.setMode(menuModels[0].getActiveItem().getMode());
model.setMode(menuModels[0].getActiveItem().getMode());
return;
}

// if key number k is pressed, select mode in k-th menu where k = 1, 2, ...
for (int i = 0; i < menuModels.length; i++) {
if (e.getKeyCode() == (KeyEvent.VK_1 + i))
app.setMode(menuModels[i].getActiveItem().getMode());
model.setMode(menuModels[i].getActiveItem().getMode());
}
}
});
}

private void resizeEverything() {
int frameWidth = frame.getWidth();
int frameHeight = frame.getHeight();
System.out.format("Frame dimensions = %d x %d %n", frameWidth, frameHeight);

int menuBarHeight = frame.getMyMenuBar().getHeight();
System.out.format("Menubar dimensions = %d x %d %n", frameWidth, menuBarHeight);

int sideBarWidth = app.getSideBarVisibility() ? Math.max(800, frameWidth / 3) : 0;
System.out.format("Sidebar dimensions = %d x %d %n", sideBarWidth, frameHeight - menuBarHeight);

// update sidebar dimensions
// frame.getSideMenuPanel().setPreferredSize(new Dimension(sideBarWidth,
// frameHeight - menuBarHeight));

// update main panel dimensions
frame.getMainPanel().setPreferredSize(new Dimension(frameWidth, frameHeight - menuBarHeight));

// update pane dimensions
JLayeredPane pane = frame.getPane();
pane.setPreferredSize(new Dimension(frameWidth, frameHeight - menuBarHeight));
System.out.format("Pane dimensions = %d x %d %n", pane.getWidth(),
pane.getHeight());

// update size of canvas control
pane.getComponent(0).setBounds(0, 0, frameWidth - 80,
frameHeight - menuBarHeight - 100);

// temporarily hide the canvas control. without this, the canvas console does
// not render its new size when frame is maximized.
pane.getComponent(0).setVisible(false);
pane.getComponent(0).setVisible(true);

// update canvas size
pane.getComponent(1).setBounds(0, 0, frameWidth, frameHeight - menuBarHeight);
}

public void playStartAnimation() {
Timer timer = new Timer();
TimerTask showNextScreen;
Expand All @@ -81,6 +111,7 @@ public void run() {
if (app.getCurrentScreen().equals(Screen.TUTORIAL_SCREEN)) {
frame.showScreen(Screen.TUTORIAL_SCREEN);
}
resizeEverything();

timer.cancel();
timer.purge();
Expand All @@ -98,6 +129,8 @@ public void propertyChange(PropertyChangeEvent e) {

if (Screen.TUTORIAL_SCREEN.equals(e.getNewValue()))
frame.showScreen(Screen.TUTORIAL_SCREEN);

resizeEverything();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.github.creme332.model.MenuModel;
import com.github.creme332.model.CanvasModel;
import com.github.creme332.model.Mode;
import com.github.creme332.model.Screen;
import com.github.creme332.view.MenuBar;

public class MenuBarController implements PropertyChangeListener {
Expand Down Expand Up @@ -91,6 +92,8 @@ public void mousePressed(MouseEvent e) {
}
});

menubar.getHelpButton().addActionListener(e -> app.switchScreen(Screen.TUTORIAL_SCREEN));

menubar.getToggleAxesButton().addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.github.creme332.controller;

import com.github.creme332.model.CanvasModel;
import com.github.creme332.view.ZoomPanel;

public class ZoomPanelController {
CanvasModel model;
ZoomPanel view;

public ZoomPanelController(CanvasModel model, ZoomPanel view) {
this.model = model;
this.view = view;

// Add action listeners for the zoom panel buttons
view.getHomeButton().addActionListener(e -> model.resetZoom());
view.getZoomInButton().addActionListener(e -> model.updateCanvasZoom(true));
view.getZoomOutButton().addActionListener(e -> model.updateCanvasZoom(false));
}
}
110 changes: 4 additions & 106 deletions src/main/java/com/github/creme332/view/Canvas.java
Original file line number Diff line number Diff line change
@@ -1,116 +1,30 @@
package com.github.creme332.view;

import javax.swing.JButton;
import javax.swing.JPanel;

import org.kordamp.ikonli.Ikon;
import org.kordamp.ikonli.bootstrapicons.BootstrapIcons;
import org.kordamp.ikonli.swing.FontIcon;

import com.github.creme332.model.CanvasModel;
import com.github.creme332.model.ShapeWrapper;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;

/**
* Drawing board for coordinate system.
*/
public class Canvas extends JPanel {
private JButton homeButton = new CircularButton();
private JButton zoomInButton = new CircularButton();
private JButton zoomOutButton = new CircularButton();
private Toolbar toolbar;

private transient CanvasModel model;
private Toast toast = new Toast();

/**
* Place zoom panel in bottom right corner of canvas.
*/
public void positionZoomPanel() {
final int MARGIN_RIGHT = 20;
final int MARGIN_BOTTOM = 200;

final int canvasWidth = getWidth();
final int canvasHeight = getHeight();

Dimension buttonSize = homeButton.getPreferredSize();
int x = canvasWidth - buttonSize.width - MARGIN_RIGHT;
int y = canvasHeight - buttonSize.height - MARGIN_BOTTOM;

homeButton.setBounds(x, y, buttonSize.width, buttonSize.height);
zoomInButton.setBounds(x, y + 60, buttonSize.width, buttonSize.height);
zoomOutButton.setBounds(x, y + 120, buttonSize.width, buttonSize.height);
}

public void positionToast() {
// position toast
Dimension toastSize = toast.getPreferredSize();

Rectangle r = new Rectangle();
r.x = 30;
r.y = (int) (this.getHeight() - toastSize.getHeight() - 30);

r.width = (int) toastSize.getWidth();
r.height = (int) toastSize.getHeight();

toast.setBounds(r);
}

/**
* Place toolbar at middle top of canvas
*/
public void positionToolbar() {
final int MARGIN_TOP = 25; // distance between toolbar and canvas top
final int canvasWidth = getWidth();

// position toolbar such that center of toolbar coincides with center of canvas
Dimension toolbarSize = toolbar.getPreferredSize();
Rectangle r = new Rectangle();
r.x = canvasWidth / 2 - (int) (toolbarSize.getWidth() / 2);
r.y = MARGIN_TOP;

r.width = (int) toolbarSize.getWidth();
r.height = (int) toolbarSize.getHeight();

toolbar.setBounds(r);
}

public JButton createZoomPanelButton(Ikon ikon) {
final int ICON_SIZE = 25;
final Color gray = new Color(116, 116, 116);

JButton btn = new CircularButton();
btn.setPreferredSize(new Dimension(50, 50));
FontIcon icon = FontIcon.of(ikon, ICON_SIZE);
icon.setIconColor(gray);
btn.setIcon(icon);
return btn;
}

public Canvas(CanvasModel model, Toolbar toolbar) {
public Canvas(CanvasModel model) {
setLayout(null); // Use no layout manager

this.model = model;
this.toolbar = toolbar;
add(toolbar);
add(toast);

// create buttons for zoom panel
homeButton = createZoomPanelButton(BootstrapIcons.HOUSE);
zoomInButton = createZoomPanelButton(BootstrapIcons.ZOOM_IN);
zoomOutButton = createZoomPanelButton(BootstrapIcons.ZOOM_OUT);

add(homeButton);
add(zoomInButton);
add(zoomOutButton);
}

public void setAntialiasing(Graphics2D g2) {
Expand Down Expand Up @@ -239,10 +153,6 @@ public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
setAntialiasing(g2);

positionZoomPanel();
positionToolbar();
positionToast();

if (model.isGuidelinesEnabled()) {
drawGuidelines(g2);
}
Expand Down Expand Up @@ -285,16 +195,4 @@ private Shape createPointAsShape(Point2D mySpaceCoord) {
radius,
radius);
}

public JButton getHomeButton() {
return homeButton;
}

public JButton getZoomInButton() {
return zoomInButton;
}

public JButton getZoomOutButton() {
return zoomOutButton;
}
}
Loading

0 comments on commit 32f7b7b

Please sign in to comment.