我想让applet在每次输入时显示一个字母,然后每次按下它时移动一个字母

时间:2016-05-03 14:56:07

标签: java applet

守则如下。它现在的作用是它不断地移动这封信,我只想让它移动一个字符,当我按下一个字母而不是更多。此外x + = 2是我使用的另一种方法,它也没有工作..这基本上应该是一个打字类...请帮助。它也把所有字母放在同一个地方..我需要它将它们分开一个空格,我不能按两次相同的字母,或只是移动字母

public class Type_Client extends Applet implements KeyListener,Runnable
{
 boolean pickA,pickB,pickC,pickD,pickE,pickF,pickG,pickH,pickI,pickJ,pickK=false;
 boolean pickL,pickM,pickN,pickO,pickP,pickQ,pickR,pickS,pickT,pickU,pickV=false;
 boolean pickW,pickX,pickY,pickZ=false;
 boolean space=false;
 boolean run=true;
 int x=10;
 Type t1;
 Thread thr;
 public void init()
 {
     t1 = new Type();
     thr=new Thread(this);
     thr.start();
     addKeyListener(this);
 }
     public void keyTyped(KeyEvent k)
 {
 }
 public void keyReleased(KeyEvent k)
 {
 }
 public void keyPressed(KeyEvent k)
 {
     if(k.getKeyCode()==KeyEvent.VK_A)
    {
        pickA=true;
        k.consume();

    }
     if(k.getKeyCode()==KeyEvent.VK_B)
    {
        pickB=true;
        k.consume();
    }
     if(k.getKeyCode()==KeyEvent.VK_C)
    {
        pickC=true;
        k.consume();
    }

     if(k.getKeyCode()==KeyEvent.VK_SPACE)
    {
        space=true;
        k.consume();
        //Spce++;
    }
 }
  public void run()
 {
    while(run==true)
    {
        try{
            Thread.sleep(20);
        }
        catch(Exception e){};
        repaint();
    }
}
public void paint(Graphics g)
{
    if(pickA)
    {
        g.drawString(" a",x,10);

    }
    if(pickB)
    {
        g.drawString(" b",x,10);
        x++;
        x++;
    }
    if(pickC)
    {
        g.drawString(" c",x,10);
        x++;
        x++;
    }

    }
}
public void stop()
 {
 }
public void start()
{
}
}

1 个答案:

答案 0 :(得分:0)

您的代码存在许多问题。

首先,无限重绘循环:

public void run() {
    while(run==true) {
        try {
            Thread.sleep(20);
        }
        catch(Exception e) { };
        repaint();
    }
}

这很糟糕。删除它和启动它的线程!

当应用程序绘制自身的方式发生变化时(或者当窗口几何体发生变化或窗口暴露时,但工具包已经处理了所有这些情况),您只需要重新绘制JFrame / JPanel / Applet。

好的,那么什么时候有变化?可能只要你按一个键就可以了。

public void keyPressed(KeyEvent k) {
    // Your existing code here

    repaint();
}

而不是每20毫秒重新绘制一次,现在只需在按下一个键后重新绘制。这可能仍然经常发生。 ShiftAltCtrlMetaCaps Lock都是关键字;如果您按下其中任何一个,即使您的应用程序未处理任何这些键,也会触发重新绘制。但至少是效率低下。

其次,x是一个字段而不是本地绘制变量。它在应用程序启动时初始化为10,并在调用paint时递增。

g.drawString(" b",x,10);

当应用程序启动并按下" b"时,将在(10,10)处绘制字符串VK_B。但是下次重新调用时(使用现有代码20ms后),它将在(12,10),然后(14,10),然后(16,10)等处绘制它,依此类推。

相反,你可能想要:

public void paint(Graphics g) {
    int x = 10;

    // Remainder of paint code ...
}

因此,每次调用paint时,它都会以相同的方式绘制(除非应用程序状态发生某些变化,导致绘图有意地以不同方式绘制)。

drawString使用像素坐标。这封信" A"任何易读字体都超过2像素宽。例如,在这种ASCII艺术中,字母" A"和" B"是5"像素"宽。为了在字母之间留一个空隙," B"需要在" A"右侧绘制至少6个像素

  *    ****
 * *   *   *
*   *  ****
*****  *   *
*   *  *   *
*   *  ****

<-7px->

您可以使用Graphics#getFontMetrics来确定使用给定字体根据前面的字符推进每个字符的位置的数量。

或者,您可以使用(例如)16像素的常数前进。

private final static int ADVANCE = 16;

public void paint(Graphics g) {
    int x = 10;
    if (pickA) {
        g.drawString("a", x, 10);
        x += ADVANCE;
    }
    if (pickB) {
        g.drawString("b", x, 10);
        x += ADVANCE;
    }
    // ...
}

或者您可以让工具包为您完成工作,并绘制String

public void paint(Graphics g) {
    StringBuilder sb = new StringBuilder(27);

    if (pickA) {
        sb.append("a ");
    }
    if (pickB) {
        sb.append("b ");
    }
    // ... remainder cases ...

    g.drawString(sb.toString(), 10, 10);
}

最后,您的26个pick(Letter)变量非常糟糕。考虑一种记录按键的不同方法。

一些选项:

boolean picked [] = new boolean[26];     // boolean array (1 per letter)
Set<Integer> picked = new HashSet<>();   // A set of VK_ codes
Set<Character> picked = new HashSet<>(); // A set of characters
BitSet picked = new BitSet(26);          // A set of bits (1 per letter)

这是我能为您制作的最小的工作示例。根据需要进行调整。

@SuppressWarnings("serial")
public class Type_Client extends Applet {

    private String typed = "";

    private KeyAdapter adapter = new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            char ch = e.getKeyChar();
            if (ch >= ' ' && ch <= '~') {
                typed += ch;
                repaint();
            }
        }
    };

    @Override
    public void start() {
        addKeyListener(adapter);
    }

    @Override
    public void stop() {
        removeKeyListener(adapter);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawString(typed, 10, 10);
    }
}