Java, optymalizacja, jakość kodu, pula wątków scheduler executor service

0

Witam
Napisałem taki programik, działa, lecz mam wątpliwość odnoście jakości optymalizacji. Chciałbym żeby przejrzał to ktoś kto się dobrze zna i ewentualnie podrzucił trochę pomysłów na usprawnienie.

import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

public class PanelWyswietlania extends JPanel {
    private FramePointer framePointer;
    private BufferedImage bufferedImage;
    private Robot robot;
    private Rectangle rectCute;

    private Rectangle rectFish = new Rectangle();
    private int pixels[];

    private Test test;
    private PanelOption panelOption;

    private ConcurrentHashMap<Point, Integer> pixelsWindowsFish = new ConcurrentHashMap<>();

    private int indexSlotFish = 0;

    private ScheduledThreadPoolExecutor mainPools;
    private ScheduledThreadPoolExecutor managementPools;

    private Panel_inventoryTracing panel_inventoryTracing;

    private volatile Future<?> task_throw = null;

    public PanelWyswietlania(Test test, PanelOption panelOption, Panel_inventoryTracing panel_inventoryTracing) {
        this.test = test;
        this.panelOption = panelOption;

        rectCute = new Rectangle();
        try {
            robot = new Robot();
        } catch (AWTException e) {
            e.printStackTrace();
        }

        this.setLayout(new FlowLayout(FlowLayout.CENTER));
        this.add(panel_inventoryTracing);

        this.panel_inventoryTracing = panel_inventoryTracing;

    }
    private ThrowRowFish throwRowFish = new ThrowRowFish();

