使用Java中的keylistener在GUI中使用箭头键绘制线条

时间:2014-02-06 01:30:18

标签: java keylistener

我正在为我的java课程进行keylistener练习,但过去一周一直困扰着。我感谢任何有用的建议。练习是:

“编写一个使用箭头键绘制线段的程序 线从框架的中心开始向东,向北, 西,或右箭头键,向上箭头键,左箭头键, 单击或向下箭头键。“

通过调试我发现KeyListener可以正常工作 得到drawComponent(图形g),但它只在我按下时绘制 向下或向右,只在前几次有效。这是我的代码:

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();
            }
        }

    }

}

感谢。

1 个答案:

答案 0 :(得分:1)

有些事情在我身上跳出来......

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

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

除了你没有打电话给super.paintComponent打破油漆链的事实,你似乎认为这幅画是准确的......

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

Swing中的绘画具有破坏性。也就是说,您应该擦除Graphics上下文并从头开始重建输出。作业paintComponent用于清除准备好绘制的Graphics上下文,但是您没有调用super.paintComponent,打破了绘画链并打开了许多非常难看的绘画工件< / p>

在框架上调用setSize(SIZE_OF_FRAME, SIZE_OF_FRAME);是危险的,因为它无法保证框架边框插入,这将减少可用的可视区域。

此....

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

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

JPanel默认使用FlowLayoutFlowLayout使用组件的首选大小来确定如何最好地布局组件。组件的默认首选大小为0x0

你可以使用......

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

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

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

奇怪的是,在我的测试中,你的KeyListener工作得很好......

基本上...

  • 覆盖getPreferredSize的{​​{1}}方法,并返回您要使用的面板的大小。
  • 使用LinePanel维护需要绘制的java.util.List列表。
  • Point方法中,使用paintComponent Point实际渲染线条。这将有点棘手,因为你需要两个点而List可能包含奇数个点,但是可行。
  • 使用首选大小或其他方式计算开始List(例如使用Point并监控ComponentListener方法。这会变得棘手,因为您的组件可能会调整大小首次创建并发布到屏幕的次数,一旦有了第一个点,您将希望忽略未来的事件。)