Charl Du Plessis
Charl Du Plessis

Reputation: 21

How do I change the position of JLabel or any other Component I add?

I am trying to create a translucent window which has no border or background other than the JLabel image's I put in it, using OverlayLayout and an extended JPanel...

My problem is when I try to add more components over the one I initially added which would be the background, I have no idea how to enable changing of the new components position.. x,y etc...

Please if possible show me what I can do and don't just point me to layoutmanagers, I need an example please if anyone is willing to show me.

Or better yet, show me what I need to do to my code in order to get the desired effect.. like changing "text" (A JLabel) position to be 10,10 ... x and y.

package core;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.OverlayLayout;

public class App {
    // Window & Panel...
    public JWindow frame;
    public TranslucentPanel panel;

    // OverlayLayout
    public LayoutManager overlay;

    // Components
    public JLabel bg;
    public JLabel test;

    // Constructor
    public App() {
        try {
            // Basics...
            frame = new JWindow();
            frame.setBackground(new Color(0, 0, 0, 0));

            // Overlay
            panel = new TranslucentPanel();
            overlay = new OverlayLayout(panel);
            panel.setLayout(overlay);
            frame.setContentPane(panel);

            // initComponents
            initComponents();

            // Finalize Frame
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    // Initialize Additional Components
    public void initComponents() throws Exception {
        test = new JLabel("test");
        test.setForeground(Color.WHITE);
        frame.add(test);

        bg = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/ball.png"))));
        frame.add(bg);

        // What must I do to be able to do this???
        test.setLocation(10, 0);
    }

    // TranslucentPanel Class...
    public class TranslucentPanel extends JPanel {
        private static final long serialVersionUID = 1L;

        public TranslucentPanel() {
            setOpaque(false);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f));
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }
    }
}

Upvotes: 2

Views: 2339

Answers (2)

Fevly Pallar
Fevly Pallar

Reputation: 3099

After reading the following pieces from your codes :

// What must I do to be able to do this???
    test.setLocation(10, 0);

If I understand correctly , you want to arrange position of your component based on custom coordinates. If so then You can use Insets class http://docs.oracle.com/javase/7/docs/api/java/awt/Insets.html to achieve that. So you can set position of your component according to position you want

     Insets insets = panel.getInsets();
    Dimension size =test.getPreferredSize();

   // just replace 10 & 0 according to X & Y postion you want.
     test.setBounds(10 + insets.left, 0 + insets.top,size.width, size.height); 

Here is you modified version:

*Note that I don't have your Icon , so I just put text on your label to help you see the result.

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


public final class App{
    // Window & Panel...
    public JWindow frame;
    public TranslucentPanel  panel;

    // OverlayLayout
    public LayoutManager overlay;

    // Components
    public JLabel bg;
    public JLabel test;

    // Constructor
    public App() {
        try {
            // Basics...
            frame = new JWindow();
            // Overlay
            // Overlay
            panel = new TranslucentPanel();
            overlay = new OverlayLayout(panel);
            panel.setLayout(overlay);
            frame.add(panel);


            initComponents();
          // Finalize Frame
            frame.pack();
            frame.setSize(400,400);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
        catch(Exception e) { e.printStackTrace();}

    }

    // Initialize Additional Components
    public void initComponents() throws Exception {
        test = new JLabel("test");
        test.setForeground(Color.RED);

        panel.setLayout(null);
        panel.add(test);

        Insets insets = panel.getInsets();
        Dimension size =test.getPreferredSize();
        test.setBounds(10 + insets.left, 0 + insets.top,
                size.width, size.height);


        frame.add(panel);

    }

    // TranslucentPanel Class...
   class TranslucentPanel extends JPanel {
        private static final long serialVersionUID = 1L;

        public TranslucentPanel() {
            setOpaque(false);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D)g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f));
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }
    }


public static void main (String args []){

    App ap = new App();      

}  
}

The output :

enter image description here

If you declare your position as test.setBounds(500 + insets.left, 10 + insets.top,size.width, size.height); then the output would be :

enter image description here

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347184

One way would be to discard the Overlayout manager, set the TranslucentPanel's layout manager to something like BorderLayout and use the JLabel, bg as a container in of itself...

bg = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/ball.png"))));
frame.add(bg);

// Set the layout of the JLabel    
bg.setLayout(new GridBagLayout());
test = new JLabel("test");
test.setForeground(Color.WHITE);
// Add the test label to the bg JLabel...
bg.add(test);

Personally, I don't like this, as JLabel doesn't take into consideration the components (or the layout manager) when it makes it's calculations for it's preferred size.

Personally, I would create a custom background component that was responsible for painting the background image. Then, onto this, I would place the other components, using what ever combination of components and layout managers I need to produce the desired results.

Pixel perfect layouts are an illusion within modern UI design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

Upvotes: 3

Related Questions