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
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...

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

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...
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.
来源:https://stackoverflow.com/questions/27974966/moving-jpasswordfield-to-absolute-position