2015-01-13 2 views
2

У меня есть этот код, который создает Jframe, где я добавляю JLabel с изображением и JpasswordField. Я хочу, чтобы JpasswordField был поверх изображения, но только в зависимости от того, где я делаю f.add. Я получаю один из них или нет. Я хочу, чтобы JpasswordField находился поверх изображения, чтобы пользователь мог ввести пароль но с изображением в качестве фона.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); 
    } 
} 

ответ

4

Во-первых, ваш код должен быть ориентирован на создание JPanels, и вы должны контролировать менеджер компоновки этого JPanel непосредственно. Затем вы можете разместить и отобразить JPanel в JDialog не JFrame, так как большая часть вашего кода пытается подражать действиям диалога (например, держать его сверху и тому подобное).

Это печально, одна из ваших больших проблем заключается в том, что вы игнорируете диспетчер компоновки, который использует панель содержимого JFrame, BorderLayout. Добавляя к нему компоненты по умолчанию, вы будете закрывать все, что было добавлено ранее в ту же позицию. Вместо этого я предлагаю:

  • Создать JPanel
  • Нарисуйте изображение в качестве фонового изображения в paintComponent methd в JPanel в.
  • Добавьте JLabel в свой JPanel.
  • Показать JPanel в JDialog не JFrame.

Например:

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(); 
      } 
     } 
     }); 
    } 
} 
+0

Я собираюсь попытаться сделать это прямо сейчас. Я отправлю здесь код или дам вам знать, есть ли у меня проблемы с ним. Честно говоря, это первый раз, когда я пишу программу GUI. В любом случае важная вещь моей программы заключается в том, что она всегда должна быть сверху и без панели меню с кнопками «закрыть», «свернуть» и «максимизировать». Могу ли я сделать это, как вы сказали? спасибо –

+0

Я действительно пытаюсь это сделать, но я не знаю, с чего начать ... :(Можете ли вы написать небольшой фрагмент кода, который я могу использовать в качестве базы? Я буду принимать ответ как действительный только с этим и я буду бороться с кодом, чтобы заставить его работать. Спасибо! –

+0

Привет, у меня есть работа, но я не могу переместить JpasswordField в случайную позицию X, Y. Хоу, я могу это сделать? Спасибо –

1

Просто чтобы дать один пример (среди многих других возможностей), вот небольшой фрагмент кода, который показывает, как справиться с этим.

Btw, когда вы звоните 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(); 
       } 
      } 
     }); 
    } 

} 
+0

Мне нравится ваше решение, но оно показывает панель меню (с кнопкой закрытия, минимизации и максимизации). Даже если я попытаюсь сделать «frame.setUndecorated (true)», это не сработает. Можете ли вы просто изменить его, чтобы он не показывал ничего из этого, и он кажется максимальным для разрешения экрана? Я отвечу как правильный, потому что все остальное работает очень хорошо. Заранее спасибо! –

+0

@ RyanFold JDialog не имеет кнопок min/max. JFrame do. JDialog становится неубедимым в любом случае. Чтобы сделать весь размер экрана, просто удалите '* 2/3' из масштабирования изображения и это должно сделать это. –

+0

Если я изменю, то это не максимизирует :( –

Смежные вопросы