-1

I have this code:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.*;

public class DialogExample extends JPanel {
   private static final int COLUMN_COUNT = 10;
   private static final int I_GAP = 3;
   public static final String BKG_IMG_PATH = "http://upload.wikimedia.org/wikipedia/commons/"
         + "thumb/9/92/Camels_in_Jordan_valley_%284568207363%29.jpg/800px-Camels_in_Jordan_valley_"
         + "%284568207363%29.jpg";

   private BufferedImage backgrndImage;
   private JTextField userNameField = new JTextField();
   private JPasswordField passwordField = new JPasswordField();
   private JPanel mainPanel = new JPanel(new GridBagLayout());
   private JButton okButton = new JButton("OK");
   private JButton cancelButton = new JButton("Cancel");

   public DialogExample(BufferedImage backgrndImage) {
      this.backgrndImage = backgrndImage;
      userNameField.setColumns(COLUMN_COUNT);
      passwordField.setColumns(COLUMN_COUNT);

      JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 5));
      btnPanel.setOpaque(false);
      btnPanel.add(okButton);
      btnPanel.add(cancelButton);

      GridBagConstraints gbc = getGbc(0, 0, GridBagConstraints.BOTH);
      mainPanel.add(createLabel("User Name", Color.white), gbc);
      gbc = getGbc(1, 0, GridBagConstraints.HORIZONTAL);
      mainPanel.add(userNameField, gbc);
      gbc = getGbc(0, 1, GridBagConstraints.BOTH);
      mainPanel.add(createLabel("Password:", Color.white), gbc);
      gbc = getGbc(1, 1, GridBagConstraints.HORIZONTAL);
      mainPanel.add(passwordField, gbc);
      gbc = getGbc(0, 2, GridBagConstraints.BOTH, 2, 1);
      mainPanel.add(btnPanel, gbc);

      mainPanel.setOpaque(false);
      add(mainPanel);
   }

   private JLabel createLabel(String text, Color color) {
      JLabel label = new JLabel(text);
      label.setForeground(color);
      return label;
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (backgrndImage != null) {
         g.drawImage(backgrndImage, 0, 0, this);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet() || backgrndImage == null) {
         return super.getPreferredSize();
      }
      int imgW = backgrndImage.getWidth();
      int imgH = backgrndImage.getHeight();
      return new Dimension(imgW, imgH);
   }

   public static GridBagConstraints getGbc(int x, int y, int fill) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = 1;
      gbc.gridheight = 1;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.insets = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
      gbc.fill = fill;

      return gbc;
   }

   public static GridBagConstraints getGbc(int x, int y, int fill, int width,
         int height) {
      GridBagConstraints gbc = getGbc(x, y, fill);
      gbc.gridwidth = width;
      gbc.gridheight = height;

      return gbc;
   }

   private static void createAndShowGui() throws IOException {
      final JFrame frame = new JFrame("Frame");

      final JDialog dialog = new JDialog(frame, "User Sign-In", ModalityType.APPLICATION_MODAL);
      URL imgUrl = new URL(BKG_IMG_PATH);
      BufferedImage img = ImageIO.read(imgUrl);
      final DialogExample dlgExample = new DialogExample(img);
      dialog.add(dlgExample);
      dialog.pack();

      JPanel mainPanel = new JPanel();
      mainPanel.add(new JButton(new AbstractAction("Please Press Me!") {

         @Override
         public void actionPerformed(ActionEvent e) {
            dialog.setVisible(true);
         }
      }));
      mainPanel.setPreferredSize(new Dimension(800, 650));

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            try {
               createAndShowGui();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      });
   }
}

Ho can I move the JPasswordField to a absolute position (X,Y)?? I've been trying different things like setPosition(int X, int Y) and nothing worked. I tryed playing too with the layout but not success either. I would like to have just a JPasswordField object and a button object on his right. that's it

Thank you

