Search code examples
javaswingparameter-passingjcomponentsetbounds

How do I modify the setBounds method for JComponents?


I wish to create a certain method that can help speed me up in GUI design. I take longest in using setBounds. Now, I would just go for FlowLayout or GridLayout but I don't like being to reliant on those.

Basically, I am thinking of a method like placeAbove, which places a JComponent above another JComponent. Its arguments would be the reference point JComponent and an integer for their distance from each other. I am currently having success with the following:

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

public class BoundBender extends JFrame {
    public BoundBender() {
        Container c = getContentPane();
        c.setLayout(null);

        JLabel l1 = new JLabel("Reference Point");
        JLabel l2 = new JLabel("Above Label");
        JLabel l3 = new JLabel("Below Label");
        JLabel l4 = new JLabel("Before Label");
        JLabel l5 = new JLabel("After Label");

        c.add(l1);
        l1.setBounds(170, 170, 100, 20);
        c.add(l2);
        placeAbove(l1, 0, l2);
        c.add(l3);
        placeBelow(l1, 10, l3);
        c.add(l4);
        placeBefore(l1, 20, l4);
        c.add(l5);
        placeAfter(l1, 30, l5);

        setVisible(true);
        setSize(500, 500);
    }
    public static void main (String args[]) {
        BoundBender bb = new BoundBender();
        bb.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void placeAbove(JComponent j, int a, JComponent k) {
        int x= j.getX();
        int y= j.getY();
        int w= j.getWidth();
        int h= j.getHeight();

        y=(y-h)-a;

        k.setBounds(x, y, w, h);
    }
    public static void placeBelow(JComponent j, int a, JComponent k) {
        int x= j.getX();
        int y= j.getY();
        int w= j.getWidth();
        int h= j.getHeight();

        y=y+h+a;

        k.setBounds(x, y, w, h);
    }
    public static void placeBefore(JComponent j, int a, JComponent k) {
        int x= j.getX();
        int y= j.getY();
        int w= j.getWidth();
        int h= j.getHeight();

        x=(x-w)-a;

        k.setBounds(x, y, w, h);
    }
    public static void placeAfter(JComponent j, int a, JComponent k) {
        int x= j.getX();
        int y= j.getY();
        int w= j.getWidth();
        int h= j.getHeight();

        x=x+w+a;

        k.setBounds(x, y, w, h);
    }
}

However, I want to make it as simple as l2.placeAbove(l1, 0), because that third argument feels inefficient. So any suggestions? And please use understandable terminologies.


Solution

  • Then use the return value thereof. Instead of being void return an instance of Rectangle. It would look something like:

        public static Rectangle placeAbove(JComponent j, int a) {
        int x= j.getX();
        int y= j.getY();
        int w= j.getWidth();
        int h= j.getHeight();
    
        y=(y-h)-a;
    
        //return our new bounds projected in a Rectangle Object
        return new Rectangle(x, y, w, h); 
    }
    

    And then the use case would be setting the bordering Rectangle:

    k.setBounds(placeAbove(j, a));
    

    That way you use the setBounds(Rectangle r) inherited from java.awt.Component in JComponent.

    Hope this helps!