Hello I would like to implement a feature in my program that allows the user to draw freely on a certain portion of the canvas so long as they have their mouse clicked, and releasing to stop. The problem is that I want to run this in a loop, which I am using not for a game but to just render stuff on the frame. The relevant code will be pasted. I have implemented the mouseListener and I have experimented, but I do not know how to do this. I currently only have a frame which looks like this: frame
I want to draw into the empty space (which is a canvas) while the game/render loop is running but I do not know how. A clearing function would be cool to implement as well but again my main concern is the drawing.
Here is the relevant code, I subsituted comments for any code I deemed irrelevant:
package dev.akaBryan.doodleclassification;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import javax.swing.JPanel;
//import my own packages
public class DoodleClassification implements Runnable, MouseListener, ActionListener{
private Display display;
public String title;
public int width, height;
//attributes for any variables for my code
public Random random = new Random();
private Thread thread;
private boolean running = false;
private BufferStrategy bs;
private Graphics g;
private Graphics2D g2d;
private BasicStroke stroke;
public DoodleClassification(String title, int width, int height, int maxSets, int trainingSets) {
this.title=title;
this.width=width;
this.height=height;
this.maxSets = maxSets;
this.trainingSets = trainingSets;
}
private void preLoad() {
//load data of 100000 doodles
beesData = ByteLoader.loadBytes("/doodleData/bee100000.bin");
dogsData = ByteLoader.loadBytes("/doodleData/dog100000.bin");
forksData = ByteLoader.loadBytes("/doodleData/fork100000.bin");
rainbowsData = ByteLoader.loadBytes("/doodleData/rainbow100000.bin");
trainsData = ByteLoader.loadBytes("/doodleData/train100000.bin");
}
private void init() {
//create and initialize data and neural network
display = new Display(title, width, height);
display.getTestButton().addActionListener(this);
display.getTrainButton().addActionListener(this);
}
public void tick() {
this.width = display.getJFrame().getSize().width;
this.height = display.getJFrame().getSize().height;
}
public void render() {
bs = display.getCanvas().getBufferStrategy();
if(bs==null) {
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g2d = (Graphics2D) g;
//clear screen
g2d.clearRect(0, 0, width, height);
//start draw here
//end draw here
bs.show();
g.dispose();
}
@Override
public void run() {
preLoad();
init();
int fps = 60;
double timePerTick = 1000000000/fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
long timer = 0;
int ticks = 0;
while(running) {
now = System.nanoTime();
delta += (now - lastTime)/timePerTick;
timer+= now-lastTime;
lastTime = now;
if(delta >= 1) {
tick();
render();
ticks++;
delta--;
}
if(timer>= 1000000000) {
//System.out.println("Ticks and Frames: " + ticks);
ticks = 0;
timer = 0;
}
}
stop();
}
public synchronized void start() {
if(running) {
return;
}
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
if(!running) {
return;
}
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public double testAll(Data training) {
//test code
}
public void trainEpoch(Data training) {
//train for one epoch code
}
public void prepareTesting(int sum, Data training) {
//prepare testing data for testing code
}
public void prepareTraining(int sum, Data training) {
//prepare testing data for testing code
}
public void prepareData(Data data, byte[] fullData, int maxSets, int trainingSets, int label) {
//prepare data and randomize
}
public byte[] subArray(byte[] bytes, int start, int end){
//create subarray to choose selection of data
}
public static DataObject[] shuffleArray(DataObject[] array) {
//shuffle data array
}
public static void shuffleArray(DataObject[] array, boolean replace) {
//2nd constructor to shuffle array
}
public double indexOfMax(double[] array) {
//get the index of the max
}
public double max(double[] array) {
//get the max of an array
}
@Override
public void mouseClicked(MouseEvent e) {
//unimplemented
}
@Override
public void mousePressed(MouseEvent e) {
//unimplemented
}
@Override
public void mouseReleased(MouseEvent e) {
//unimplemented
}
@Override
public void mouseEntered(MouseEvent e) {
//unimplemented
}
@Override
public void mouseExited(MouseEvent e) {
//unimplemented
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==display.getTrainButton()) {
trainEpoch(brainData);
epochCounter++;
}else if(e.getSource()==display.getTestButton()) {
double percent = testAll(brainData);
System.out.println("% Correct: " + percent+"%");
System.out.println();
}
}
}