Java drawString无法正确写入字符串

Java drawString无法正确写入字符串,java,swing,user-interface,Java,Swing,User Interface,我试图使这个GUI有一个文本字段(下面的变量查询),如果GUI注意到按下了一个键,它将在文本字段中提取输入的字符串。但是,如果我将字符串str初始化为“它在GUI上保持为”,并且从不更改,但是当我在paintComponent方法中打印字符串时,它具有正确的字符串(出于某种原因,最后一个字符除外)。有什么建议吗?提前谢谢 private String str; private JTextField query; public void keyPressed(KeyEvent e) {

我试图使这个GUI有一个文本字段(下面的变量查询),如果GUI注意到按下了一个键,它将在文本字段中提取输入的字符串。但是,如果我将字符串str初始化为“它在GUI上保持为”,并且从不更改,但是当我在paintComponent方法中打印字符串时,它具有正确的字符串(出于某种原因,最后一个字符除外)。有什么建议吗?提前谢谢

private String str;
private JTextField query;
public void keyPressed(KeyEvent e) {
        str = query.getText();
}
...
public void paintComponent(Graphics g){
        super.paintComponent(g);
        //System.out.println(str);
        g.drawString(str,20,30);

}
  • 不要将
    KeyListener
    用于任何
    JTextComponent
    ,它不是监视这些组件更改的合适方法,而是使用
    DocumentListener
    ,当通过call
    setText
    修改字段时,或者如果将文本粘贴到字段中,以及当用户键入某些内容时,这将发出通知
  • 确保在更新字段时重新绘制组件
  • 还应避免直接绘制到具有组件的同一组件,因为布局管理器可能会将内容放置在自定义绘制的顶部

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Document;
    
    public class Test1 {
    
        public static void main(String[] args) {
            new Test1();
        }
    
        public Test1() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private String paintText;
    
            public TestPane() {
                JTextField field = new JTextField(10);
                add(field);
                field.getDocument().addDocumentListener(new DocumentListener() {
    
                    protected void update(DocumentEvent e) {
                        Document doc = e.getDocument();
                        try {
                            paintText = doc.getText(0, doc.getLength());
                            repaint();
                        } catch (BadLocationException ex) {
                            ex.printStackTrace();
                        }
                    }
    
                    @Override
                    public void insertUpdate(DocumentEvent e) {
                        update(e);
                    }
    
                    @Override
                    public void removeUpdate(DocumentEvent e) {
                        update(e);
                    }
    
                    @Override
                    public void changedUpdate(DocumentEvent e) {
                        update(e);
                    }
                });
                field.setText("This is some text");
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                FontMetrics fm = g2d.getFontMetrics();
                int x = (getWidth() - fm.stringWidth(paintText)) / 2;
                int y = ((getHeight() - fm.getHeight()) + fm.getAscent()) / 2;
                g2d.drawString(paintText, x, y);
                g2d.dispose();
            }
    
        }
    
    }
    
  • 不要将
    KeyListener
    用于任何
    JTextComponent
    ,它不是监视这些组件更改的合适方法,而是使用
    DocumentListener
    ,当通过call
    setText
    修改字段时,或者如果将文本粘贴到字段中,以及当用户键入某些内容时,这将发出通知
  • 确保在更新字段时重新绘制组件
  • 还应避免直接绘制到具有组件的同一组件,因为布局管理器可能会将内容放置在自定义绘制的顶部

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Document;
    
    public class Test1 {
    
        public static void main(String[] args) {
            new Test1();
        }
    
        public Test1() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private String paintText;
    
            public TestPane() {
                JTextField field = new JTextField(10);
                add(field);
                field.getDocument().addDocumentListener(new DocumentListener() {
    
                    protected void update(DocumentEvent e) {
                        Document doc = e.getDocument();
                        try {
                            paintText = doc.getText(0, doc.getLength());
                            repaint();
                        } catch (BadLocationException ex) {
                            ex.printStackTrace();
                        }
                    }
    
                    @Override
                    public void insertUpdate(DocumentEvent e) {
                        update(e);
                    }
    
                    @Override
                    public void removeUpdate(DocumentEvent e) {
                        update(e);
                    }
    
                    @Override
                    public void changedUpdate(DocumentEvent e) {
                        update(e);
                    }
                });
                field.setText("This is some text");
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                FontMetrics fm = g2d.getFontMetrics();
                int x = (getWidth() - fm.stringWidth(paintText)) / 2;
                int y = ((getHeight() - fm.getHeight()) + fm.getAscent()) / 2;
                g2d.drawString(paintText, x, y);
                g2d.dispose();
            }
    
        }
    
    }
    

    你能解释一下为什么会改变吗?首先,不要将KeyListener与文本组件一起使用,而是在字段中注册DocumentListener。确保在触发DocumentListener时调用repaint…
    除了最后一个字符之外,因为某些原因这是因为在字符附加到textfield之前会触发keypressed事件。您可以使用keyrealesed。如果要使用keypressed,则
    query.getText()+e.getKeyChar()
    将解决此问题,但澄清问题的其余部分。您能否澄清为什么会发生变化?首先,不要将KeyListener与文本组件一起使用,请在字段中注册DocumentListener。确保在触发DocumentListener时调用repaint…
    除了最后一个字符之外,因为某些原因这是因为在字符附加到textfield之前会触发keypressed事件。您可以使用keyrealesed。如果要使用keypressed,则
    query.getText()+e.getKeyChar()
    将解决此问题,但会澄清其余问题