Hot questions for Using JTextField in jpasswordfield

Top Java Programmings / JTextField / jpasswordfield

Question:

I'm working on a login system program on Java.

Every time I write down the user and password and press Login it always goes towards the else statement. I did turn the passwordfield into a string but it still doesn't work.

Here's the code:

public static void main(String[] args)
{
    JFrame frame = new JFrame("Login");
    frame.setLayout(new BorderLayout());
    frame.add(panelC(), BorderLayout.CENTER);
    frame.add(panelN(), BorderLayout.NORTH);
    //frame.add(panelW(), BorderLayout.WEST);
    //frame.add(panelE(), BorderLayout.EAST);
    frame.add(panelS(), BorderLayout.SOUTH);
    frame.setVisible(true);
    frame.pack();
}

public static JPanel panelC()
{
    JPanel panel = new JPanel();
    label1 = new JLabel("Username");
    label2 = new JLabel("Password");
    field1 = new JTextField(10);
    pass = new JPasswordField(10);
    panel.add(label1);
    panel.add(field1);
    panel.add(label2);
    panel.add(pass);
    return panel;
}
public static JPanel panelN()
{
    JPanel panel = new JPanel();
    panel.setPreferredSize(new Dimension(0,25));
    return panel;
}
public static JPanel panelS()
{

    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(0,5));
    button1 = new JButton("Login");
    JLabel test = new JLabel();
    JLabel test2 = new JLabel();
    JLabel test3 = new JLabel();
    JLabel test4 = new JLabel();
    panel.add(test);
    panel.add(test2);
    panel.add(test3);
    panel.add(test4);
    panel.add(button1);
    char[] p = pass.getPassword();
    button1.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent f)
        {
            try
            {
                Scanner scan = new Scanner (new File("Logins.txt"));
                String user = scan.nextLine();
                String pass = scan.nextLine();
                String inPass = new String(p);
                String inUser = field1.getText();
                while (scan.hasNextLine())
                {

                    if (inUser.equals(user) && inPass.equals(pass))
                    {
                        System.out.println("Granted");
                        break;
                    }
                    else
                    {
                        user = scan.nextLine();
                        pass = scan.nextLine();
                    }
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

    });
    return panel;
}
}

Answer:

You're calling getText() in code where you create a component, so this is being called before a user has had any chance of entering anything into the text field. Instead this method should only be called from within an appropriate listener, such as an ActionListener that is triggered by the user pressing an accept JButton or by pressing enter in a JTextField.

Solution: fill your inPass and inUser Strings within the ActionListener, not within the creational code.

Other problems:

  1. You're grossly over-using static, suggesting that your code needs to be refactored so that statics (other than the main method) aren't needed.
  2. In general it's not a good idea to create a String out of your password char[] array, but rather to compare char arrays. This makes your password more secure, although this is not such a big deal in a simple academic exercise such as this one. Still you should know this.
  3. Same for storing password text in a text file -- not very secure (as you can imagine).
  4. Most Swing login windows should be modal JDialogs and not JFrames as they present information that absolutely must be dealt with before the program progresses, and a modal dialog will halt program flow until it is no longer visible.

Question:

I wants to remove blank space or border space between JButton and JTextfield added inside raisedbevel border I tried this code but still gap between them

import java.awt.*; 
import javax.swing.*;
import javax.swing.border.Border;

public class Main {
  public static void main(String args[]) {
    JFrame f = new JFrame("JPasswordField  ");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p=new JPanel(),pp=new JPanel();
    JButton b=new JButton("o");

b.setBorder(null);
b.setBorderPainted(false);
b.setMargin(new Insets(0,0,0,0));
 Border emptyBorder = BorderFactory.createEmptyBorder();
    b.setBorder(emptyBorder);
    Border  raisedbevel=BorderFactory.createRaisedBevelBorder();


    pp.setBorder(raisedbevel);
    JTextField t=new JTextField(20);
    t .setBorder(javax.swing.BorderFactory.createEmptyBorder());
    t.setPreferredSize(new Dimension(100, 25));
    b.setPreferredSize(new Dimension(25, 25));
    pp.setBackground(Color.black);
    pp.add(t);

     pp.add(b);


     p.add(pp);
    f.add(p);
    f.setSize(400, 100);
    f.setVisible(true);


  }
}

I wants to remove that black space completely Thanks.


Answer:

