今日內容:KeyListener、Inner Class、KeyBinding
在MyFrame中implements KeyListener
會有三個需要Override的method (KeyTyped, KeyPressed , KeyReleased)
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Color;
import javax.swing.ImageIcon;
public class MyFrame extends JFrame implements KeyListener {
JLabel label;
ImageIcon icon;
MyFrame(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
this.setLayout(null);
this.addKeyListener(this);
icon = new ImageIcon("rocket.png");
label = new JLabel();
label.setBounds(0, 0, 100, 100);
label.setIcon(icon);
this.getContentPane().setBackground(Color.black);
this.add(label);
this.setVisible(true);
}
@Override
public void keyTyped(KeyEvent e) {
// 當key被輸入,回傳char
// 可以用來接收wasd
switch(e.getKeyChar()){
case 'a', 'A' -> label.setLocation(label.getX()-10, label.getY());
case 'w', 'W' -> label.setLocation(label.getX(), label.getY()-10);
case 's', 'S' -> label.setLocation(label.getX(), label.getY()+10);
case 'd', 'D' -> label.setLocation(label.getX()+10, label.getY());
}
}
@Override
public void keyPressed(KeyEvent e) {
// 當鍵盤上的按鍵被按,回傳int
// 可以用來接收上下左右(arrow)
switch(e.getKeyCode()){
case 37 -> label.setLocation(label.getX()-10, label.getY());
case 38 -> label.setLocation(label.getX(), label.getY()-10);
case 40 -> label.setLocation(label.getX(), label.getY()+10);
case 39 -> label.setLocation(label.getX()+10, label.getY());
}
}
@Override
public void keyReleased(KeyEvent e) {
// 當按鍵被放開
System.out.println("You released key char: " + e.getKeyChar());
System.out.println("You released key code: " + e.getKeyCode());
System.out.println();
}
}
一個class裡面可以有另一個class,(很像nested loop)
通常被設為private,但不是必要
用來方便存取兩個class之間的內容
public class Outside {
String x = "Hello ";
public class Inside{
String y = "World!";
public void greeting(){
System.out.println(x+y);
}
}
}
public class Main {
public static void main(String[] args){
Outside out = new Outside();
Outside.Inside in = out.new Inside();
in.greeting();
// Hello World!
}
}
另一種接收使用者按鍵輸入的模式,更適合用於遊戲開發
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Game {
JFrame frame;
JLabel label;
// 這邊設Action變數,並建立Inner Class
Action upAction;
Action downAction;
Action leftAction;
Action rightAction;
Game(){
frame = new JFrame("KeyBinding Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLayout(null);
label = new JLabel();
label.setBackground(Color.red);
label.setBounds(100, 100, 100, 100);
label.setOpaque(true);
upAction = new UpAction();
downAction = new DownAction();
leftAction = new LeftAction();
rightAction = new RightAction();
label.getInputMap().put(KeyStroke.getKeyStroke("UP"), "upAction");
label.getActionMap().put("upAction", upAction);
label.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "downAction");
label.getActionMap().put("downAction", downAction);
label.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
label.getActionMap().put("leftAction", leftAction);
label.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
label.getActionMap().put("rightAction", rightAction);
frame.add(label);
frame.setVisible(true);
}
// 下面的Action都是Inner Class,都extends AbstractAction
public class UpAction extends AbstractAction{
@Override
public void actionPerformed(ActionEvent e) {
label.setLocation(label.getX(), label.getY()-10);
}
}
public class DownAction extends AbstractAction{
@Override
public void actionPerformed(ActionEvent e) {
label.setLocation(label.getX(), label.getY()+10);
}
}
public class LeftAction extends AbstractAction{
@Override
public void actionPerformed(ActionEvent e) {
label.setLocation(label.getX()-10, label.getY());
}
}
public class RightAction extends AbstractAction{
@Override
public void actionPerformed(ActionEvent e) {
label.setLocation(label.getX()+10, label.getY());
}
}
}
今天是接觸Java GUI的第五天,順著這五天以來學到的東西,似乎已經可以大概抓到整個製作遊戲的雛型了,我目前的想法是先創建frame,然後在frame中新增panel,然後調整panel的內容,用來抓使用者按鍵輸入之類的,就可以進行遊戲了。
今天也是快樂學習的一天,明天繼續!