Рисование нескольких прямоугольников с помощью Java (awt) - PullRequest
1 голос
/ 15 января 2010

Вот мой код:

class Ramka extends JFrame
    {
    public static final int SZEROKOSC = 800;
    public static final int WYSOKOSC = 600;
    Container powZawartosci = getContentPane();
    public Ramka()
        {
        setSize(SZEROKOSC, WYSOKOSC);
        setTitle("Siatka bryły by Paweł Mysior");
        }
    public void addRectangle(int startX, int startY, int sizeX)
        {
        drawRectangle rect = new drawRectangle(startX, startY, sizeX);
        powZawartosci.add(rect);
        }  

class drawRectangle extends JPanel
    {
    private int a, startX, startY;
    public drawRectangle(int startX, int startY, int a) // square
        {
        this.a = a;
        this.startX = startX;
        this.startY = startY;
        }
    public void paintComponent(Graphics g)
        {
        Rectangle2D rect = new Rectangle2D.Double(startX, startY, a, a);
        Graphics2D g1 = (Graphics2D) g;
        g1.draw(rect);
        }
    }

public class Main
    {
    public static void main(String[] args)
        {
        Ramka ramka = new Ramka();
        ramka.addRectangle(200, 200, 50);
        ramka.addRectangle(100, 100, 100);
        ramka.addRectangle(300, 300, 150);
        ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ramka.setVisible(true);
        }
    }

Что я хочу сделать, так это нарисовать три прямоугольника (оставив в стороне функциональность и смысл этого, я все еще только учусь).

Но он рисует только последний, начиная с 300 и 300. Я не совсем понимаю, что такое paintComponent ...

Заранее спасибо за любую помощь, Пол

Ответы [ 2 ]

1 голос
/ 15 января 2010

Проблема в основном в том, что вы используете два разных уровня абстракции здесь.

Во-первых, вы добавляете компонент в свой JFrame, что в какой-то момент нормально.

Вы добавляете свой экземпляр DrawRectangle, точно так же, как вы добавляете новую кнопку, метку или другую панель. Проблема возникает, когда вы добавляете компоненты в одну и ту же позицию. Главная панель JFrame (панель содержимого) использует Менеджер макета «Граница» , который помещает компонент в середину, если вы не добавляете никаких ограничений.

Для удобства BorderLayout интерпретирует отсутствие спецификации строки так же, как константа CENTER

alt text

Итак, эта строка:

powZawartosci.add(rect);

Всегда добавляет ваш компонент в «центр», переопределяя предыдущий. Вот почему вы видели только один прямоугольник.

Второй уровень абстракции, используемый здесь, это рисование компонента самостоятельно. Это низкий уровень, и вы должны указать компоненту, кто и где будет рисовать каждую линию.

Это нормально, но если вы хотите нарисовать несколько прямоугольников в одном и том же компоненте, вы должны хранить ссылки для каждого из них (используя коллекцию, подобную списку), а затем выполнить итерацию этой коллекции и нарисовать их все.

Как это:

много http://img40.imageshack.us/img40/8125/capturadepantalla201001nd.png

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

Обратите внимание также на стиль именования / фигурных скобок, хотя он не является обязательным, он распространен при программировании на Java

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;

class Ramka extends JFrame {
    public static final int SZEROKOSC = 800;
    public static final int WYSOKOSC = 600;
    Container powZawartosci = getContentPane();
    DrawRectangle rectangle = new DrawRectangle();
    public Ramka() {
        setSize(SZEROKOSC, WYSOKOSC);
        setTitle("Siatka bryły by Paweł Mysior");
        powZawartosci.add( new JLabel("Several rectangles are being displayed"), BorderLayout.NORTH );
        powZawartosci.add(rectangle);
    }
    public void addRectangle(int startX, int startY, int sizeX) {
        this.rectangle.addRectangle( startY, startY, sizeX );
    }

}  

class DrawRectangle extends JPanel {
    private java.util.List<Rectangle2D> squares;
    //private int a, startX, startY;
    public DrawRectangle(){
        squares = new ArrayList<Rectangle2D>();
    }

    public void addRectangle(int startX, int startY, int a)  { // square
        squares.add( new Rectangle2D.Double(startX, startY, a, a) ) ;
        //this.a = a;
        //this.startX = startX;
        //this.startY = startY;
    }
    public void paintComponent(Graphics g) {
        Graphics2D g1 = (Graphics2D) g;
        for( Rectangle2D rect : squares ) {
            g1.draw(rect);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Ramka ramka = new Ramka();
        //ramka.addRectangle(200, 200, 50);
        //ramka.addRectangle(100, 100, 100);
        //ramka.addRectangle(300, 300, 150);
        for( int i = 0 ; i < 20 ; i++ ){
            ramka.addRectangle( i * 10 , i * 10 , i * 20 );
        } 
        ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ramka.setVisible(true);
    }
}
1 голос
/ 15 января 2010

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

Проверьте эту ссылку и попробуйте научиться. Код, приведенный ниже, должен помочь.

...
Container powZawartosci = getContentPane();
public Ramka()
    {
    setSize(SZEROKOSC, WYSOKOSC);
    setTitle("Siatka bryły by Paweł Mysior");
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));//Only this line is inserted.
    }
public void addRectangle(int startX, int startY, int sizeX)
    {
    drawRectangle rect = new drawRectangle(startX, startY, sizeX);
    powZawartosci.add(rect);
    }  
...

В вашей производной JPanel вы можете отслеживать Rectangle s, которые вам нужно нарисовать. Я пишу код ниже, спонтанно, поэтому сначала проверьте ошибки.

class RectangleDrawer extends JPanel{
    ArrayList<Rectangle> rList = new ArrayList()<Rectangle>;
    public void addRectangle(Rectangle rect){
        rList.add(rect);
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for(int i=0; i<rList.size(); r++){
            g.drawRectangle(rList.get(i));
        }
    }
}
...