在一个面板的不同类实例中使用repaint()

时间:2018-12-20 20:36:01

标签: java graphics jpanel repaint

我有一个draw类,该类扩展了JPanel并具有一个名为draw的void方法,其中带有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 :(得分:1)

JFrame默认情况下使用BorderLayout,这意味着布局将仅管理最后添加的组件(到默认的中心位置)。

有关更多详细信息,请参见BorderLayout

一个直接的解决方案可能是使用其他布局管理器,但是我认为这是错误的解决方案。

相反,您应该有一个组件,它可以根据“模型”中的可用数据绘制多个条形

这将数据源与数据表示分离开来,从而可以产生多种不同的实现方式,而这不会破坏另一个实现方式。

在这种情况下,“视图”不必关心数据是如何获得或保存的,仅是它符合指定的合同即可,就像明智的做法是,数据不在乎其呈现方式。

有关更多详细信息,请参见Model-View-Controller

答案 1 :(得分:0)

此答案是

的非常基本且简化的示例
  

”您应该具有一个组件,该组件能够绘制多个   条,基于“模型”中可用的数据

引自MadProgrammer's answer

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; }
}