Вопрос по рисованию квадратов с graphics и swing с помощью arraylist и отдельных классов.

 
 
 
Сообщения:8
Добрый день.
Я пытаюсь понять как "обмануть" graphics метод.

На данный момент мои знания позволяют создавать простую анимацию с
graphics и swing. Но как добавлять или убирать новые графические обьекты
из метода graphics не знаю.

Сейчас я планирую создать программу которая делает именно это.
Создаёт или удаляет квадраты при нажатии кнопки.



По моему плану сами квадратики должны быть отдельным
классом и сохранены в arraylist. Примерно как на рисунке внизу.



Ищу примеры кода подобной программы или чего нибудь похожего.

P.S. гугль не помогает, он даёт только ссылки на то как рисовать
фигуры с помощью drawrect в graphics методе. это я и так знаю.

P.P.S. Код я пока не писал т.к. хочу сначала понять как это вообще можно сделать.
Печатать потом.

С Уважением.
Андрей.
 
 
Сообщения:595
зачем его обманывать? он очень послушный и сделает всё, о чём его попросили.

пример глянь тут

и пользуйся, пока я добрый.
 
 
Сообщения:8
Ясно, программа немного продвинута для меня, поэтому я как новичок мог что то пропустить.
я не совсем понял, где здесь прорисовываются нажатые квадратики:

    public void paint(Graphics g1) 
    {
        Graphics2D g = (Graphics2D)g1;
        g.clearRect(0, 0, width, high);  //зде
        
        for(int i = 0; i<=width-50;i+=tileWidth)
            g.drawLine(i, 0, i, high);
        
        for(int i = 0; i<=high;i+=tileHigh)
            g.drawLine(0, i, width-51, i);
        
        
        for(int x = 1; x<map.length-1;x++)
            for(int y = 1; y<map[x].length-1;y++)
                if(map[x][y]>0)
                    g.fillRect((x-1)*tileWidth, (y-1)*tileHigh, tileWidth, tileHigh);
        
        g.draw3DRect(955, 5, 40, 20, true);
        g.draw3DRect(955, 35, 40, 20, true);
        
        if(runing)
        {
            Color color = g.getColor();
            g.setColor(Color.red);
            g.fillRect(955, 5, 40, 20);
            g.setColor(color);
        }
        
        g.drawString("S", 970, 20);
        g.drawString("C", 970, 50);      
    }
 
 
Сообщения:595
    public void paint(Graphics g1) 
    {
        Graphics2D g = (Graphics2D)g1;
        g.clearRect(0, 0, width, high);  //здесь экран очищается
        
        for(int i = 0; i<=width-50;i+=tileWidth) // здесь рисуются вертикальные линии
            g.drawLine(i, 0, i, high);
        
        for(int i = 0; i<=high;i+=tileHigh) // здесь горизонтальные
            g.drawLine(0, i, width-51, i);
        
        
        for(int x = 1; x<map.length-1;x++)
            for(int y = 1; y<map[x].length-1;y++)
                if(map[x][y]>0)
                    g.fillRect((x-1)*tileWidth, (y-1)*tileHigh, tileWidth, tileHigh); // здесь заполняются квадратики
        
        g.draw3DRect(955, 5, 40, 20, true);  // это две кнопки 
        g.draw3DRect(955, 35, 40, 20, true);
        
        if(runing) // здесь закрашивается кнопка старт, если игра запущена
        {
            Color color = g.getColor();
            g.setColor(Color.red);
            g.fillRect(955, 5, 40, 20);
            g.setColor(color);
        }
        
        g.drawString("S", 970, 20); // здесь вписывается текст в кнопки
        g.drawString("C", 970, 50);      
    }
 
 
Сообщения:8
Но где происходит запоминание количества и местоположения нажатых квадратиков?
 
 
Сообщения:595
совсем нуб? количество нигде, а положение в map.
 
 
Сообщения:8
Нуб, да.
Программу понял теперь.
Впрочем попробовал сделать по своему:

package squares.adder;
//main class
public class SquaresAdder {

    public static void main(String[] args) {
        MainScreen ms = new MainScreen();
        ms.go();//запускаем главный экран
    }
}


