2014-02-06 72 views
1

我正在为我的java课程进行keylistener练习,但过去一周一直在卡住。我很欣赏任何有用的建议。这次演习是:使用Java中的keylistener在GUI中使用箭头键绘制线条

“写绘制使用箭头键线段程序的 线从帧的中心开始,向华东,华北, 西,或南画时,右箭头键,上箭头键,左箭头键, 或单击向下箭头键。“

经过调试我想通了KeyListener的工作,以获得对drawComponent(图形克)点 ,但是当我按下 向下或向右只汲取,只有工作的第一对夫妇倍。这里是我的代码:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class EventProgrammingExercise8 extends JFrame { 

    JPanel contentPane; 
    LinePanel lines; 
    public static final int SIZE_OF_FRAME = 500; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        EventProgrammingExercise8 frame = new EventProgrammingExercise8(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public EventProgrammingExercise8() { 
     setTitle("EventExercise8"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(SIZE_OF_FRAME, SIZE_OF_FRAME); 
     contentPane = new JPanel(); 
     lines = new LinePanel(); 
     contentPane.add(lines); 
     setContentPane(contentPane); 
     contentPane.setOpaque(true); 
     lines.setOpaque(true); 

     lines.setFocusable(true); 
     lines.addKeyListener(new ArrowListener()); 
    } 

    private class LinePanel extends JPanel { 

     private int x; 
     private int y; 
     private int x2; 
     private int y2; 

     public LinePanel() { 
      x = getWidth()/2; 
      y = getHeight()/2; 
      x2 = x; 
      y2 = y; 
     } 

     protected void paintComponent(Graphics g) { 
      g.drawLine(x, y, x2, y2); 
      x = x2; 
      y = y2; 
     } 

     public void drawEast() { 
      x2 += 5; 
      repaint(); 
     } 

     public void drawWest() { 
      x2 -= 5; 
      repaint(); 
     } 

     public void drawNorth() { 
      y2 -= 5; 
      repaint(); 
     } 

     public void drawSouth() { 
      y2 += 5; 
      repaint(); 
     } 

    } 

    private class ArrowListener extends KeyAdapter { 

     public void keyPressed(KeyEvent e) { 
      int key = e.getKeyCode(); 
      if (key == KeyEvent.VK_RIGHT) { 
       lines.drawEast(); 
      } else if (key == KeyEvent.VK_LEFT) { 
       lines.drawWest(); 
      } else if (key == KeyEvent.VK_UP) { 
       lines.drawNorth(); 
      } else { 
       lines.drawSouth(); 
      } 
     } 

    } 

} 

谢谢。

+0

就个人而言,我会使用[键绑定API](http://docs.oracle.com/javase/tutorial/uiswing/ misc/keybinding.html),从长远来看这是一个更安全的赌注,但你可能有理由不这样做... – MadProgrammer

+0

谢谢。我听说过关键绑定,但没有看到它们被使用。通常我们只应该使用我们在课堂上看到的技巧。我会进一步看看键绑定虽然.. –

回答

1

有几件事情我跳出...

public LinePanel() { 
    x = getWidth()/2; 
    y = getHeight()/2; 

这将是一个问题,因为当时你构建类,它的大小是0x0

除了事实,你没有所谓的super.paintComponent打破了油漆链,你似乎认为这幅画是accumaltive ...

protected void paintComponent(Graphics g) { 
    g.drawLine(x, y, x2, y2); 
    x = x2; 
    y = y2; 
} 

绘画在Swing是破坏性的。也就是说,您预计将擦除Graphics上下文并从头重新生成输出。该工作paintComponent是清除Graphics方面准备好画,但你不叫super.paintComponent,打破了油漆链和打开自己注册了一些非常丑陋的油漆文物

一个框架调用setSize(SIZE_OF_FRAME, SIZE_OF_FRAME);是危险的,因为它不保证框架边框的插入,这将减少可供您查看的区域。

这....

contentPane = new JPanel(); 
lines = new LinePanel(); 
contentPane.add(lines); 
setContentPane(contentPane); 

不是必需的,它只是增加了混乱到您的代码。这也是一个很好的暗示,你的代码出了什么问题。

JPanel默认使用FlowLayout。 A FlowLayout使用该组件的首选大小来确定如何最好地布置组件。组件的默认首选大小0x0

您可以使用...

lines = new LinePanel(); 
add(lines); 

代替或设置contentPane使用BorderLayout这将有助于...

尝试增加lines.setBorder(new LineBorder(Color.RED));看到添加你得到什么...

奇怪的是,在我的测试中,你的KeyListener工作正常...

基本上...

  • 重写LinePanelgetPreferredSize方法,并返回你想用面板的大小。
  • 使用java.util.List来维护需要着色的Point的列表。
  • 在你的paintComponent方法中,使用PointList来实际呈现你的线条。这将会有点棘手,因为你需要两分和List可能包含奇点数,但是可行的。
  • 通过使用首选大小或其他方法(如使用ComponentListener和监控componentResized方法来计算开始Point这会变得棘手,因为您的组件可能会在首次创建并发布到屏幕上,你会想要忽略未来的事件,一旦你有你的第一点)
+0

非常有帮助,谢谢! –

+0

我很高兴它有帮助;) – MadProgrammer