Нажатие JButton и отображение прямой в JPanel

303
23 декабря 2016, 13:07

Подскажите пожалуйста.

Немного объясню смысл программы, загружаем в неё мишень, рассчитываем масштаб пикселей/мм (для того чтобы рисовать точки попадания с реальным диаметром), рисуем точки попадания и далее программа их анализирует.

Код урезан, от не урезанного отличается тем что у меня больше кнопок. Логику его закомментировал.

Проблема является с масштабом (на самом деле со всеми режимами одинаковая проблема, что с масштабом, что с добавлением центра мишени и точек попаданий).

Сейчас у меня реализовано это следующим образом.

  • Загружаем класс, с переменной mashtab = 0.
  • Считаем клики и записываем в массив координаты клика.
  • Если все координаты забиты, рисуем прямую.
  • Если есть масштаб, тогда следующие клики являются уже координатами не для масштаба а для точек попаданий. Запоминаем координаты клика.
  • Создаем массив ArrayList<Pellets> с координатами.
  • Рисуем прямую масштаба и точки попаданий из ArrayList<Pellets>.

А проблема в том, что я не понимаю как сделать так чтобы, мы нажали кнопку и мы рисуем масштаб (причем линия непрерывно тянется от первой точки до курсора мышки). Вернее понимаю, но наверное это тупо: Создаем переменную, например, setMashtab = 0; Нажимаем кнопку "Установить длину", и setMashtab = 1; В методе drawPanel.paintComponent() , рисуем новый If по условию которого смотрим переменную setMashtab и если она 1 тогда входим в рисование масштаба.

Но мне кажется такой метод не очень входит в понятия ООП, а какая-то фигня.

Подскажите пожалуйста как реализовать метод setMashtab чтобы он работал как метод без лишних If в методе drawPanel.paintComponent().

