图像顶部的 JPasswordField
JPasswordField on top of Image
我有创建 Jframe 的代码,我在其中添加了带有图片的 JLabel 和 JpasswordField。我希望 JpasswordField 位于图像之上,但仅取决于我在哪里 f.add
我是否显示其中之一......我希望 JpasswordField 位于图片之上以允许用户引入密码,但以图片为背景。
代码如下:
package java;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
public class Java implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new Java());
}
@Override
public void run() {
JFrame f = new JFrame();
/*Keep on front*/
f.toFront();
f.repaint();
f.setAlwaysOnTop(true);
f.setExtendedState( f.getExtendedState()|JFrame.MAXIMIZED_BOTH );
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.setUndecorated(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setBounds(0,0,screenSize.width-5, screenSize.height-100);
double width = screenSize.getWidth();
double height = screenSize.getHeight();
System.out.println(width+" "+height);
BufferedImage myPicture = null;
try {
myPicture = ImageIO.read(new File("C:\image.jpg"));
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = myPicture.getScaledInstance((int)width, (int)height,Image.SCALE_SMOOTH);
JLabel picLabel = new JLabel(new ImageIcon(dimg));
JPasswordField myTextfield = new JPasswordField("Password");
myTextfield.setEchoChar('*'); // U+26AB
picLabel.setPreferredSize(screenSize);
picLabel.setVerticalAlignment(JLabel.BOTTOM);
/*Depending of who I add first the image or the JPasswordField is showed*/
f.add(myTextfield);
f.add(picLabel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
首先,您的代码应该面向创建 JPanel,并且您应该直接控制此 JPanel 的布局管理器。然后您可以在 JDialog 而不是 JFrame 中放置和显示 JPanel,因为您的大部分代码似乎都在尝试模拟对话框的操作(例如将其保持在顶部等)。
遗憾的是,您的一个大问题是您忽略了 JFrame 的 contentPane 正在使用的布局管理器,即 BorderLayout。通过以默认方式向其添加组件,您将掩盖之前添加到同一位置的所有内容。相反,我建议:
- 创建 JPanel
- 在 JPanel 的
paintComponent
方法中将您的图像绘制为背景图像。
- 将 JLabel 添加到 JPanel。
- 在 JDialog 而不是 JFrame 中显示 JPanel。
例如:
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();
}
}
});
}
}
仅举一个例子(在许多其他可能性中),这里有一个小片段展示了如何处理这个问题。
顺便说一句,当你调用 f.pack(); f.setLocationRelativeTo(null);
时,这个调用就没用了:f.setBounds(0,0,screenSize.width-5, screenSize.height-100);
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;
public class BasicSwingTest2 {
private JFrame frame;
protected void initUI() throws MalformedURLException {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
askForPassword();
}
private void askForPassword() {
final JDialog dialog = new JDialog(frame);
dialog.setResizable(false);
BufferedImage myPicture = null;
try {
myPicture = ImageIO
.read(new URL("http://images.all-free-download.com/images/graphiclarge/blue_abstract_background_310971.jpg"));
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = myPicture.getScaledInstance(Toolkit.getDefaultToolkit().getScreenSize().width * 2 / 3, Toolkit.getDefaultToolkit()
.getScreenSize().height * 2 / 3, Image.SCALE_SMOOTH);
JLabel picLabel = new JLabel(new ImageIcon(dimg));
picLabel.setLayout(new GridBagLayout());
final JPasswordField password = new JPasswordField(25);
password.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Password is " + new String(password.getPassword()));
dialog.setVisible(false);
}
});
picLabel.add(password);
dialog.add(picLabel);
dialog.setTitle("Enter your password");
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new BasicSwingTest2().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}
我有创建 Jframe 的代码,我在其中添加了带有图片的 JLabel 和 JpasswordField。我希望 JpasswordField 位于图像之上,但仅取决于我在哪里 f.add
我是否显示其中之一......我希望 JpasswordField 位于图片之上以允许用户引入密码,但以图片为背景。
代码如下:
package java;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
public class Java implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new Java());
}
@Override
public void run() {
JFrame f = new JFrame();
/*Keep on front*/
f.toFront();
f.repaint();
f.setAlwaysOnTop(true);
f.setExtendedState( f.getExtendedState()|JFrame.MAXIMIZED_BOTH );
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
f.setUndecorated(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
f.setBounds(0,0,screenSize.width-5, screenSize.height-100);
double width = screenSize.getWidth();
double height = screenSize.getHeight();
System.out.println(width+" "+height);
BufferedImage myPicture = null;
try {
myPicture = ImageIO.read(new File("C:\image.jpg"));
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = myPicture.getScaledInstance((int)width, (int)height,Image.SCALE_SMOOTH);
JLabel picLabel = new JLabel(new ImageIcon(dimg));
JPasswordField myTextfield = new JPasswordField("Password");
myTextfield.setEchoChar('*'); // U+26AB
picLabel.setPreferredSize(screenSize);
picLabel.setVerticalAlignment(JLabel.BOTTOM);
/*Depending of who I add first the image or the JPasswordField is showed*/
f.add(myTextfield);
f.add(picLabel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
首先,您的代码应该面向创建 JPanel,并且您应该直接控制此 JPanel 的布局管理器。然后您可以在 JDialog 而不是 JFrame 中放置和显示 JPanel,因为您的大部分代码似乎都在尝试模拟对话框的操作(例如将其保持在顶部等)。
遗憾的是,您的一个大问题是您忽略了 JFrame 的 contentPane 正在使用的布局管理器,即 BorderLayout。通过以默认方式向其添加组件,您将掩盖之前添加到同一位置的所有内容。相反,我建议:
- 创建 JPanel
- 在 JPanel 的
paintComponent
方法中将您的图像绘制为背景图像。 - 将 JLabel 添加到 JPanel。
- 在 JDialog 而不是 JFrame 中显示 JPanel。
例如:
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();
}
}
});
}
}
仅举一个例子(在许多其他可能性中),这里有一个小片段展示了如何处理这个问题。
顺便说一句,当你调用 f.pack(); f.setLocationRelativeTo(null);
时,这个调用就没用了:f.setBounds(0,0,screenSize.width-5, screenSize.height-100);
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;
public class BasicSwingTest2 {
private JFrame frame;
protected void initUI() throws MalformedURLException {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
askForPassword();
}
private void askForPassword() {
final JDialog dialog = new JDialog(frame);
dialog.setResizable(false);
BufferedImage myPicture = null;
try {
myPicture = ImageIO
.read(new URL("http://images.all-free-download.com/images/graphiclarge/blue_abstract_background_310971.jpg"));
} catch (IOException e1) {
e1.printStackTrace();
}
Image dimg = myPicture.getScaledInstance(Toolkit.getDefaultToolkit().getScreenSize().width * 2 / 3, Toolkit.getDefaultToolkit()
.getScreenSize().height * 2 / 3, Image.SCALE_SMOOTH);
JLabel picLabel = new JLabel(new ImageIcon(dimg));
picLabel.setLayout(new GridBagLayout());
final JPasswordField password = new JPasswordField(25);
password.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Password is " + new String(password.getPassword()));
dialog.setVisible(false);
}
});
picLabel.add(password);
dialog.add(picLabel);
dialog.setTitle("Enter your password");
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new BasicSwingTest2().initUI();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
}
}