简体   繁体   中英

Why does the following code only work with GridLayout?

When I add BorderLayout or FlowLayout then I am not able to draw any kind of graphics on Canvas . Although it works fine with GridLayout but the interface is not so good. Even if I try with setBounds I get the same result as with border and flow layout. Can anyone give me some suggestions regarding this problem?

//Why does the following code not work with FlowLayout??
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Mycanvas1 extends Canvas
{
  int flag=0;
  public void paint(Graphics g)
  {
    if(flag==1)
    {
      g.setColor(Color.pink);
      g.drawRoundRect(30,30,100,100,20,20);
      g.setColor(Color.blue);
      g.drawString("Anks",67,75);
      g.drawOval(100,130,15,15);
      g.drawOval(50,130,15,15);
    }
  }
}
class Myf2 implements ActionListener
{
  Mycanvas1 m=new Mycanvas1();
  Myf2()
  {
    JFrame f=new JFrame("Graphics");
    Button b=new Button("Line");
    //b.setBounds(400,400,41,41);
    b.addActionListener(this);
    f.add(m);
    f.add(b);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(400,400);
    f.setLayout(new GridLayout());
    f.setVisible(true);
  }
  public void actionPerformed(ActionEvent e)
  {
    m.flag=1;   
    m.repaint();
  }
  public static void main(String... s)
  {
    new Myf2();
  }
}
class Mycanvas1 extends Canvas

AFAIR a Canvas has a default size of 0x0 pixels. @Override the getPreferredSize() method to return a sensible value that might be honored by the layout.

Here's what I mean, using FlowLayout .

在此处输入图片说明

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Mycanvas1 extends Canvas {

    int flag = 0;

    Mycanvas1() {
        // so we can easily see its bounds
        setBackground(Color.WHITE);
    }

    public void paint(Graphics g) {
        super.paint(g); // honor the paint chain..
        if (flag == 1) {
            g.setColor(Color.pink);
            g.drawRoundRect(30, 30, 100, 100, 20, 20);
            g.setColor(Color.blue);
            g.drawString("Anks", 67, 75);
            g.drawOval(100, 130, 15, 15);
            g.drawOval(50, 130, 15, 15);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(150,150);
    }
}

class Myf2 implements ActionListener {

    Mycanvas1 m = new Mycanvas1();

    Myf2() {
        JFrame f = new JFrame("Graphics");
        // best done before adding components
        f.setLayout(new FlowLayout()); 
        Button b = new Button("Line");
        b.addActionListener(this);
        f.add(m);
        f.add(b);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //f.setSize(400, 400); // no, don't guess, instead..
        f.pack();
        f.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        m.flag = 1;
        m.repaint();
    }

    public static void main(String... s) {
        new Myf2();
    }
}

If you don't let the Canvas to have a size then this may cause problems depending on the Layout .

FlowLayout does not resize its subcomponents, it just let them determine their own size (default 0,0 for Canvas ) and place them in the space of the Container from left to right and then top to bottom.

BorderLayout resizes the subcomponents but you need to use the BorderLayout constraints: NORTH , etc. The default constraints is CENTER but it is wrong to add two components in the same BorderLayout 's logical space.

GridLayout resizes its components in such a way that every component have the same size (a rectangle), they are placed in a logical grid, etc. And the logical grid fills all the space of its Container host.

So, add a Dimension getPreferredSize() method to your component that returns the "natural" size of your drawing inside. This will let your component behave much more normally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM