2

を拡張するクラスを作成しJPanel、毎回サイズを設定しています。しかし今、そのJPanelサブクラスの複数のインスタンスが別のパネルに存在する必要があります。を使用していますが、 のサイズを変更したり、サブクラスからを削除したりするGridBagLayoutと、コンポーネントが消えます。これらに従うコンポーネントを構築するにはどうすればよいですか?FramesetSize(800,100)JPanellayout managers

カスタム コンポーネントを、レイアウト マネージャーが要求するサイズに合わせられるようにしたいと考えています。

ここに私のカスタムコンポーネントがあります

public class GridPanel extends JPanel implements MouseMotionListener, MouseListener{
    private Rectangle offdutyRect, sbRect, driveRect, onRect;
    private int delta = 60;
    private int[][] gridArray;
    int draggedStartX = -1;
    int draggedStartY = -1;
    private int dutyStatusSpacing = 60;
    private int totalSpacing = 80;

    public GridPanel(){
    super();
    this.setSize(new Dimension(800, 100));//without this it doesn't display
    this.addMouseMotionListener((MouseMotionListener) this);
    this.addMouseListener(this);
    int gridArrayColumns = 24*60/delta;
    gridArray = new int[4][gridArrayColumns];

    int r = 0;
    int rHeight = this.getHeight()/4;
    offdutyRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
    r++;
    sbRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
    r++;
    driveRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);
    r++;
    onRect = new Rectangle(this.getX() + dutyStatusSpacing, this.getY() + r*rHeight, this.getWidth() - totalSpacing, rHeight);

    Rectangle rect = null;
    for(r = 0; r < gridArray.length; r++){
        if(r == 0){
        rect = offdutyRect;
        }else if(r == 1){
        rect = sbRect;
        }else if(r == 2){
        rect = driveRect;
        }else if(r == 3){
        rect = onRect;
        }

        //I haven't actually derived any of these things, just my best guesses.
        int len = gridArray[r].length;
        int width = (int) (rect.getWidth()/len);
        rect.setSize((int)(width*len), (int) rect.getHeight());
    }

    }

    public void paintComponent(Graphics g){
    g.clearRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
    //the center black bar for duty status "placeholders"
    g.setColor(Color.black);
    g.drawRect(getX(), getY(), getWidth() - 1, getHeight() - 1);
    g.drawRect((int)offdutyRect.getX(), (int)offdutyRect.getY() + (int)offdutyRect.getHeight()/2, (int)offdutyRect.getWidth(), 1);
    g.drawRect((int)sbRect.getX(), (int)sbRect.getY() + (int)sbRect.getHeight()/2, (int)sbRect.getWidth(), 1);
    g.drawRect((int)driveRect.getX(), (int)driveRect.getY() + (int)driveRect.getHeight()/2, (int)driveRect.getWidth(), 1);
    g.drawRect((int)onRect.getX(), (int)onRect.getY() + (int)onRect.getHeight()/2, (int)onRect.getWidth(), 1);
    g.setColor(Color.pink);
    g.drawRect((int)offdutyRect.getX(), (int)offdutyRect.getY(), (int)offdutyRect.getWidth(), (int)offdutyRect.getHeight());
    g.drawRect((int)sbRect.getX(), (int)sbRect.getY(), (int)sbRect.getWidth(), (int)sbRect.getHeight());
    g.drawRect((int)driveRect.getX(), (int)driveRect.getY(), (int)driveRect.getWidth(), (int)driveRect.getHeight());
    g.drawRect((int)onRect.getX(), (int)onRect.getY(), (int)onRect.getWidth(), (int)onRect.getHeight());

    //draw the array
    g.setColor(Color.green);
    Rectangle rect = null;
    for(int r = 0; r < gridArray.length; r++){
        if(r == 0){
        rect = offdutyRect;
        }else if(r == 1){
        rect = sbRect;
        }else if(r == 2){
        rect = driveRect;
        }else if(r == 3){
        rect = onRect;
        }

        //I haven't actually derived any of these things, just my best guesses.
        int len = gridArray[r].length;
        int width = (int) (rect.getWidth()/len);

        int height = (int) rect.getHeight() - 2;
        for(int c = 0; c < gridArray[r].length; c++){
        if(gridArray[r][c] == 1){
                int x = (int) (rect.getX() + width*c);
                int y = (int) rect.getY() + 2;
                g.fillRect(x, y, width, height);
        }
        }
    }
    }

そして、これがgridbagを使用してコンテナに追加する方法です

public void actionPerformed(ActionEvent e) {
System.out.println("action performed"  +  panels.size());
removeAll();
repaint();
panels.add(new GridPanel());
int r = 0;
GridBagConstraints c = new GridBagConstraints();
for(int i = 0; i < panels.size(); i++){
        JLabel label = new JLabel("day " + i);
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = r;
        this.add(label, c);
        r++;

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = r;
        c.fill = GridBagConstraints.HORIZONTAL;
        this.add(panels.get(i), c);
        r++;
}

c = new GridBagConstraints();
c.gridx = 0;
c.gridy = r;
c.fill = GridBagConstraints.HORIZONTAL;
BufferedImage img = null;
try {
    img = ImageIO.read(this.getClass().getResource("/res/add.png"));
} catch (IOException ex) { }
JButton addButton = new JButton();
addButton.setIcon(new ImageIcon(img));
addButton.addActionListener(this);


 this.add(addButton, c);


    }

追加するはずのこの「実行されたアクション」を実行すると、カスタムコンポーネントが左上隅に表示されますが、すべてのコンポーネントを表示するにはウィンドウのサイズを変更する必要があります。

4

1 に答える 1

4

多くのレイアウト マネージャーはgetPreferredSizegetMinimumSizeおよびによって返される値を利用しますgetMaximumSize

GridBagLayout一般に、可能であれば、3 つすべてを尊重しようとするものの 1 つです。

カスタム コンポーネントで、(少なくとも)getPreferredSizeメソッドをオーバーライドし、わかる範囲で、必要なコンポーネントのサイズを返します。

コンポーネントが他のコンポーネントを含むレイアウト マネージャーを使用している場合は、常にレイアウト マネージャーにこの決定を行わせる必要があります (これがデフォルトの動作です)。

更新しました

revalidateコンポーネントを追加または削除するときは、コンテナ階層のレイアウトを強制的に更新するために呼び出す必要がある場合があることを忘れないでください

于 2013-07-04T00:45:47.403 に答える