    public void start() {
        robot.mouseMove(framePointer.getCenterPoint().x, framePointer.getCenterPoint().y);
        robot.mousePress(InputEvent.BUTTON2_DOWN_MASK);
        robot.mouseRelease(InputEvent.BUTTON2_DOWN_MASK);
        isBlockThrow.set(false);

        mainPools = new ScheduledThreadPoolExecutor(4);
        managementPools = new ScheduledThreadPoolExecutor(4);
        managementPools.scheduleAtFixedRate(new TimerTitle(), 0,1000, TimeUnit.MILLISECONDS);
        mainPools.scheduleAtFixedRate(new MainTask(), 0,2, TimeUnit.MILLISECONDS);

        managementPools.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                repaint();
            }
        }, 500, 1000/50, TimeUnit.MILLISECONDS);
    }
    public void stop() {
        if(mainPools!=null && managementPools!=null) {
            mainPools.shutdownNow();
            managementPools.shutdownNow();
            try {
                mainPools.awaitTermination(10,TimeUnit.SECONDS);
                mainPools.awaitTermination(10,TimeUnit.SECONDS);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }


        }
        bufferedImage = null;
        repaint();
    }

    private AtomicBoolean isBlockThrow = new AtomicBoolean();
    private AtomicBoolean blockCliked = new AtomicBoolean();
    private AtomicBoolean isWindowsVisible = new AtomicBoolean();

    private class MainTask implements Runnable {

        @Override
        public void run() {
            updateArea();
            isWindowsVisible.set(isWindowFishVisible());

            if(!isWindowsVisible.get() && !isBlockThrow.get()) {
                isBlockThrow.set(true);
                task_throw = mainPools.schedule(throwRowFish, 4500, TimeUnit.MILLISECONDS);
                return;
            }

            if(isWindowsVisible.get()) {
                if(task_throw !=null) {
                    isBlockThrow.set(false);
                    task_throw.cancel(false);
                }

                tracingFish();
                if(!blockCliked.get() && isFishOnCursor()) {
                    blockCliked.set(true);
                    robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
                    robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
                    mainPools.schedule(new Runnable() {
                        @Override
                        public void run() {
                            blockCliked.set(false);
                        }
                    },test.getDelayA(), TimeUnit.MILLISECONDS);
                }
            }
        }
    }
    private class ThrowRowFish implements Runnable {

        @Override
        public void run() {
            try {
                boolean[] keys = panelOption.getChosenKeys();
                int key = 0;
                if (indexSlotFish >= 7) {
                    indexSlotFish = 0;
                }
                for (int i = indexSlotFish; i < keys.length; i++) {
                    if (keys[i] == true) {
                        switch (i) {
                            case 0:
                                key = KeyEvent.VK_1;
                                break;
                            case 1:
                                key = KeyEvent.VK_2;
                                break;
                            case 2:
                                key = KeyEvent.VK_3;
                                break;
                            case 3:
                                key = KeyEvent.VK_4;
                                break;
                            case 4:
                                key = KeyEvent.VK_F1;
                                break;
                            case 5:
                                key = KeyEvent.VK_F2;
                                break;
                            case 6:
                                key = KeyEvent.VK_F3;
                                break;
                            case 7:
                                key = KeyEvent.VK_F4;
                                break;
                        }
                        robot.keyPress(key);
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }
                        robot.keyRelease(key);

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }

                        robot.keyPress(KeyEvent.VK_SPACE);
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }
                        robot.keyRelease(KeyEvent.VK_SPACE);
                        indexSlotFish++;
                        System.out.println(key);
                        break;
                    } else {
                        indexSlotFish++;
                    }
                }
            }
            finally {
                isBlockThrow.set(false);

            }
        }
    }
    private class TimerTitle implements Runnable {
        long timeSecunds = 0;
        long timeMinuts = 0;

        int counters_tracing_inventory = 0;

        @Override
        public void run() {
            if(timeSecunds > 59) {
                timeMinuts++;
                timeSecunds = 0;
            }
            if(timeMinuts > 0) {
                test.setTitle("Fish bot : time running - " + timeMinuts + " minuts " + timeSecunds + " secunds.");
            }
            else {
                test.setTitle("Fish bot : time running - " + timeSecunds + " secunds.");
            }

            if(panel_inventoryTracing.isActive()) {
                counters_tracing_inventory++;
                if (counters_tracing_inventory >= panel_inventoryTracing.getDelay()*60&& !isWindowsVisible.get()) {
                    counters_tracing_inventory = 0;
                    mainPools.shutdownNow();
                    try {
                        mainPools.awaitTermination(10,TimeUnit.SECONDS);
                    } catch (InterruptedException exception) {
                        exception.printStackTrace();
                    }

                    managementPools.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                panel_inventoryTracing.getInventoryTracking().start();
                            } catch (InterruptedException exception) {
                                exception.printStackTrace();
                            }
                            mainPools = new ScheduledThreadPoolExecutor(4);
                            isBlockThrow.set(false);
                            mainPools.scheduleAtFixedRate(new MainTask(), 0,2, TimeUnit.MILLISECONDS);
                            counters_tracing_inventory = 0;
                            System.gc();
                            System.runFinalization();
                        }
                    });
                }
            }


            timeSecunds++;
        }
    }

    private void updateArea() {
        //Update area
        rectCute.setFrame(framePointer.getCenterPoint().x,framePointer.getCenterPoint().y,framePointer.getRadius(),framePointer.getRadius());
        bufferedImage = robot.createScreenCapture(rectCute);
        pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
    }

    private void tracingFish() {
        //0x37597C // 36587C
        //System.out.println(Integer.decode("0x37597C"));
        //if(r.getRed() > 52 && r.getRed() < 55 && r.getGreen() >85 &&r.getGreen() < 95 && r.getBlue() >115 &&r.getBlue() < 125)
        rectFish.setFrame(0,0,0,0);
        for(int i = 0; i < pixels.length; i++) {
            Color r = Color.decode(String.valueOf(pixels[i]));
            if(r.getRed() > 45 && r.getRed() < 70 && r.getGreen() >80 &&r.getGreen() < 115 && r.getBlue() >100 &&r.getBlue() < 140) {
                int size = bufferedImage.getWidth();
                robot.mouseMove(framePointer.getCenterPoint().x + i - i/size*size +2, framePointer.getCenterPoint().y + i/size +5);
                break;
            }
        }
    }
    private boolean isFishOnCursor() {
        Point pointMouse = MouseInfo.getPointerInfo().getLocation();

        Color r = robot.getPixelColor(pointMouse.x, pointMouse.y);
        if(r.getRed() > 45 && r.getRed() < 70 && r.getGreen() >80 &&r.getGreen() < 115 && r.getBlue() >100 &&r.getBlue() < 140) {
            if(Trygonometria.checkCollision(pointMouse.x , pointMouse.y,1, framePointer.getCenterPoint().x, framePointer.getCenterPoint().y, framePointer.getRadius())) {
                return true;
            }
        }

        /*
        rectFish.setFrame(0,0,0,0);
        for(int i = 0; i < pixels.length; i++) {
            Color r = Color.decode(String.valueOf(pixels[i]));
            if(r.getRed() > 45 && r.getRed() < 70 && r.getGreen() >80 &&r.getGreen() < 115 && r.getBlue() >100 &&r.getBlue() < 140) {
                int size = bufferedImage.getWidth();
                if(Trygonometria.checkCollision(framePointer.getCenterPoint().x + i - i/size*size +2, framePointer.getCenterPoint().y + i/size +5,1, framePointer.getCenterPoint().x, framePointer.getCenterPoint().y, framePointer.getRadius())) {
                    return true;
                }
            }
        }
        return false;

         */
        return false;
    }

    private boolean isWindowFishVisible() {
        int index = 0 ;
        for (Map.Entry<Point, Integer> maps : pixelsWindowsFish.entrySet()) {
            if(pixels[(int)(maps.getKey().getX() + maps.getKey().getY() * bufferedImage.getWidth())] == maps.getValue()) {
                index ++;
            }
        }
        if(index > 0) {return true;}
        return false;
    }
    /*
    private void throwFishingRod() {
        boolean[] keys = test.getChosenKeys();
        int key = 0;
        if(indexSlotFish >= 7) {
            indexSlotFish = 0;
        }
        for(int i = indexSlotFish; i < keys.length; i++) {
            if(keys[i] == true) {
                switch(i) {
                    case 0 : key = KeyEvent.VK_1; break;
                    case 1 : key = KeyEvent.VK_2; break;
                    case 2 : key = KeyEvent.VK_3; break;
                    case 3 : key = KeyEvent.VK_4; break;
                    case 4 : key = KeyEvent.VK_F1; break;
                    case 5 : key = KeyEvent.VK_F2; break;
                    case 6 : key = KeyEvent.VK_F3; break;
                    case 7 : key = KeyEvent.VK_F4; break;
                }
                robot.keyPress(key);
                robot.keyRelease(key);

                robot.keyPress(KeyEvent.VK_SPACE);
                robot.keyRelease(KeyEvent.VK_SPACE);
          System.out.println(key);
                indexSlotFish++;
                return;
            }
            else {
                indexSlotFish++;
            }
        }
    }


     */

    public void getPixelColorFromWindowFish() {
        rectCute.setFrame(framePointer.getCenterPoint().x,framePointer.getCenterPoint().y,framePointer.getRadius(),framePointer.getRadius());
        bufferedImage = robot.createScreenCapture(rectCute);
        pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();

        pixelsWindowsFish.clear();

        pixelsWindowsFish.put(new Point(bufferedImage.getWidth()/10, bufferedImage.getHeight()/2), pixels[bufferedImage.getWidth()/10 + bufferedImage.getHeight()/2 * bufferedImage.getWidth()]);
        pixelsWindowsFish.put(new Point(bufferedImage.getWidth()/2, bufferedImage.getHeight()/10), pixels[bufferedImage.getWidth()/2 + bufferedImage.getHeight()/10 * bufferedImage.getWidth()]);
        pixelsWindowsFish.put(new Point(bufferedImage.getWidth()/2, bufferedImage.getHeight()/2), pixels[bufferedImage.getWidth()/2 + bufferedImage.getHeight()/2 * bufferedImage.getWidth()]);
        pixelsWindowsFish.put(new Point(bufferedImage.getWidth()/2, (int)(bufferedImage.getHeight()*0.9)), pixels[bufferedImage.getWidth()/2 + (int)(bufferedImage.getHeight()*0.9) * bufferedImage.getWidth()]);
        pixelsWindowsFish.put(new Point((int)(bufferedImage.getWidth()*0.9), bufferedImage.getHeight()/2), pixels[(int)(bufferedImage.getWidth()*0.9) + bufferedImage.getHeight()/2 * bufferedImage.getWidth()]);
        System.out.println("pobrano wartosic kolorow :  " + pixelsWindowsFish.size());
    }


    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        if(bufferedImage !=null) {
            g2.drawImage(bufferedImage, getWidth() / 2 - bufferedImage.getWidth() / 2, 0, null);
            if (blockCliked.get()) {
                g2.setPaint(Color.RED);
            } else {
                g2.setPaint(Color.GREEN);
            }
            g2.draw(rectFish);

            for (Map.Entry<Point, Integer> maps : pixelsWindowsFish.entrySet()) {
                g2.setPaint(Color.decode(String.valueOf(maps.getValue())));
                g2.setPaint(Color.RED);
                g2.drawRect(getWidth() / 2 + bufferedImage.getWidth() / 2 - maps.getKey().x, maps.getKey().y, 2, 2);
            }
        }
    }

    public void setFramePointer(FramePointer framePointer) {this.framePointer = framePointer;}

    public void setPixelsWindowsFish(ConcurrentHashMap<Point, Integer> pixelsWindowsFish) {
        this.pixelsWindowsFish = pixelsWindowsFish;
    }
    public ConcurrentHashMap<Point, Integer> getPixelsWindowsFish() {
        return pixelsWindowsFish;
    }
}


