JTextField光标显示不正确

3

我在JFrame中使用了JTextField。光标在正常的光标和半个绘制的光标之间闪烁。

截屏

光标只显示在顶部和底部。我尝试使用自定义光标,但它们只显示图形的一部分。密码字段也有相同的错误。我不知道这是否相关,但我在Mac上运行,没有Windows机器来测试该错误是否也会在Windows上发生。 以下是我的窗口的MCVE(尽可能简短):

public class Login1 extends JFrame implements Serializable {
private static final long serialVersionUID = 1L;

private JPanel pnl_mainPanel;
private JButton btn_login_main, btn_newAccount, btn_seeAccounts, btn_login_login, btn_cancel_login, btn_next, btn_cancel_new;
private JTextField tf_username_login, tf_username_new;
private JPasswordField pf_password, pf_password_new, pf_password_confirm;
private JLabel lbl_username_login, lbl_password_login, lbl_username_new, lbl_password_new, lbl_password_confirm;

private static final String TITLE = "Login";
private final int WINDOW_WIDTH = 400;
private final int WINDOW_HEIGHT = 300;
private final Dimension WINDOW_DIM = new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT);

public Login1() {
    super(TITLE);
    setSize(WINDOW_DIM);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(new BorderLayout());
    buildPanel();
    add(pnl_mainPanel);
    setVisible(true);
    setResizable(false);
}

private void buildPanel() {
    pnl_mainPanel = new JPanel();
    btn_login_main = new JButton("Login");
    btn_newAccount = new JButton("New Account");
    btn_seeAccounts = new JButton("ℹ");

    // login page
    btn_login_login = new JButton("Login");
    btn_cancel_login = new JButton("Cancel");
    tf_username_login = new JTextField();
    pf_password = new JPasswordField();
    lbl_username_login = new JLabel("Username:");
    lbl_password_login = new JLabel("Password:");

    // new account page
    btn_next = new JButton("Next");
    btn_cancel_new = new JButton("Cancel");
    tf_username_new = new JTextField();
    pf_password_new = new JPasswordField();
    pf_password_confirm = new JPasswordField();
    lbl_username_new = new JLabel("Username:");
    lbl_password_new = new JLabel("Password:");
    lbl_password_confirm = new JLabel("<html>Confirm<br>Password:</html>");

    pnl_mainPanel.setLayout(null);
    pnl_mainPanel.add(btn_login_main);
    pnl_mainPanel.add(btn_newAccount);
    pnl_mainPanel.add(btn_seeAccounts);

    btn_login_login.setSize(75, 30);
    btn_login_login.setLocation(new Point(310, 175));
    btn_cancel_login.setSize(75, 30);
    btn_cancel_login.setLocation(new Point(310, 215));
    tf_username_login.setSize(200, 25);
    tf_username_login.setLocation(new Point(100, 178));
    pf_password.setSize(200, 25);
    pf_password.setLocation(new Point(100, 218));
    lbl_username_login.setSize(100, 25);
    lbl_username_login.setLocation(new Point(15, 178));
    lbl_password_login.setSize(100, 25);
    lbl_password_login.setLocation(new Point(15, 218));

    btn_next.setSize(75, 30);
    btn_next.setLocation(new Point(310, 160));
    btn_cancel_new.setSize(75, 30);
    btn_cancel_new.setLocation(new Point(310, 200));
    tf_username_new.setSize(200, 25);
    tf_username_new.setLocation(new Point(100, 163));
    pf_password_new.setSize(200, 25);
    pf_password_new.setLocation(new Point(100, 203));
    pf_password_confirm.setSize(200, 25);
    pf_password_confirm.setLocation(new Point(100, 243));
    lbl_username_new.setSize(100, 25);
    lbl_username_new.setLocation(new Point(15, 163));
    lbl_password_new.setSize(100, 25);
    lbl_password_new.setLocation(new Point(15, 203));
    lbl_password_confirm.setSize(100, 30);
    lbl_password_confirm.setLocation(new Point(15, 238));

    btn_login_main.setSize(163, 100);
    btn_login_main.setLocation(new Point(25, 150));
    btn_newAccount.setSize(162, 100);
    btn_newAccount.setLocation(new Point(213, 150));
    btn_seeAccounts.setSize(20, 20);
    btn_seeAccounts.setLocation(new Point(375, 255));

    btn_login_main.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            pnl_mainPanel.remove(btn_login_main);
            pnl_mainPanel.remove(btn_newAccount);

            pnl_mainPanel.remove(btn_next);
            pnl_mainPanel.remove(btn_cancel_new);
            pnl_mainPanel.remove(tf_username_new);
            pnl_mainPanel.remove(pf_password_new);
            pnl_mainPanel.remove(pf_password_confirm);
            pnl_mainPanel.remove(lbl_username_new);
            pnl_mainPanel.remove(lbl_password_new);
            pnl_mainPanel.remove(lbl_password_confirm);

            pnl_mainPanel.add(btn_login_login);
            pnl_mainPanel.add(btn_cancel_login);
            pnl_mainPanel.add(tf_username_login);
            pnl_mainPanel.add(pf_password);
            pnl_mainPanel.add(lbl_username_login);
            pnl_mainPanel.add(lbl_password_login);
            repaint();
            tf_username_login.requestFocus();
        }
    });
    btn_cancel_login.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            pnl_mainPanel.remove(btn_login_login);
            pnl_mainPanel.remove(tf_username_login);
            pnl_mainPanel.remove(pf_password);
            pnl_mainPanel.remove(btn_cancel_login);
            pnl_mainPanel.remove(lbl_username_login);
            pnl_mainPanel.remove(lbl_password_login);
            pnl_mainPanel.add(btn_login_main);
            pnl_mainPanel.add(btn_newAccount);
            repaint();
        }
    });
    btn_newAccount.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            pnl_mainPanel.remove(btn_login_main);
            pnl_mainPanel.remove(btn_newAccount);
            pnl_mainPanel.add(btn_next);
            pnl_mainPanel.add(btn_cancel_new);
            pnl_mainPanel.add(tf_username_new);
            pnl_mainPanel.add(pf_password_new);
            pnl_mainPanel.add(pf_password_confirm);
            pnl_mainPanel.add(lbl_username_new);
            pnl_mainPanel.add(lbl_password_new);
            pnl_mainPanel.add(lbl_password_confirm);
            repaint();
            tf_username_new.requestFocus();
        }
    });
    btn_cancel_new.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            pnl_mainPanel.remove(btn_next);
            pnl_mainPanel.remove(btn_cancel_new);
            pnl_mainPanel.remove(tf_username_new);
            pnl_mainPanel.remove(pf_password_new);
            pnl_mainPanel.remove(pf_password_confirm);
            pnl_mainPanel.remove(lbl_username_new);
            pnl_mainPanel.remove(lbl_password_new);
            pnl_mainPanel.remove(lbl_password_confirm);
            pnl_mainPanel.add(btn_login_main);
            pnl_mainPanel.add(btn_newAccount);
            repaint();
        }
    });

}