public class SimpleAnimation {
    private int x = 70 , y = 70;
    // переменная Масштаб, она хранит значение в котором записывается диаметр Пули.
    // она считается следующим образом, длина прямой в пикселях между точками, она делится на
    // длину в миллиметрах и умножается на диаметр пули. И получаем некую цифру которая содержит в себе
    // диаметр кнопки в пикселях соответствующий реальному.
    private int mashtab;
    private int[] firstClick = new int[2];
    private int[] secondClick = new int[2];
    private ArrayList<Pellets> pelletsArrayList = new ArrayList<Pellets>();
    private BufferedImage imageOfTarget;
    DrawPanel drawPanel = new DrawPanel();
    public static void main(String[] args) throws IOException {
        SimpleAnimation gui = new SimpleAnimation();
        gui.go();
    }
    public void go() throws IOException{
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane scrollpane = new JScrollPane();
        drawPanel.repaint();
        scrollpane.setViewportView(drawPanel);
        drawPanel.addMouseListener(new MouseListener() {
            int click = 0;
            @Override
            public void mouseClicked(MouseEvent e) {
                // Здесь я обрабатываю клик мышкой, смотрю на переменные mashtab и если он 0, тогда
                if (mashtab == 0) {
                    // если кликов 0, значит это первый клик по drawPanel и тогда запоминаем координаты мышки в массив
                    // тоже самое делаем и на втором клике.
                    if (click == 0) {
                        firstClick[0] = e.getX();
                        firstClick[1] = e.getY();
                    }
                    if (click == 1) {
                        secondClick[0] = e.getX();
                        secondClick[1] = e.getY();
                        click = -1;
                        drawPanel.repaint();
                    }
                    click++;
                } else {
                    x = e.getX();
                    y = e.getY();
                }
                drawPanel.repaint();
            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
        frame.add(BorderLayout.CENTER,scrollpane);
        JButton btnLength = new JButton();
        btnLength.setIcon(new ImageIcon("./Image/length_sm.png"));
        btnLength.setPreferredSize(new Dimension(60,60));
        // Создаем встроенный класс для обработчика событий нажатий
        // Такой вариант я подсмотрел в книге.
        btnLength.addActionListener(new btnLengthListener());
        JPanel panelOfMenuPic = new JPanel();
        panelOfMenuPic.setLayout(new BoxLayout(panelOfMenuPic,BoxLayout.Y_AXIS));
        panelOfMenuPic.add(btnLength);
        frame.add(BorderLayout.WEST,panelOfMenuPic);
        frame.setSize(600,700);
        frame.setVisible(true);
    }

    public void resetAll(){
        // Нажимамем кнопку сброс и всё переменные очищаются, для того чтобы можно было вводить новые данные
        pelletsArrayList.clear();
        mashtab = 0;
        drawPanel.repaint();
        firstClick[0] = firstClick[1] = 0;
        secondClick[0] = secondClick[1] = 0;
    }
    // Проблема в этом методе (описание в вопросе)
    public void setMashtab(){
    }
    class DrawPanel extends JPanel{
        public void setPrefSize(){
            setBorder(new LineBorder(Color.RED));
            setPreferredSize(new Dimension(imageOfTarget.getWidth(), imageOfTarget.getHeight()));
        }
        public void paintComponent (Graphics g){
            super.paintComponent(g);
            BufferedImage image = imageOfTarget;
            g.drawImage(image,0,0,this);
            int xStart = firstClick[0];
            int yStart = firstClick[1];
            int xEnd = secondClick[0];
            int yEnd = secondClick[1];
            if( xStart > 0 && yStart > 0) {
                g.setColor(Color.green);
            }
            if( xStart > 0 && yStart > 0 && xEnd > 0 && yEnd > 0) {
                g.setColor(Color.RED);
                g.drawLine(xStart,yStart,xEnd,yEnd);

                // Если масштаб ещё не расчитан, т.е равен 0 и у нас уже есть все координаты прямой по которой считается
                // масштаб определяем его длину и запоминаем.
                if (mashtab == 0) {
                    double lenghtLinePic = Math.hypot((xEnd - xStart), (yEnd - yStart));
                    double avg = (lenghtLinePic/31)*4.5;
                    TargetAnalise.convertPixelInMM((int) lenghtLinePic,31);
                    System.out.println("line= " + (xStart - xEnd) + " (mast)= " + avg);
                    mashtab = (int) avg;
                    // Если маштаб уже поссчитан, переходим к редактированию точек попаданий в мишень.
                    // И их отрисовки.
                } else {
                    pelletsArrayList.add(new Pellets(x, y, 1, mashtab , Color.green));
                    for(Pellets pellets: pelletsArrayList){
                        g.setColor(pellets.getColor());
                        g.fillOval(pellets.getX()-pellets.getHalfSize(),pellets.getY()-pellets.getHalfSize(),pellets.getSize(),pellets.getSize());
                    }
                    int[] rect = new int[4];
                    rect = TargetAnalise.getRectOfGroup(pelletsArrayList);
                    g.drawRect(rect[0],rect[1],rect[2],rect[3]);
                    g.setColor(Color.BLACK);
                    g.drawString("Квадрат рассеивания: " +  rect[2]/TargetAnalise.getPixelInMM() + "x" + rect[3]/TargetAnalise.getPixelInMM(),100,150);
                    TargetAnalise.avergeOfImpact(pelletsArrayList);
                    int[] ttt = new int[2];
                    TargetAnalise.avergeOfImpact(pelletsArrayList);
                    ttt = TargetAnalise.getAverageOfImpact();
                    System.out.println("STP x = " + ttt[0] + " y= " + ttt[1]);
                    g.setColor(Color.red);
                    g.fillOval(ttt[0]-5,ttt[1]-5,10,10);
                }
            }
        }
    }
    class btnLengthListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Нажата кнопка Length");
            setMashtab();
        }
    }
}
READ ALSO
Cookies в Spring REST [требует правки]

Cookies в Spring REST [требует правки]

Имеется метод который принимает @RequestBody, также необходимо брать данные из cookie, в которых содержится язык, но если использовать HttpServlerRequest getCookies,...

291
Поиск нецензурных слов в словах

Поиск нецензурных слов в словах

Подскажите, как cделать простую и не очень медленную проверку отправляемого текста на сервер на наличие матов? Те ввел юзер плохие слова и идет...

345
RestTemplate - как отправить на сервер строку

RestTemplate - как отправить на сервер строку

Использую SpringНужно сделать post-запрос из андроид приложения

435