4

o_O to pytanie na serio? Masz tu jakiś GOD OBJECT, wszystko w jednej biednej klasie która niby jest panelem na którym coś wyświetlasz. Podziel to na powiedzmy 15 klas, tak żeby logika nie była pomieszana z widokiem i może coś się będzie dało tu zobaczyć.

2

Polecam przeczytać Clean Code. Dowiesz się jak dobrze podzielić kod na testowalny, rozbity na małe sensowne chunki.

1
  1. Pozbyć się polskich nazw w metodach, zmiennych...
  2. Zrównać niektóre wcięcia, bo to nie jest dobre.
  3. exception.printStackTrace();WTF?
  4. WTF v2
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }
                        robot.keyRelease(key);

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }

                        robot.keyPress(KeyEvent.VK_SPACE);
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException exception) {
                            exception.printStackTrace();
                        }
  1. task_throw To nie C/C++.
  2. PanelWyswietlania(Test test, No nazwa test to nie bardzo pasuje.
  • to co poprzednicy.

W ogóle jak się wrzuca kod do oceny, to fajnie pokazać co on robi, jakieś zrzuty itp.

0

@Shalom:



            if(panel_inventoryTracing.isActive()) {
                counters_tracing_inventory++;
                if (counters_tracing_inventory >= panel_inventoryTracing.getDelay()*60&& !isWindowsVisible.get()) {
                    counters_tracing_inventory = 0;
                    mainPools.shutdownNow();
                    try {
                        mainPools.awaitTermination(10,TimeUnit.SECONDS);
                    } catch (InterruptedException exception) {
                        exception.printStackTrace();
                    }

                    managementPools.submit(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                panel_inventoryTracing.getInventoryTracking().start();
                            } catch (InterruptedException exception) {
                                exception.printStackTrace();
                            }

                           mainPools = new ScheduledThreadPoolExecutor(4);
                            isBlockThrow.set(false);
                            mainPools.scheduleAtFixedRate(new MainTask(), 0,2, TimeUnit.MILLISECONDS);
                            counters_tracing_inventory = 0;
                            System.gc();
                            System.runFinalization();
                        }
                    });
                }
            }

jak potrzebowałem zrobić pause to zrobiłem to tak że zabijam scheduler i tworze go jeszcze raz dobry to jest patent ?

2

Nie, brzmi jak jakieś chore rozwiązanie. Normalny człowiek użyłby jakiegoś semafora w wątku. Zresztą jak widzę ze ktoś woła

                            System.gc();
                            System.runFinalization();

to na pewno nic w tym kodzie nie jest dobrze.
I nadal główny problem tego kodu jest taki, że wcisnałeś wszystko do jednego biednego panelu, podczas gdy panel powinien tylko opisywać wygląd interfejsu.

0

@Shalom: @Shalom: Czyści pamięć z nie używanych obiektów , zmiennych ? Wszystko działa perfekcyjnie, ale co to pewnych rzeczy mam wątpliwość.

5

Czyści pamięć z nie używanych obiektów , zmiennych ?

Java sama czyści System.gc() nie jest potrzebne,a System.runFinalization(); też nie. Korzystasz z finalizerów? Jeśli tak to powinieneś przestać a jeśli nie to na co Ci to?

1 użytkowników online, w tym zalogowanych: 0, gości: 1