JTextField 插入符号未正确显示
JTextField caret not showing properly
我在 JFrame 中有一个 JTextField。插入符号在看起来正常的插入符号和半画的插入符号之间闪烁。
插入符号仅显示在顶部和底部。我试过使用自定义插入符号,但它们都只显示部分图形。密码字段的错误也相同。我不知道它是否相关,但我在 mac 上并且我没有 windows machine 来测试错误是否发生在 windows 上出色地。
这是我的 window 的 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();
}
}
提前致谢!
我可以确认这发生在我的 Mac 上,而不会发生在我的 Linux 上。
将字段的高度至少改成28即可轻松解决
tf_username_login.setSize(200, 28);
我的猜测是Mac OS X无法创建高度小于28像素的字段(虽然这可能是字体选择等问题,我没有测试过那么远)。出于某种原因,它会在全高(28 像素)处绘制完整的插入符号,但会以用户指定的大小 (25) 将其擦除,这会导致您注意到的现象。
我在 JFrame 中有一个 JTextField。插入符号在看起来正常的插入符号和半画的插入符号之间闪烁。
插入符号仅显示在顶部和底部。我试过使用自定义插入符号,但它们都只显示部分图形。密码字段的错误也相同。我不知道它是否相关,但我在 mac 上并且我没有 windows machine 来测试错误是否发生在 windows 上出色地。 这是我的 window 的 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();
}
}
提前致谢!
我可以确认这发生在我的 Mac 上,而不会发生在我的 Linux 上。
将字段的高度至少改成28即可轻松解决
tf_username_login.setSize(200, 28);
我的猜测是Mac OS X无法创建高度小于28像素的字段(虽然这可能是字体选择等问题,我没有测试过那么远)。出于某种原因,它会在全高(28 像素)处绘制完整的插入符号,但会以用户指定的大小 (25) 将其擦除,这会导致您注意到的现象。