Ryan Fold
  • 181
  • 1
  • 3
  • 14
  • You could randomize the insets and border properties – MadProgrammer Jan 15 '15 at 23:41
  • I can't believe there is not an easy way just to set a position for a JtextField right? – Ryan Fold Jan 16 '15 at 01:11
  • If somebody give me an example of how to just put a JTextField in front of an image in a absolute position I will give that answer as valid. Thank you guys – Ryan Fold Jan 16 '15 at 01:14
  • 2
    The problem is, there is so much more to the problem then you are seeing. Every platform (and hardware combination) has the potential to render fonts and other graphical elements differently, changing the amount of space they require to be rendered, this is why we have layout managers and many UI toolkits use them. Simply wanting to place a component at a given position is less than 10% of the problem....thus the reason why you got the answer you did. Any answer involving simply calling `setLocation` or `setBounds` is, frankly, wrong. – MadProgrammer Jan 16 '15 at 01:17
  • @MadProgrammer thank you for your honest response. Can I get a snipset code to know how to start dealing with this? I can go from there even if Im using layout managers. Thank you – Ryan Fold Jan 16 '15 at 01:24
  • Regarding, "if somebody" -- I've already shown you how to place components over an image in your previous question, and you've yet to accept that answer as the solution of that specific problem. – Hovercraft Full Of Eels Jan 16 '15 at 01:37
  • @RyanFold You do realise that you've just asked two questions now; How to place components over a background image and how to place components at a random location. You might want to stop trying to find the answer you "want" and start exploring the answers that "work" - just saying – MadProgrammer Jan 16 '15 at 01:47

2 Answers2

4

Start by creating a panel for the password field and button to reside on. Next, randomise a EmptyBorder and the Insets of a GridBagConstraints to define different locations within the parent container. Add the password/button panel to this container with these randomised constraints...

Random Positions

public class TestPane extends JPanel {

    public TestPane() {

        Random rnd = new Random();

        JPanel panel = new JPanel();
        JPasswordField pf = new JPasswordField(10);
        JButton btn = new JButton("Login");
        panel.add(pf);
        panel.add(btn);

        panel.setBorder(new EmptyBorder(rnd.nextInt(10), rnd.nextInt(10), rnd.nextInt(10), rnd.nextInt(10)));
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(rnd.nextInt(100), rnd.nextInt(100), rnd.nextInt(100), rnd.nextInt(100));

        add(panel, gbc);

    }

}

The other choice would be to write your own custom layout manager...but if you can avoid it, the above example is MUCH simpler...

ps- You could randomise either the border OR the insets, maybe using a larger random range and get the same effect, I've simpler used both to demonstrate the point ;)

Updated with layout manager example

Random layout

public class TestPane extends BackgroundImagePane {

    public TestPane() throws IOException {

        super(ImageIO.read(new File("Path/to/your/image")));            

        Random rnd = new Random();

        JPanel panel = new JPanel();
        panel.setOpaque(false);
        JPasswordField pf = new JPasswordField(10);
        JButton btn = new JButton("Login");
        panel.add(pf);
        panel.add(btn);

        setLayout(new RandomLayoutManager());

        Dimension size = getPreferredSize();
        size.width -= panel.getPreferredSize().width;
        size.height -= panel.getPreferredSize().height;

        add(panel, new Point(rnd.nextInt(size.width), rnd.nextInt(size.height)));

    }

}

public class RandomLayoutManager implements LayoutManager2 {

    private Map<Component, Point> mapConstraints;

