Java JPasswordField位于图像顶部

Java JPasswordField位于图像顶部,java,swing,user-interface,jframe,jlabel,Java,Swing,User Interface,Jframe,Jlabel,我有这段代码,它创建了一个Jframe,我在其中添加了一个带有图片和JpasswordField的JLabel。我希望JpasswordField位于图像顶部,但这仅取决于我在哪里执行f。添加我会显示其中一个字段或不显示其中一个。。。我希望JpasswordField位于图片顶部,允许用户引入密码,但以图片为背景 代码如下: package java; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.

我有这段代码,它创建了一个Jframe,我在其中添加了一个带有图片和JpasswordField的JLabel。我希望JpasswordField位于图像顶部,但这仅取决于我在哪里执行
f。添加
我会显示其中一个字段或不显示其中一个。。。我希望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
    methd中将图像绘制为背景图像
  • 将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(空)
,则此调用无效:
f.setBounds(0,0,screenSize.width-5,screenSize.height-100)


我马上就去做。我会把代码贴在这里,如果有问题,我会告诉你。老实说,这是我第一次编写GUI程序。无论如何,我的程序的一个重要的事情是,它应该总是在顶部,没有菜单栏与关闭,最小化和最大化按钮。我能照你说的做吗?谢谢,我真的很想做,但我不知道如何开始…:(你能写一小段代码,我可以用它作为基础吗?我会接受有效的回答,我会用代码来让它工作。谢谢!!嗨。我让它工作了,但我不能将JpasswordField移动到随机的X,Y位置。我该怎么做?)谢谢you@RyanFold当前位置这是一个完全不同的问题,我邀请你在这个网站上提出一个关于它的新问题,但简短而错误的答案是将JPanel的布局设置为
null
,并设置带有
setBounds(…)的组件的绝对位置
。这是错误的,因为使用绝对定位的GUI在除原始版本以外的所有操作系统平台上看起来都很糟糕。而且它们非常难以维护和增强。正确的答案是学习如何使用布局管理器,然后再使用布局管理器。我喜欢您的解决方案,但它会显示菜单栏(使用“关闭”、“最小化”和“最大化”按钮)。即使我尝试执行“frame.setUndecorated”(真)59440在大小上,只需从图像缩放中删除
*2/3
,就可以了。如果我更改了,它不会最大化:(
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();
                }
            }
        });
    }

}