How to align multiple textfields on a background image within a JOptionPane?

旧街凉风 提交于 2019-12-13 18:31:55

问题


I want to have multiple textfiled to be aligned in a customized order, so that they are on the top of the background image. I tried to use setBounds but it did not work:

import javax.swing.*;


    public class TestJP {


        public static void main(String[] args) {

                  JLabel myLabel = new JLabel();
                  myLabel.setIcon ( new ImageIcon("system\\myBackground.jpg"));
                  myLabel.setBounds(0,0,750,500);


                  JTextField login = new JTextField(5);
                  login.setBounds(50,50,20,100); // This does not work

                  JPasswordField password = new JPasswordField(5);
                  password.setBounds( 50, 70, 20, 100); // Doesn't help either

                  JPanel myPanel = new JPanel();
                  myPanel.add(myLabel);
                  myPanel.add(login);
                  myPanel.add(password);

                   int result = JOptionPane.showConfirmDialog(null, myPanel, 
               "Please Login", JOptionPane.OK_CANCEL_OPTION);

                 // etc

               }

        }

回答1:


Don't use setBounds(). Swing was designed to be used with layout managers.

You can add the text fields to the label by doing something like:

JLabel myLabel = new JLabel( new ImageIcon("system\\myBackground.jpg") );
mylabel.setLayout( new FlowLayout() );
mylabel.add(login);
mylabel.add(password);

Use the appropriate layout manager for the label to get the desired layout.




回答2:


"I tried to use setBounds but it did not work:"

  • Use the layout managers as that's what they're for. You can find the layout manager tutorial here.
  • Add a layout to the JLabel that is displaying the image.
  • Add your JTextFields to that JLabel.
  • Display the JLabel in your JOptionPane.

For more help, post an image of what you're trying to do.


Edit You state in a comment:

Thank You! I used setBounds many times in a contentPane ... It worked fine.

While as a newbie, you will find that setBounds and null layouts seem easier to work with, the longer you code with swing, the more involved your GUI's the more you'll find that null layouts will fail youy, will look terrible on different platform, will be inflexible and not allow you to update or improve your GUI later.

How come it doesn't work for JOptionPane? The regular Layout managers are not precise ... I do not want to use those: east, west

It has nothing to do with JOptionPane and all to do with how you're not creating your GUI correctly. Learn to use the layout managers and they will be easier to use.


Edit 2 For example:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.beans.Transient;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

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

public class GridBagEg {
   public static final String IMG_PATH = "https://duke.kenai.com/tshirts/.Midsize/Tshirt1997.png.png";

   private static void createAndShowGui() {
      BufferedImage img = null;
      try {
         URL imgUrl = new URL(IMG_PATH);
         img = ImageIO.read(imgUrl);
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
      PlayerEditorPanel playerEditorPane = new PlayerEditorPanel(img);

      int result = JOptionPane.showConfirmDialog(null, playerEditorPane,
            "Edit Player", JOptionPane.OK_CANCEL_OPTION,
            JOptionPane.PLAIN_MESSAGE);
      if (result == JOptionPane.OK_OPTION) {
         // TODO: do something with info

         for (PlayerEditorPanel.FieldTitle fieldTitle : 
            PlayerEditorPanel.FieldTitle.values()) {
            System.out.printf("%10s: %s%n", fieldTitle.getTitle(),
                  playerEditorPane.getFieldText(fieldTitle));
         }
      }
   }

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

@SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
   enum FieldTitle {
      NAME("Name"), SPEED("Speed"), STRENGTH("Strength");
      private String title;

      private FieldTitle(String title) {
         this.title = title;
      }

      public String getTitle() {
         return title;
      }
   };

   private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
   private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
   private static final double SCALE = 0.4;
   private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
   private BufferedImage backgroundImg = null;
   private int imgWidth;
   private int imgHeight;

   public PlayerEditorPanel(BufferedImage img) {
      this.backgroundImg = img;
      imgWidth = (int) (backgroundImg.getWidth() * SCALE);
      imgHeight = (int) (backgroundImg.getHeight() * SCALE);

      setLayout(new GridBagLayout());
      setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Player Editor"),
            BorderFactory.createEmptyBorder(5, 5, 5, 5)));
      GridBagConstraints gbc;
      for (int i = 0; i < FieldTitle.values().length; i++) {
         FieldTitle fieldTitle = FieldTitle.values()[i];
         gbc = createGbc(0, i);
         JLabel fieldLabel = new JLabel(fieldTitle.getTitle() + ":",
               JLabel.LEFT);
         fieldLabel.setForeground(new Color(200, 10, 10));
         fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD, 24f));
         add(fieldLabel, gbc);
         gbc = createGbc(1, i);
         JTextField textField = new JTextField(10);
         add(textField, gbc);

         fieldMap.put(fieldTitle, textField);
      }
   }

   @Override
   @Transient
   public Dimension getPreferredSize() {
      if (backgroundImg != null) {
         return new Dimension(imgWidth, imgHeight);
      }

      return super.getPreferredSize();
   }

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

   private GridBagConstraints createGbc(int x, int y) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = 1;
      gbc.gridheight = 1;

      gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
      gbc.fill = (x == 0) ? GridBagConstraints.BOTH
            : GridBagConstraints.HORIZONTAL;

      gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
      gbc.weightx = (x == 0) ? 0.1 : 1.0;
      gbc.weighty = 1.0;
      return gbc;
   }

   public String getFieldText(FieldTitle fieldTitle) {
      return fieldMap.get(fieldTitle).getText();
   }

}

Which displays a JOptionPane like so:



来源:https://stackoverflow.com/questions/17872099/how-to-align-multiple-textfields-on-a-background-image-within-a-joptionpane

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!