Как рисовать компоненты в слоях в Java? - PullRequest
0 голосов
/ 30 декабря 2018

У меня большая проблема с кодированием графической части моего приложения, где мне нужно, чтобы компоненты располагались один над другим:

  1. Сначала у меня есть JFrame (с фиксированным размером)

  2. В нем у меня есть два JPanel компонента.Я хочу, чтобы у них был цветной фон.Это простая часть.

  3. На одном из JPanel компонентов я хочу нарисовать фиксированные фигуры - прямоугольники, полосы и т. Д. Здесь у меня проблема, что у меня есть два класса: одинрасширяет JPanel и является фоном для этой части, а вторая расширяет JComponent и представляет элемент I Draw (есть несколько элементов).Я не знаю, как рисовать элементы в JPanel - я пробовал несколько методов, но ничего не появилось.Для меня важно, чтобы компоненты J были нарисованы и соединены только с этим JPanel, а не с целым кадром.

  4. Кроме того, я хочу иметь движущиеся фигуры.Это легко, когда у меня есть только рамка и, скажем, прямоугольник, потому что я меняю только положение и вызываю метод repaint(), но как сделать так, чтобы движущиеся фигуры были связаны и находились внутри JPanel и оставляли предыдущие слои в ихplace?

Для своих попыток я создал несколько классов с прямоугольниками:

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

public class Main{
    public Main() {
        JFrame frame = new JFrame();
        frame.setSize(1200, 900);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        JPanel background = new JPanel();
        background.setBackground(Color.lightGray);

        GreenRect gr = new GreenRect();
        gr.setPreferredSize(new Dimension(500,800));
        background.add(gr, BorderLayout.WEST);


        RedRect rr = new RedRect();
        rr.setPreferredSize(new Dimension(500,800));
        background.add(rr, BorderLayout.EAST);

        frame.add(background);
    }

    public static void main(String[] args) {
        new Main();
    }
}

class GreenRect extends JPanel {
    ArrayList<BlackRect> r = new ArrayList<>();
    ArrayList<MovingRec> m = new ArrayList<>();

   public GreenRect() {
       setBackground(Color.green);
       addRec(10,10);
       addRec(50,50);
       addRec(100,100);
       addRec(1000,1000);
   }

   public void addRec(int x, int y) {
       r.add(new BlackRect(x,y));
   }
}


class RedRect extends JPanel {
    public RedRect() {
        setBackground(Color.red);
    }
}

class BlackRect extends JComponent {
    int x, y;
    int w = 100, h = 100;

    public BlackRect (int x, int y){
        this.x = x;
        this.y = y;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponents(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        g2d.fillRect(x, y, w, h);
    }
}

class MovingRec  extends JComponent {
    int x, y;
    int w = 20, h = 20;

    public MovingRec (int x, int y){
        this.x = x;
        this.y = y;
    }

    public void paintComponent(Graphics g) {
        super.paintComponents(g);

        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLUE);
        g2d.fillRect(x, y, w, h);
    }

    public void update() {
        x += 5;
        y += 5;
    }
}

и теперь у меня проблемы с точками 3 и 4, потому что я не могу разместитьчерные прямоугольники на заднем плане и движущиеся прямоугольники сверху.

Буду благодарен за любую помощь:)

1 Ответ

0 голосов
/ 31 декабря 2018

Вам не нужно (и не следует) расширять BlackRect и MovingRect с JComponent.

Например, BlackRect может быть простым объектом, например:

class BlackRect {
    int x, y;
    int w = 100, h = 100;

    public BlackRect(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void paint(Graphics2D g2d) {
        g2d.setColor(Color.BLACK);
        g2d.fillRect(x, y, w, h);
    }
}

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

public GreenRect extends JPanel {
    // Existing members 

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

        Graphics2D g2d = (Graphics2D) g;

        for (BlackRect black_rect : r) {
            black_rect.paint(g2d);
        }

        // Also paint list of moving rectangles here
    }
}

Когда вызывается GreenRect.repaint(), он закрашивает свой фон, и все прямоугольники изrm список при добавлении этого кода).Если у прямоугольников m обновлены их позиции, они будут нарисованы на своих новых позициях, поэтому они будут двигаться.Поскольку движущиеся прямоугольники рисуются последними, они будут отображаться «сверху».

Используйте Swing Timer для управления анимацией.Когда таймер истекает, он должен слегка переместить все движущиеся прямоугольники (например, позвонить MovingRec.update()) и вызвать repaint() на GreenRect.

...