【Java-GUI】05 绘图 Part1
案例:
package cn.dzz; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class Main { static String shape = ""; public static void main(String[] args) { // 创建窗体 Frame frame = new Frame(); // 创建所需的组件 // 绘制矩形和椭圆的两个事件按钮 Button rectangleButton = new Button("draw-rectangle"); Button ellipsoidButton = new Button("draw-ellipsoid"); // 逻辑判断 // 判断图形的逻辑 final String RECT = "RECT"; final String OVAL = "OVAL"; // 自定义的Canvas类 class DemoCanvas extends Canvas { // paint方法在repaint()调用之后触发 @Override public void paint(Graphics g) { // super.paint(g); if (shape.equals(RECT)) { g.setColor(Color.BLACK); g.drawRect(100,100,150,100); } else if (shape.equals(OVAL)){ g.setColor(Color.RED); g.drawOval(100,100,150,100); } } } // 初始化画布容器对象 Canvas canvas = new DemoCanvas(); // 按钮的事件监听 rectangleButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { shape = RECT; canvas.repaint(); } }); ellipsoidButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { shape = OVAL; canvas.repaint(); } }); // 组件组装 Panel panel = new Panel(); panel.add(rectangleButton); panel.add(ellipsoidButton); canvas.setPreferredSize(new Dimension(300, 300)); frame.add(panel, BorderLayout.SOUTH); frame.add(canvas); // 自适应和可见 frame.pack(); frame.setVisible(true); } }
预览效果
矩形和椭圆
弹球游戏的实现:
借助repaint方法,只要方法执行的频率超过肉眼的速度,
静态的画面就可以实现动画的效果
package cn.dzz; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SamplePinball { private Frame frame = new Frame("Pinball-Game"); // 弹跳的活动空间 private final int TABLE_WIDTH = 300; private final int TABLE_HEIGHT = 400; // 球拍尺寸 private final int RACKET_WIDTH = 60; private final int RACKET_HEIGHT = 10; // 弹球大小 private final int BALL_SIZE = 15; // 弹球初始出现的坐标位置 private int ball_location_x = 150; private int ball_location_y = 200; // 弹球的移动速度 private int speedX = 5; private int speedY = 10; // 球拍的坐标 private int racket_location_x = 120; private final int RACKET_INIT_LOCATION_Y = 340; private boolean isGameOver = false; // 计时器? private Timer flasher; private Canvas table = new PinballTable(); class PinballTable extends Canvas { @Override public void paint(Graphics g) { // super.paint(g); // 游戏结束 if(isGameOver) { g.setColor(Color.BLACK); g.setFont(new Font("times", Font.BOLD, 30)); g.drawString("游戏结束", 75, 200); } else { // 游戏没有结束 // 绘制球拍 g.setColor(Color.LIGHT_GRAY); g.fillRect( racket_location_x, RACKET_INIT_LOCATION_Y, RACKET_WIDTH, RACKET_HEIGHT ); // 绘制弹球 g.setColor(Color.RED); g.fillOval( ball_location_x, ball_location_y, BALL_SIZE, BALL_SIZE ); } } } public void init() { // 视图组装与逻辑控制 // 实现球拍变化的控制 KeyListener keyListener = new KeyAdapter(){ @Override public void keyPressed(KeyEvent e) { // super.keyPressed(e); // 每一个按键都对应了一个按键代码数值 int keyCode = e.getKeyCode(); System.out.println("当前按下的按键是:" + keyCode); switch (keyCode) { case KeyEvent.VK_LEFT : if (racket_location_x > 0) { racket_location_x -= 15; } break; case KeyEvent.VK_RIGHT : if (racket_location_x < (TABLE_WIDTH - RACKET_WIDTH)) { racket_location_x += 15; } break; } } }; // 每次刷新需要干的事情: ActionListener actionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 弹球碰到墙壁的反弹逻辑 if (ball_location_x <= 0 || ball_location_x >= (TABLE_WIDTH - BALL_SIZE) ) { speedX = -speedX; } if (ball_location_y <= 0 || ( ball_location_y > RACKET_INIT_LOCATION_Y - BALL_SIZE && ball_location_x > racket_location_x && ball_location_x < racket_location_x + RACKET_WIDTH ) ) { speedY = -speedY; } // 弹球越过了球拍的高度,游戏结束了 if (ball_location_y > RACKET_INIT_LOCATION_Y - BALL_SIZE && (ball_location_x < racket_location_x || ball_location_x > racket_location_x + RACKET_WIDTH) ) { flasher.stop(); isGameOver = true; } // 如果没有碰到墙壁则继续移动 ball_location_x += speedX; ball_location_y += speedY; // 画布刷新 table.repaint(); } }; // 弹球的控制 100毫秒(0.1秒) flasher = new Timer(100, actionListener); flasher.start(); // 由顶级窗体监听这个事件 frame.addKeyListener(keyListener); table.addKeyListener(keyListener); // 设置大小和装填组件 table.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT)); frame.add(table, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } }
差点忘了启动类:
package cn.dzz; public class GUI { public static void main(String[] args) { new SamplePinball().init(); } }