本帖最后由 clause3c7 于 2013-03-28 03:57:15 编辑

解决方案 »

  1.   

    String 雖然也可以追加,但是追加后會生成新的String對象,所以追加操作要用StringBuffer
      

  2.   

    问题出在你那句  message = "";上,而不在于你到底用 String 还是用 StringBuffer 。也许不是特别直观,不过事实是这样:message = ""; 的运行, 在重绘之前。
    换句话说,当你的控件重绘的时候, message 的值是 "" 。要想只用 String,那么试试这样:
    class StringPanel extends JPanel {
         
        private String message = "";
        //private StringBuffer buffer = new StringBuffer();
         
        public StringPanel() {
            addKeyListener(new KeyAdapter() {
                @Override
                public void keyTyped(KeyEvent e) {
                    //buffer.append(e.getKeyChar());
                    message += e.getKeyChar();
                }
                 
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        //message = buffer.toString().trim();
                        repaint();                    SwingUtilities.invokeLater(new Runnable() {                        @Override
                            public void run() {
                                
                                message = "";
                            }
                        });
                        //message = ""; // In the correct version, this line is deleted
                        //buffer.setLength(0);
                    }
                }
            });
        }
         
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
             
            FontMetrics fm = g.getFontMetrics();
            int stringAscent = fm.getAscent();
            int stringWidth = fm.stringWidth(message);
            int x = getWidth() / 2 - stringWidth / 2;
            int y = getHeight() / 2 - stringAscent / 2;
            g.drawString(message, x, y);
        }
    }另外从代码效率来考虑的话, String 也好 StringBuffer 也好都是不推荐的, —— 应该用 StringBuilder。代码简单更正如下:class StringPanel extends JPanel {
        
        private String message = "";
        private StringBuilder buffer = new StringBuilder();
         
        public StringPanel() {        addKeyListener(new KeyAdapter() {
                @Override
                public void keyTyped(KeyEvent e) {                buffer.append(e.getKeyChar());
                }
                 
                @Override
                public void keyPressed(KeyEvent e) {                if (e.getKeyCode() == KeyEvent.VK_ENTER) {                    message = buffer.toString().trim();
                        buffer.delete(0, buffer.length());
                        repaint();
                    }
                }
            });
        }
         
        @Override
        protected void paintComponent(Graphics g) {        super.paintComponent(g);
             
            FontMetrics fm = g.getFontMetrics();
            int stringAscent = fm.getAscent();
            int stringWidth = fm.stringWidth(message);
            int x = getWidth() / 2 - stringWidth / 2;
            int y = getHeight() / 2 - stringAscent / 2;
            g.drawString(message, x, y);
        }
    }(上面两个示例代码都没有测试,也许有错误)
      

  3.   

    要想知道原理,
    google搜索:   Java Swing EDT, Swing 绘制原理, Swing 线程 ……
    或者阅读: 《Filthy Rich Clients》