    public RandomLayoutManager() {
        mapConstraints = new WeakHashMap<>(25);
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void removeLayoutComponent(Component comp) {
        mapConstraints.remove(comp);
    }

    @Override
    public Dimension preferredLayoutSize(Container parent) {
        Area area = new Area();
        for (Component comp : mapConstraints.keySet()) {

            Point p = mapConstraints.get(comp);
            Rectangle bounds = new Rectangle(p, comp.getPreferredSize());
            area.add(new Area(bounds));

        }

        Rectangle bounds = area.getBounds();
        Dimension size = bounds.getSize();
        size.width += bounds.x;
        size.height += bounds.y;

        return size;

    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
        return preferredLayoutSize(parent);
    }

    @Override
    public void layoutContainer(Container parent) {
        for (Component comp : mapConstraints.keySet()) {
            Point p = mapConstraints.get(comp);
            comp.setLocation(p);
            comp.setSize(comp.getPreferredSize());
        }
    }

    @Override
    public void addLayoutComponent(Component comp, Object constraints) {
        if (constraints instanceof Point) {

            mapConstraints.put(comp, (Point) constraints);

        } else {

            throw new IllegalArgumentException("cannot add to layout: constraint must be a java.awt.Point");

        }
    }

    @Override
    public Dimension maximumLayoutSize(Container target) {
        return preferredLayoutSize(target);
    }

    @Override
    public float getLayoutAlignmentX(Container target) {
        return 0.5f;
    }

    @Override
    public float getLayoutAlignmentY(Container target) {
        return 0.5f;
    }

    @Override
    public void invalidateLayout(Container target) {
    }

}

public class BackgroundImagePane extends JPanel {

    private Image image;

    public BackgroundImagePane(Image img) {

        this.image = img;

    }

    @Override
    public Dimension getPreferredSize() {
        return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null) {
            int x = (getWidth() - image.getWidth(this)) / 2;
            int y = (getHeight() - image.getHeight(this)) / 2;
            g.drawImage(image, x, y, this);
        }
    }

}

The BackgroundImagePane is based on this example, allowing the background image panel to be the container for the field panel and you should be well on your way...

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Sorry, what I meant was to an absolute position. So I want it to be for example in the position (100,200). Thank you and sorry again for not being clear at the first moment – Ryan Fold Jan 16 '15 at 00:25
  • @RyanFold Avoid using `null` layouts, 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 – MadProgrammer Jan 16 '15 at 00:28
  • If you "really" want "absolute" positioning, then you will need to write your own layout manager. If you were, for example, to set the `insets` up to allow for a `top` position of `100` and a `left` position of `200`, you would get close to what you're seeking without breaking down the layout management API – MadProgrammer Jan 16 '15 at 00:29
  • Can you then help me out to write a layout?? thank you and sorry to bother you – Ryan Fold Jan 16 '15 at 00:30
  • 1
    I told him all of this previously. Hopefully he'll take it to heart. – Hovercraft Full Of Eels Jan 16 '15 at 01:33
  • @HovercraftFullOfEels Horse + Water = drowned horse – MadProgrammer Jan 16 '15 at 01:43
0

You could use a null layout, but that takes too long and it doesn't re-size with the frame. Like this:

public class TestPane{

public static void main (String[] args) {

    Random rnd = new Random();

    JFrame frame = new JFrame();
    JPasswordField pf = new JPasswordField();
    JButton btn = new JButton("Login");
    frame.setSize(500, 500);
    frame.setLayout(null);
    btn.setBounds(y, x, width, height);
    pf.setBounds(y, x, width, height);
    frame.add(btn);
    frame.add(pf);        
}

}

And that should work. If you want to use a null layout.

Caders117
  • 319
  • 3
  • 18
  • Avoid using `null` layouts, 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 – MadProgrammer Jan 16 '15 at 01:20
  • I agree with @MadProgrammer. This way leads only to misery. Imagine creating a complex GUI this way, then deciding that you need to add a new JRadioButton to a group of them in the middle. If you use null layouts, you'll have to manually fiddle with **every** component in the GUI to create your enhancement and then debug all the problems that this fiddling causes. If you use layout managers, you can sometimes do this with a line or two of code with very low risk of bugs. Just don't recommend this. Seriously. – Hovercraft Full Of Eels Jan 16 '15 at 01:35
  • +1 because this answer highlights `null` layout manager which enables absolute positioning (what OP asked) and is precisely what I expected the answer to OP's question to be. – Alex Mandelias Feb 19 '21 at 17:36