views:

207

answers:

2

Hi everyone, I have a problem. I used Gridbaglayout in my JFrame. One of the component is JPanel.

I wanted to draw a gridline as a background for my JPanel. e.g in the program below, it supposed to produce 3 vertical and 3 horizontal lines, however it only shows 2 vertical and 2 horizontal line. the last line was not shown.

Another problem was that, it seems that the size of the JPanel was bigger that what I have set. I noticed this by the length of the line which is shorter that the JPanel white background.

  public class drawLayout extends JComponent 
    {

 public Dimension getPreferredSize() { 
  return new Dimension(600, 600); 
 }

 public int getY() { 
  return 0; 
 } 

 public int getX() { 
   return 0; 
    }

    @Override public void paintComponent(Graphics g)
    {
     g.setPaint(Color.GRAY);

            for (int i = 0; i <= getSize().width; i += 300) 
            {
               g2.drawLine(i, 0, i, getSize().height);
            }

            for (int i = 0; i <= getSize().height; i += 300) 
            {
               g2.drawLine(0,i, getSize().width, i);
            }
    } 
}

EDIT:

http://www.freeimagehosting.net/image.php?1af16edc28.jpg

The first problem solved (the gridlines were shown on JPanel). The other problem puzzled me. As you can see on the image attached, the size of the JPanel seems to be more than 600 when look at the length of the grid (marked as red box). How can I solve this so the gridline background look nice without any extra white space outside the gridline?

A: 

You are incrementing i by 300. After two itterations, i is 600, and you exit the for loop. Try setting your dimensions to 601 or increment by 299. You can also use width+1 and Height+1 in your comparison.

Andres
Thanks Andres. I have increased the dimension to 601 and it shows the last line. But I was wonder because I have set the restriction to i <= getSize().height which means it should in the loop for three times, which mean the third line should be paint.
Jessy
Carl said it below, but a dimension of 600 give a range from 0 to 599. Thus on the third itteration, i = 600, and width = 599. Therefore i > width.
Andres
Thanks Andres. One more question, why the JPanel look bigger? How can I make it showing only the exact size of 600 X 600?
Jessy
Leave the dimension at 600 and add the following two lines at the end of your paintComponent code: g2.drawLine(getSize().width, 0, getSize().width, getSize().height);g2.drawLine(getSize().height, 0, getSize().height, getSize().width);
Andres
Sorry about the formatting!
Andres
Go ahead and accept Carl's answer above.
Andres
+1  A: 

If your JPanel's size is 600, then its available coordinates only go from 0 to 599. The line at 600 isn't going to be drawn.

Also, any borders and/or insets would further reduce the available space.

Update: I had some time, so I wrote your application. Hopefully you will find some useful hints.

public class Jessy extends JFrame {

   private static final int DRAWING_SIZE = 600;
   private static final int SUBDIVISIONS = 2;
   private static final int SUBDIVISION_SIZE = DRAWING_SIZE / SUBDIVISIONS;

   public Jessy() {
      setSize(800, 800);
      setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.gridx = 0;
      gbc.gridy = 0;
      JLabel drawingBoard = new JLabel("Drawing Board");
      gbc.anchor = GridBagConstraints.SOUTH;
      drawingBoard.setFont(new Font("Serif", Font.BOLD, 28));
      add(drawingBoard, gbc);
      JPanel panel = new JPanel() {
         @Override public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(Color.GRAY);
            for (int i = 1; i < SUBDIVISIONS; i++) {
               int x = i * SUBDIVISION_SIZE;
               g2.drawLine(x, 0, x, getSize().height);
            }
            for (int i = 1; i < SUBDIVISIONS; i++) {
               int y = i * SUBDIVISION_SIZE;
               g2.drawLine(0, y, getSize().width, y);
            }
         }          
      };
      panel.setPreferredSize(new Dimension(DRAWING_SIZE, DRAWING_SIZE));
      panel.setBackground(Color.WHITE);
      panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
      gbc.gridy++;
      gbc.anchor = GridBagConstraints.CENTER;
      add(panel, gbc);
      JButton saveDrawing = new JButton("SAVE DRAWING");
      gbc.gridy++;
      gbc.anchor = GridBagConstraints.NORTH;
      add(saveDrawing, gbc);
   }
   public static void main(String[] args) {
      (new Jessy()).setVisible(true);
   }
}

Some details:

  • I used a Border for the outside lines, this saves us a bit of trouble with "599".
  • I assumed you wanted a subdivided grid on the inside so I added some plumbing for making that flexible and configurable.
  • I noticed your paintComponents() doesn't call super.paintComponents(). It should!
  • I used what I think to be the minimum required coding to specify the gridbag constraints. Less coding = less bugs :)
  • I subclassed a JPanel (in accordance with what you wrote) rather than a JComponent (in accordance with what's in your code). The difference seems to be that JComponent isn't able to draw its background, so that ended up gray.
  • Perhaps most importantly, I measured my GUI with kruler: The drawing component is exactly 600 in size both ways! :)
Carl Smotricz
Thanks for the answer Carl. My Jpanel looks bigger than 600. I used no border or insets.
Jessy
If it looks bigger than 600 but you didn't see 3rd lines, then the extra space is outside the panel. Either you have ipadx/ipady set non-0 or fill is NONE but there is some other component forcing your cell bigger. Simplest way to test this is to set your panel's background color so you can see where its edges are.
Carl Smotricz
Just for completeness, insets could also have been set in the GridBagConstraints. But that wouldn't explain your panel being > 600.
Carl Smotricz
I only just looked at your screenshot and find no explanation for what I see. Please show us your GUI code! Pastebin is probably a nice way to do this: <http://pastebin.com/>
Carl Smotricz
+1 For taking the extra time. @Jessy, you should accept this answer by clicking the green check box. It is only polite for someone who did so much work on your behalf.
Andres