JPanel use a FlowLayout by default, which uses a padding of 5, vertically and horitzontially, by default.

If you want to continue using FlowLayout, you could specify the padding you want using something like...

pp = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0);

or use another layout manager, like GridBagLayout

I'd also discourage you from using setPreferredSize generally and rely on Border's and layout's to affect how a component might be "extra" sized beyond its default preferred size

Have a look at Laying Out Components Within a Container, How to Use FlowLayout, How to Use GridBagLayout and Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

Question:

I have an empty class MyJTextField extending JTextField, and I want MyJTextField to be initialized as JPasswordField, like JTextField can do.

JTextField pass = new JPasswordField(); //no errors
but
MyJTextField pass = new JPasswordField();//"Type mismatch: cannot convert from JPasswordField to MyJTextField"

Answer:

Your MyJTextField is a child of JTextField. And JPasswordField also is a child of JTextField. But MyJTextField is not a child of JPasswordField, so MyJTextField is not a JPasswordField, they are siblings.

    //you can do
    JTextField field1 = new JPasswordField(); //child is an instance of parent
    JTextField field2 = new MyJTextField(); //child is an instance of parent

    //you can't do
    JPasswordField field3 = new JTextField(); // parent is not instance of child
    MyJTextField field4 = new JTextField(); // parent is not instance of child
    JPasswordField field5 = new MyJTextField(); // siblings are not instances of each other
    MyJTextField field6 = new JPasswordField(); // siblings are not instances of each other

Question:


Answer:

i tried this

 if(this.icon!=null){
        int iconWidth = icon.getIconWidth();
        int iconHeight = icon.getIconHeight();
        int x = (dummyInsets==null) ? 0 : dummyInsets.left - 5;
        textX = x+iconWidth+2;
        int y = (this.getHeight() - iconHeight)/2;
        icon.paintIcon(this, g, x, y);
    }

and it worked

Question:

Well, am working on a java project which requires input from the user. I realised that if the user press the backspace when there are no characters in the field, a window warning sound is heard. How can I stop this please. My system is windows 10 if at all the behavior may be different on different platforms. Thank you.


Answer:

behavior may be different on different platforms.

Yes, the behaviour can be different because it is controlled by the LAF, so you should not really be changing it.

But to understand how Swing works you need to understand that Swing uses an Action provided by the DefaultEditorKit to provide the editing functions of text components.

Following is the code for the current "delete previous character" Action (taken from the DefaultEditKit):

/*
 * Deletes the character of content that precedes the
 * current caret position.
 * @see DefaultEditorKit#deletePrevCharAction
 * @see DefaultEditorKit#getActions
 */
static class DeletePrevCharAction extends TextAction {

    /**
     * Creates this object with the appropriate identifier.
     */
    DeletePrevCharAction() {
        super(DefaultEditorKit.deletePrevCharAction);
    }

    /**
     * The operation to perform when this action is triggered.
     *
     * @param e the action event
     */
    public void actionPerformed(ActionEvent e) {
        JTextComponent target = getTextComponent(e);
        boolean beep = true;
        if ((target != null) && (target.isEditable())) {
            try {
                Document doc = target.getDocument();
                Caret caret = target.getCaret();
                int dot = caret.getDot();
                int mark = caret.getMark();
                if (dot != mark) {
                    doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
                    beep = false;
                } else if (dot > 0) {
                    int delChars = 1;

                    if (dot > 1) {
                        String dotChars = doc.getText(dot - 2, 2);
                        char c0 = dotChars.charAt(0);
                        char c1 = dotChars.charAt(1);

                        if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
                            c1 >= '\uDC00' && c1 <= '\uDFFF') {
                            delChars = 2;
                        }
                    }

                    doc.remove(dot - delChars, delChars);
                    beep = false;
                }
            } catch (BadLocationException bl) {
            }
        }
        if (beep) {
            UIManager.getLookAndFeel().provideErrorFeedback(target);
        }
    }
}

If you don't like the beep then you would need to create your own custom Action to remove the beep sound. (ie. don't provide the error feedback). Once you customize the Action you can than change a single text field using:

textField.getActionMap().put(DefaultEditorKit.deletePrevCharAction, new MyDeletePrevCharAction());

Or you can change all text fields using:

ActionMap am = (ActionMap)UIManager.get("TextField.actionMap");
am.put(DefaultEditorKit.deletePrevCharAction, new MyDeletePrevCharAction());