Использование repaint () в разных экземплярах классов на одной панели - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть класс рисования, который расширяет JPanel и имеет метод void, называемый Drawing с repaint().

public class draw extends JPanel {

    public draw(int position_x, int position_y, int width, int height) {
        positionx = position_x;
        positiony = position_y;
        this.width = width;
        this.height = height;
    }

    public void drawing() {

        repaint();
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(positionx, positiony, width, height);
    }
}

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

public class coin_launcher {

    public static void main(String[] args) {

        JFrame frame = new JFrame("Coin Launcher");
        frame.setVisible(true);
        frame.setSize(1920, 1080);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        draw object = new draw(2,2,100,2);
        frame.add(object);
        object.drawing();

        draw object2 = new draw(2,6,200,2);
        frame.add(object2);
        object2.drawing();
    }
}

Проблема в том, что когда я вызываю drawing() в обоих объектах, рисуется только один.Если использовать отладчик только его первый, если я не, его только второй.Мне нужно сделать 100 баров, но он буквально перерисовывает JPanel каждый раз, как я могу добавить разные классы рисования в один JPanel, не стирая остальные?

Ответы [ 2 ]

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

Этот ответ является очень простым и упрощенным примером

"у вас должен быть ОДИН компонент, который способен рисовать несколько столбцов, основываясь на данных, доступных от" модели "

, цитируемой из Ответ MadProgrammer.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class CoinLauncher {

    public static void main(String[] args) {

        JFrame frame = new JFrame("Coin Launcher");
        frame.setSize(920, 480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //data to be painted. for better implementation use a model class that 
        //encapsulates the data     
        Rectangle[] bars = {         
            new Rectangle(2,2,100,2),
            new Rectangle(2,6,200,2),
        };

        Draw object = new Draw(Arrays.asList(bars));
        frame.add(object);
        frame.setVisible(true);
    }
}

class Draw extends JPanel {

    private final List<Rectangle> bars;

     Draw(List<Rectangle> bars) {
         this.bars = bars;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        for(Rectangle bar : bars){
            g.fillRect(bar.x, bar.y, bar.width, bar.height);
        }
    }
}

Реализация модели для инкапсуляции данных, необходимых для представления, может быть простой:

public class CoinLauncher {

    public static void main(String[] args) {

        JFrame frame = new JFrame("Coin Launcher");
        frame.setSize(920, 480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Model model = new Model();
        model.addBar( new Rectangle(2,2,100,2) );
        model.addBar( new Rectangle(2,6,200,2) );

        Draw object = new Draw(model);
        frame.add(object);
        frame.setVisible(true);
    }
}

class Draw extends JPanel {

    private final List<Rectangle> bars;

     Draw(Model model) {
         bars = model.getBars();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        for(Rectangle bar : bars){
            g.fillRect(bar.x, bar.y, bar.width, bar.height);
        }
    }
}

class Model {

    private final List<Rectangle> bars;

    Model(){
        bars = new ArrayList<>();
    }

    void addBar(Rectangle rectangle){
        bars.add(rectangle);
    }

    List<Rectangle> getBars() { return bars; }
}
0 голосов
/ 21 декабря 2018

JFrame по умолчанию использует BorderLayout, это означает, что макет будет управлять только последним добавленным компонентом (в центральную позицию по умолчанию).

См. BorderLayout для более подробной информации.

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

Вместо этого у вас должен быть ОДИН компонент, который способенрисовать несколько столбцов, основываясь на данных, доступных из «модели»

Это отделяет источник данных от представления данных, позволяя создавать несколько различных их реализаций, которые не должны нарушатьпрочее.

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

Подробнее см. Model-View-Controller

...