0

I've created a Login form for a program using a JFrame. It will display all the text labels, input fields, buttons and other GUI elements but for some reason it will not display my image file (the image "mm.png" is stored in the project's parent directory).

I must be doing something wrong. Perhaps someone could help me.

My code is below.

Many thanks.

import java.io.*;
import java.net.*;
import java.awt.*;//contains layouts, buttons etc.
import java.awt.event.*; //contains actionListener, mouseListener etc.

import javax.swing.*; //allows GUI elements

public class Login extends JFrame implements ActionListener, KeyListener {

    private JLabel usernameLabel = new JLabel("Username/Email:");
    private JLabel userPasswordLabel = new JLabel("Password:");
    public JTextField usernameField = new JTextField();
    private JPasswordField userPasswordField = new JPasswordField();
    private JLabel status = new JLabel("Status: Not yet logged in.");

    private JButton loginButton = new JButton("Login");
    private JButton registerButton = new JButton("New User");

    public Login() {
        super("Please Enter Your Login Details...");// titlebar
        setVisible(true);
        setSize(400, 260);
        this.setLocationRelativeTo(null); // places frame in center of screen
        this.setResizable(false); // disables resizing of frame
        this.setLayout(null); // allows me to manually define layout of text
                                // fields etc.

        ImageIcon icon = new ImageIcon("mm.png");
        JLabel label = new JLabel(icon);

        this.add(usernameLabel);
        this.add(userPasswordLabel);
        this.add(usernameField);
        this.add(userPasswordField);
        this.add(loginButton);
        this.add(registerButton);
        this.add(status);

        usernameLabel.setBounds(30, 100, 120, 30); // (10, 60, 120, 20);
        userPasswordLabel.setBounds(30, 125, 80, 30);// (10, 85, 80, 20);
        usernameField.setBounds(150, 100, 220, 30);
        userPasswordField.setBounds(150, 125, 220, 30);
        loginButton.setBounds(150, 180, 110, 25);
        registerButton.setBounds(260, 180, 110, 25);
        status.setBounds(30, 210, 280, 30);
        status.setForeground(new Color(50, 0, 255)); // sets text colour to blue

        loginButton.addActionListener(this);
        registerButton.addActionListener(this);
        registerButton.setEnabled(false);
        userPasswordField.addKeyListener(this);

    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == loginButton) {
            String userName = usernameField.getText();
            String password = userPasswordField.getText();
            if (userName.equals("mick") && password.equals("mick")) {
                status.setText("Status: Logged in.");
                this.setVisible(false);
                new Client("127.0.0.1").startRunning();
            } else {
                status.setText("Status: Password or username is incorrect.");
                status.setForeground(new Color(255, 0, 0)); // changes text
                                                            // colour to red
            }
        }

    }

}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
mickm
  • 281
  • 2
  • 6
  • 20

4 Answers4

3
  1. Don't use null layouts. Swing has been designed to work with layout managers. Pixel perfect layouts are an illusion in modern GUI design. You do not control the availability of fonts or how they are rendered on individual systems. Layout out managers take the guess work out of determining the relationship between how components work together
  2. Call setVisible only after you have completed building the contents of the frame. If you need to add/remove components after the frame has been made visible, you will need to call revalidate

Take a look at Laying Out Components Within a Container for more details

MirroredFate
  • 12,396
  • 14
  • 68
  • 100
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1
    ImageIcon icon = new ImageIcon("mm.png");
    JLabel label = new JLabel(icon);

but for some reason it will not display my image file

You create the Icon and the JLabel, but I don't see where you add the label to the GUI.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Thank you for your suggestion. I added `this.add(label);` `label.setBounds(130, 10, 140, 80)` prior to this and it still does not display the image. – mickm Apr 07 '14 at 21:48
0

Given what you already have, the issues are that you haven't added the label, and you haven't set its bounds. For instance:

this.add(label);
label.setBounds(130, 10, 140, 80);

I will second MadProgrammer's recommendations though -- use nested layout managers to achieve what you want, instead of precomputing the pixel values.

johncip
  • 2,087
  • 18
  • 24
  • Thanks for your recommendation John. I tried this earlier, but it didn't work. `this.add(label);` `label.setBounds(130, 10, 140, 80);` Label seems to behave in a different manner to the other this.add statements, i.e. the variable name 'label' does not turn blue, as with the other `this.add(x)` and `.setBound`statements. – mickm Apr 07 '14 at 21:39
  • I added those two lines to your code (after `this.add(status);`) and it worked for me using a PNG file I downloaded. Also in order to get it to compile and run I commented out `new Client("127.0.0.1").startRunning();` and added a main method which creates a new instance of `Login`. How are you running the code? Loading images from a local path can be tricky in Eclipse since by default the class files go in a separate `bin` folder. – johncip Apr 07 '14 at 21:41
  • I tried doing what you have just suggested, but it still doesn't work (including commenting out `new Client("127.0.0.1).startRunning();`). I require `new Client("127.0.0.1).startRunning();` for the login to proceed to a client window. Sorry if this is a stupid question, but can you show me where you added the main method? Thanks. – mickm Apr 07 '14 at 21:46
  • The label variable looks different in your IDE because it's not a member (it gets declared in the constructor rather than "above" it). Also I commented out the Client line so that I wouldn't have to implement Client, and added a main method so I could run the example. You don't have to do either of those things. – johncip Apr 07 '14 at 21:47
  • I sincerely appreciate your efforts John and your thoroughness. Yes, I'm using a separate main method to launch the login form. I tried two different .png files and have no idea why the image will not load in my own IDE. – mickm Apr 07 '14 at 21:59
  • Thanks John. It now works!!! I re-read one of your posts and you were absolutely spot on. My image had been moved to the 'bin' folder. I changed the line filepath to 'bin/mm.png' and it now works perfectly. Thanks again for all your help. – mickm Apr 07 '14 at 22:04
0

I just figured out that, actually I had the same problem, my Image won't display on the Label, so what I found out is that, when you are using (null) layout make sure that when you use setBounds() function, make sure that the width and height must be same as the picture or icon you are using.

Example

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MyFrame extends JFrame{
    JLabel label;
    ImageIcon icon;

    MyFrame(){
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(500, 500);
        this.setLayout(null);
        getContentPane().setBackground(Color.BLACK);
    
        icon = new ImageIcon("icon.png"); // this icon's width and height is 126
    
        label = new JLabel();
        label.setIcon(icon);
        label.setBounds(0,0,216,216); // 216 is width and height of my image 
    
        this.add(label);
        this.setVisible(true);
    }
}

I hope this makes sense for you, and you got the idea that the while using setBounds you must pass width and height of your icon/image