package squares.adder;
// Главное меню
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainScreen {
    
public void go(){    
    AddingSquares addsquares = new AddingSquares();
    AddingSquares.upListener upp = addsquares.new upListener();//передаём ссылку на кнопку классу со всей логикой
    AddingSquares.downListener dowwn = addsquares.new downListener();//передаём ссылку на кнопку классу со всей логикой
    
    MainCanvas canvas = new MainCanvas();
    JButton buttonup = new JButton("UP");
    JButton buttondown = new JButton("DOWN");
    buttonup.addActionListener(upp);
    buttondown.addActionListener(dowwn);
    JPanel panel = new JPanel();
    panel.add(buttonup);
    panel.add(buttondown);
    JFrame frame = new JFrame();
           frame.getContentPane().add(BorderLayout.SOUTH, panel);
           frame.getContentPane().add(BorderLayout.CENTER,canvas);
           frame.setSize(500, 500); 
           frame.setVisible(true);
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}


package squares.adder;
//Главный холст
import java.awt.Canvas;
import java.awt.Graphics;

public class MainCanvas extends Canvas{
AddingSquares asq = new AddingSquares();
   
@Override
public void paint(Graphics g){

    asq.Drawing(g);//срисовуем холст из AddingSquare

    }
    
}


package squares.adder;

//В данном классе мы создаём и прорисовуем квадрат.

import java.awt.Graphics;
import static squares.adder.SquaresAdder.main;
import sun.java2d.loops.DrawRect;

public class Square {

int y;//у позиция 

    public Square(int y) {//конструктор, устанавливает у позицию
        this.y = y;
    }

    
    public void PaintSguare(Graphics g){
        g.drawRect(0,y, 20, 10);//рисуем квадрат
    }

}


package squares.adder;

//В данном классе вся логика происходит.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class AddingSquares {
    int ypos=100; //счётчик позиции

    
        ArrayList<Square> list = new ArrayList<>();//создание списка квадратов

        
    class upListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            
        list.add(new Square(ypos));    //добавление квадрата при нажатии кнопки
        ypos = ypos+10;    //ув. счётчик позиции
        }
    
    }
    
    class downListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            
        list.remove(list.size() - 1);  //удавление квадрата при нажатии кнопки  
        ypos = ypos-10;     //ум. счётчик позиции
        }
    
    }
    
    public void Drawing(Graphics g){
        /*прорисовка списка квадрата*/
        for (int i = 0; i < list.size(); i++) {
        g.setColor(Color.green);
        list.get(i).PaintSguare(g);

        //Не работает. Почему?
        }   
    } 
    
}


По идее последний класс должен прорисовывать квадраты. Но не прорисовует :( . Нельзя ли экспертного мнения почему и как исправить.

С уважением.
Андрей.
 
 
Сообщения:595
ты repaint забыл.
 
 
Сообщения:8
Боюсь моих знаний о использовании repaint не хватает. Его я так понимаю в downListener и upListener запихивать надо.
Этого у меня не получается. Можно посмотреть как это должно выглядеть?
 
 
Сообщения:595
дело в том, что лисенеры, обычно, пихают в Component, в твоём случае это MainCanvas, а ты вынес их за пределы View и пихнул в Model.
кстати, почитай про MVC вещь полезная.
глянь тут а именно класс Start строчки 39-46.
 
 
Сообщения:8
MainCanvas? не MainScreen?
Информация интересная про MCV. Я так понимаю что MCV как раз и используется для разделения логики и экрана который эту логику показывает?
Следующее приложение с ним сделаю. как на этом левелап получу ).Есть пример MCV с графикой?

Я програмить начал недавно но насколько мог понять программу нужно разбивать на части, причём чем больше тем лучше. В одной на экран выводить, в другой кнопки прорисовывать, в третьей квадраты, итд. Поэтому я так думал что и листенер нужно отдельно от кнопки размещать. Всё же если приложение будет большим то на каждую кнопку листенер в том же классе - очень большой файл может получится я так понимаю, под >300 строк.

Просмотрел приложение, судя по моему копанию и экспериментам проблема именно в for loop в graphics в AddingSquares.
Как видно из примера ниже. (P.S. ошибка возникает когда размер arraylist < 0. потом исправлю, пока неважно).

package squares.adder;
//main class
public class SquaresAdder {

