0

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();
            }
        }
    
    }
akaBryan
  • 92
  • 7
  • 1
    There's a couple of ways you might do this, you could render to a backing buffer (like `BufferedImage`), [for example](https://stackoverflow.com/questions/18528061/resize-the-panel-without-revalidation/18528140#18528140) or you could keep track the of the mouse points and render lines between them each time the UI is updated, [for example](https://stackoverflow.com/questions/49216829/draw-trail-of-circles-with-mousedragged/49216898#49216898). Now, before you complain to me that these examples are in Swing and you're using "active rendering", the concept is the same – MadProgrammer Mar 14 '22 at 21:59
  • Ahh thank you, honestly I am very new to rendering as a whole and whatnot, I appreciate the help. I thought of somehow using a buffer or buffered image, so I will probably go with that since the mouse points and lines seem a bit hectic, but I'll try both out. Thank you! – akaBryan Mar 14 '22 at 22:14

0 Answers0