public static void main(String[] args){
    Login1 l = new Login1();
}
}

感谢您的提前帮助!

信息不足。您可以做的最好的事情是创建一个 MCVE - 一个简化版本的程序,展示问题(在链接中阅读详细信息)。将简化的代码作为问题的编辑,这样我们就可以复制和运行它,并查看问题。 - RealSkeptic
@RealSkeptic 这来自于一个用于登录窗口的大型类。这是一个常见的错误吗?我为显示文本框的按钮添加了actionlistener。 - Dando18
1
这不是一个 MCVE。想法是编写一个新程序,它很,但我们可以自己编译和运行以查看您的问题。这需要时间,但由于问题的源头不明显,所以需要一个完整的程序,因此您必须制作一个新的、小的程序。 - RealSkeptic
@RealSkeptic 我添加了一个 MCVE。 - Dando18
@gknicker 感谢您的回复。MacBook Pro 上没有插入键,也没有适用的按键组合。 - Dando18
显示剩余2条评论
1个回答

2

我可以确认这种情况发生在我的 Mac 上,而在我的 Linux 上没有发生。

通过将该字段的高度至少改为 28,可以轻松解决此问题。

tf_username_login.setSize(200, 28);

我猜测Mac OS X无法创建高度小于28像素的字段(尽管这可能涉及字体选择等问题,我还没有测试到那么远)。由于某种原因,它会以完整高度(28像素)绘制完整插入符号,但在用户指定的大小(25)处擦除它,这导致了您注意到的现象。


我以为Swing是平台无关的。 - Dioxin
1
在GUI方面,不存在所谓的平台无关性。最终,代码会被转换为系统相关的调用。 - RealSkeptic
2
最好避免使用setSize(),而是使用布局并将封装的Window打包(pack())。 - trashgod
@trashgod 这只是我个人的一个小项目,我没有计划发布它。我知道布局是如何工作的,但这次我选择了绝对布局,并将可调整大小设置为false。 - Dando18

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接