    public static void main(String[] args) {
        MainScreen ms = new MainScreen();
        ms.go();//запускаем главный экран
    }
}


package squares.adder;
// Главное меню
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainScreen {
JFrame frame;    


public void go(){    
    AddingSquares addsquares = new AddingSquares();
    AddingSquares.upListener upp = addsquares.new upListener();//передаём ссылку на кнопку классу со всей логикой
    AddingSquares.downListener dowwn = addsquares.new downListener();//передаём ссылку на кнопку классу со всей логикой
    boolean bool = getget();
    
    
    
    MainCanvas canvas = new MainCanvas();
    JButton buttonup = new JButton("UP");
    JButton buttondown = new JButton("DOWN");
    buttonup.addActionListener(upp);
    buttondown.addActionListener(dowwn);
    JPanel panel = new JPanel();
    panel.add(buttonup);
    panel.add(buttondown);
           frame = new JFrame();
           frame.getContentPane().add(BorderLayout.SOUTH, panel);
           frame.getContentPane().add(BorderLayout.CENTER,canvas);
           frame.setSize(500, 500); 
           frame.setVisible(true);
           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           while(bool==true){frame.repaint();bool = false;System.out.println("redraw");System.out.println("repaint");}
           System.out.println("mainscreen");

    }
    public boolean getget(){
    boolean bool;
    return bool = true;
    }

}


package squares.adder;
//Главный холст
import java.awt.Canvas;
import java.awt.Graphics;

public class MainCanvas extends Canvas{
AddingSquares asq = new AddingSquares();
   
@Override
public void paint(Graphics g){
    
    asq.Drawing(g);//срисовуем холст из AddingSquare
    System.out.println("maincanvas");
    }
    
}


package squares.adder;

//В данном классе вся логика происходит.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class AddingSquares {
    int ypos=10; //счётчик позиции
    MainScreen screen = new MainScreen();
 
        ArrayList<Square> list = new ArrayList<>();//создание списка квадратов
        {
        list.add(new Square(11));
        list.add(new Square(21));//мануальное добавление (для теста)
        }

        
    class upListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            
        list.add(new Square(ypos));    //добавление квадрата при нажатии кнопки
        ypos = ypos+10;    //ув. счётчик позиции
        screen.getget();
        System.out.println("up");
        }
    
    }
    
    class downListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            
        list.remove(list.size() - 1);  //удавление квадрата при нажатии кнопки  
        ypos = ypos-10;     //ум. счётчик позиции
        screen.getget();
        System.out.println("down");
        }
    
    }
    
   
    public void Drawing(Graphics g){
        /*прорисовка списка квадрата*/
        for (int i = 0; i < list.size()-1; i++) {
        g.setColor(Color.green);
        list.get(i).PaintSguare(g);
            System.out.println("draw");
        //Не работает for. Почему?
        }   
        list.get(1).PaintSguare(g);//работает ок
    
    } 
}


package squares.adder;

//В данном классе мы создаём и прорисовуем квадрат.

import java.awt.Graphics;
import static squares.adder.SquaresAdder.main;
import sun.java2d.loops.DrawRect;

public class Square {
int y;//у позиция 

    public Square(int y) {//конструктор, устанавливает у позицию
        this.y = y;    
        System.out.println("newsquare2");
    }

    
    public void PaintSguare(Graphics g){
        g.drawRect(0,y, 20, 10);//рисуем квадрат
        System.out.println("newsquare");
    }

}


run:
newsquare2
newsquare2
newsquare2
newsquare2  //мануальное добавление
redraw
repaint
mainscreen
newsquare
draw
newsquare
maincanvas
newsquare
draw
newsquare
maincanvas
newsquare2 // start input
up
newsquare2
up
newsquare2
up
down
down
down
down
down
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
 
 
Сообщения:595
класс MainScreen строчка 34. что ты курил, когда писал эту чушь?
 
 
Сообщения:8
Переключатель, экспериментировал.

Впрочем это неважно. Проблема в for loop.
 
 
Сообщения:595
дай угадаю: не реагирует на кнопки?
 
 
Сообщения:8
Почему, реагирует.
up
newsquare2
up
newsquare2
up
down
down
down
down


Даже прорисовует
list.get(1).PaintSguare(g);


for loop не работает.
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет