@[TOC]GUI编程2
①.Swing
- 窗口、面板
与AWT不同的是,Swing得到的JFrame窗口在这是背景颜色等属性是需要获取一个Container对象,进而通过它来对JFrame 的各项属性进行设置。其余属性与Frame设置基本相同。
import javax.swing.*;
import java.awt.*;
public class JFrameTest {
//init();初始化
public void init(){
//顶级窗口
JFrame frame = new JFrame("First JFrame");
frame.setVisible(true);
frame.setBounds(200,200,300,300);
frame.setBackground(Color.CYAN); //直接进行设置是无效的
Container container = frame.getContentPane(); //获得容器的实例对象
container.setBackground(Color.cyan);
//设置文字 JLabel
JLabel jLabel = new JLabel("This is a JLabel");
jLabel.setHorizontalAlignment(SwingConstants.CENTER); //将标签文字设置为居中
frame.add(jLabel);
//关闭事件
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
//建立窗口
new JFrameTest().init();
}
}
- 弹窗
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//主窗口
public class DialogTest extends JFrame {
public DialogTest(){
this.setVisible(true);
this.setBounds(200,200,400,400);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//JFrame放东西需要获得一个容器
Container container = this.getContentPane();
//绝对布局,直接根据内容的大小定位摆放
container.setLayout(null);
//按钮
JButton jBtn = new JButton("Click for a Dialog !");
jBtn.setBounds(30,30,200,50);
this.add(jBtn);
//点击按钮的时候,弹出弹窗
jBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//弹窗
new MyDialog01();
}
});
}
public static void main(String[] args) {
new DialogTest();
}
}
//弹窗的窗口
class MyDialog01 extends JDialog{
public MyDialog01(){
this.setVisible(true);
this.setBounds(100,100,300,300);
Container container = this.getContentPane();
container.setLayout(null);
container.add(new JLabel("Please Study Harder !"));
}
}
- 标签
- JLabel: new JLabel(“Text”);
- 图标Icon
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class ImgIconTest extends JFrame {
public void init(){
//获取图片的地址,获取当前路径下的同级资源
URL url = this.getClass().getResource("tx.jpg");
JLabel jLabel = new JLabel("ImageIcon");
ImageIcon icon = new ImageIcon(url);
jLabel.setIcon(icon);
//居中显示
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
Container container = this.getContentPane();
container.add(jLabel);
this.setVisible(true);
this.setBounds(200,200,500,500);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ImgIconTest().init();
}
}
- 面板
JPanel
import javax.swing.*;
import java.awt.*;
public class JPanelTest extends JFrame {
public void init(){
this.setVisible(true);
this.setBounds(200,200,500,500);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container container = this.getContentPane();
container.setLayout(new GridLayout(2,2,10,10)); //两行一列,上下间距为10
JPanel jPanel1 = new JPanel(new GridLayout(1,3));
JPanel jPanel2 = new JPanel(new GridLayout(1,2));
JPanel jPanel3 = new JPanel(new GridLayout(2,1));
JPanel jPanel4 = new JPanel(new GridLayout(3,2));
jPanel1.add(new JButton("P1-1"));
jPanel1.add(new JButton("P1-2"));
jPanel1.add(new JButton("P1-3"));
jPanel2.add(new JButton("P2-1"));
jPanel2.add(new JButton("P2-2"));
jPanel3.add(new JButton("P3-1"));
jPanel3.add(new JButton("P3-2"));
jPanel4.add(new JButton("P4-1"));
jPanel4.add(new JButton("P4-2"));
jPanel4.add(new JButton("P4-3"));
jPanel4.add(new JButton("P4-4"));
jPanel4.add(new JButton("P4-5"));
jPanel4.add(new JButton("P4-6"));
container.add(jPanel1);
container.add(jPanel2);
container.add(jPanel3);
container.add(jPanel4);
}
public static void main(String[] args) {
new JPanelTest().init();
}
}
JScroll
import javax.swing.*;
import java.awt.*;
public class JScrollTest extends JFrame {
public void init(){
Container container = this.getContentPane();
//文本域JTextArea
JTextArea textArea = new JTextArea(20,50); //一行20个字
textArea.setText("Welcome!");
JScrollPane jScrollPane = new JScrollPane(textArea); //滚动面板,当内容超出显示范围显示滚动条
container.add(jScrollPane);
this.setBounds(200,200,500,200);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollTest().init();
}
}
- 按钮
- 图片按钮
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonTest extends JFrame {
public void init(){
Container container = this.getContentPane();
//将图片装载为图标
URL url = this.getClass().getResource("tx.jpg");
ImageIcon icon = new ImageIcon(url);
//把图标放在按钮上
JButton jButton = new JButton();
jButton.setIcon(icon);
jButton.setToolTipText("This is a Icon Btn"); //悬浮的提示框
container.add(jButton);
this.setVisible(true);
this.setBounds(200,200,300,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonTest().init();
}
}
- 单选按钮 RadioButton
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class SingleButton extends JFrame {
public void init(){
Container container = this.getContentPane();
URL url = this.getClass().getResource("tx.jpg");
Icon icon = new ImageIcon(url);
//单选框
JRadioButton jRadioButton01 = new JRadioButton("JRadioButton01");
JRadioButton jRadioButton02 = new JRadioButton("JRadioButton02");
JRadioButton jRadioButton03 = new JRadioButton("JRadioButton03");
jRadioButton02.setBackground(new Color(134, 133, 133));
//由于单选框只能选择一个,所以一般会添加到Group中,一个组中只能选择一个
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(jRadioButton01);
buttonGroup.add(jRadioButton02);
buttonGroup.add(jRadioButton03);
container.add(jRadioButton01);
container.add(jRadioButton02);
container.add(jRadioButton03);
this.setVisible(true);
this.setLayout(new GridLayout(3,1));
this.setBounds(200,200,400,400);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new SingleButton().init();
}
}
- 复选按钮 CheckBox
import javax.swing.*;
import java.awt.*;
public class CheckBoxTest extends JFrame {
public void init(){
Container container = this.getContentPane();
//多选框CheckBox
JCheckBox jCheckBox01 = new JCheckBox("CheckBox01");
JCheckBox jCheckBox02 = new JCheckBox("CheckBox02");
JCheckBox jCheckBox03 = new JCheckBox("CheckBox03");
JCheckBox jCheckBox04 = new JCheckBox("CheckBox04");
container.add(jCheckBox01);
container.add(jCheckBox02);
container.add(jCheckBox03);
container.add(jCheckBox04);
this.setVisible(true);
this.setLayout(new GridLayout(4,1));
this.setBounds(200,200,400,400);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new CheckBoxTest().init();
}
}
- 列表
- 下拉框
选择一些地区或众多选择中的单个的选项
import javax.swing.*;
import java.awt.*;
public class ComBoxTest extends JFrame {
public void init(){
Container container = this.getContentPane();
JComboBox comboBox = new JComboBox();
comboBox.addItem("The First Select");
comboBox.addItem("The Second Select");
comboBox.addItem("The Third Select");
comboBox.addItem("The Forth Select");
container.add(comboBox);
this.setVisible(true);
this.setBounds(200,200,500,350);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ComBoxTest().init();
}
}
- 列表框
展示一些信息,一般是动态扩容的
import javax.swing.*;
import java.awt.*;
import java.util.Vector;
public class ComBoxTest02 extends JFrame {
public void init(){
Container container = this.getContentPane();
//生成列表的内容
//String[] contents = {"1","2","3"};
Vector<String> contents = new Vector<>();
//列表中需要放内容
JList<String> jList = new JList<>(contents);
JScrollPane jScrollPane = new JScrollPane(jList);
for (int i = 0; i < 100; i++) {
contents.add("User:" + i);
}
container.add(jScrollPane);
this.setVisible(true);
this.setBounds(200,200,400,350);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ComBoxTest02().init();
}
}
- 文本框
正常文本框,密码框,文本域
import javax.swing.*;
import java.awt.*;
public class TextTest01 extends JFrame {
public void init(){
Container container = this.getContentPane();
JPanel textField = new JPanel();
JPanel passWord = new JPanel();
//在使用JScrollPanel的时候需要用一个JPanel装载内容,再将Jpanel放到JScrollPanel中
JPanel textAreaPanel = new JPanel();
JScrollPane textArea = new JScrollPane(textAreaPanel);
//文本框
JTextField jTextField1 = new JTextField("TextField01",20);
JTextField jTextField2 = new JTextField("TextField02",20);
textField.setLayout(new GridLayout(2,1));
textField.add(jTextField1);
textField.add(jTextField2);
//密码框
JPasswordField jPasswordField = new JPasswordField();
jPasswordField.setEchoChar('*');
passWord.setLayout(new GridLayout(1,1));
passWord.add(jPasswordField);
//文本域
JTextArea jTextArea = new JTextArea("TextArea",20,40);
textArea.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
textAreaPanel.setLayout(new GridLayout(1,1));
textAreaPanel.add(jTextArea);
container.add(textField);
container.add(passWord);
container.add(textArea);
this.setVisible(true);
this.setLayout(new GridLayout(3,1));
this.setBounds(200,200,500,300);
this.setResizable(false);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TextTest01().init();
}
}
②.游戏Demo
import javax.swing.*;
import java.net.URL;
//数据中心,资源加载器,将外部资源直接拿到,方便后期调用
public class Data {
//相对路径
public static URL headerURL = Data.class.getResource("img/Head.png");
public static URL upURL = Data.class.getResource("img/Up.png");
public static URL downURL = Data.class.getResource("img/Down.png");
public static URL leftURL = Data.class.getResource("img/Left.png");
public static URL rightURL = Data.class.getResource("img/Right.png");
public static URL bodyUpURL = Data.class.getResource("img/BodyUp.png");
public static URL bodyDownURL = Data.class.getResource("img/BodyDown.png");
public static URL foodURL = Data.class.getResource("img/Food.png");
public static ImageIcon header = new ImageIcon(headerURL);
public static ImageIcon up = new ImageIcon(upURL);
public static ImageIcon down = new ImageIcon(downURL);
public static ImageIcon left = new ImageIcon(leftURL);
public static ImageIcon right = new ImageIcon(rightURL);
public static ImageIcon bodyUp = new ImageIcon(bodyUpURL);
public static ImageIcon bodyDown = new ImageIcon(bodyDownURL);
public static ImageIcon food = new ImageIcon(foodURL);
}
import javax.swing.*;
//游戏的主启动类,设置窗口的大小位置等等参数
public class StartGame {
public static void main(String[] args) {
JFrame frame = new JFrame("贪吃蛇");
frame.setBounds(200,200,900,720);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//一般的游戏的界面都在面板上
frame.add(new GamePanel());
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
//游戏的主面板,借助定时器实现游戏的帧显示效果
public class GamePanel extends JPanel implements KeyListener, ActionListener {
//定义蛇的数据结构
int length; //蛇的长度
int[] snakeX = new int[600]; //蛇的坐标
int[] snakeY = new int[500]; //蛇的坐标 25*25 为一格
String fx; //初始方向
boolean isStart = false; //游戏当前的状态
int speed = 101; //速度数值
//食物的坐标
int foodX;
int foodY;
Random random = new Random();
//失败标志位
boolean isFail = false;
//积分统计器
int score;
//定时器 以毫秒为单位
Timer timer = new Timer(speed,this); //100毫秒执行一次
//构造器
public GamePanel() {
init();
//获得焦点和键盘事件
this.setFocusable(true); //获得焦点事件
this.addKeyListener(this); //已经实现了接口,所以传这个对象本身就可以了
timer.start(); //游戏一开始,定时器就启动
}
//初始化方法
public void init(){
length = 3;
snakeX[0] = 100;snakeY[0] = 100; //脑袋的坐标
snakeX[1] = 75;snakeY[1] = 100; //第一节身体的做i奥
snakeX[2] = 50;snakeY[2] = 100;
fx = "R"; //初识方向向右
//把食物随机分布在界面上
foodX = 25 + 25*random.nextInt(34);
foodY = 75 + 25*random.nextInt(24);
score = 0;
}
//绘制面板,游戏中的所有东西都用这一支画笔来画
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //每次调用有清屏的作用
//绘制静态的面板
this.setBackground(Color.WHITE);
Data.header.paintIcon(this,g,25,11); //头部广告栏
g.fillRect(25,75,850,600); //默认的游戏界面
//把小蛇画上去
for(int i = 1;i < length;i++){
if(fx.equals("U") || fx.equals("D")){
Data.bodyUp.paintIcon(this,g,snakeX[i],snakeY[i]);
}else if (fx.equals("L") || fx.equals("R")){
Data.bodyDown.paintIcon(this,g,snakeX[i],snakeY[i]);
}
}
//画食物
Data.food.paintIcon(this,g,foodX,foodY);
if(fx.equals("R")){
Data.right.paintIcon(this,g,snakeX[0],snakeY[0]); //需要通过方向属性来判断
}else if(fx.equals("L")) {
Data.left.paintIcon(this, g, snakeX[0], snakeY[0]); //需要通过方向属性来判断
}else if(fx.equals("U")) {
Data.up.paintIcon(this, g, snakeX[0], snakeY[0]); //需要通过方向属性来判断
}else if(fx.equals("D")) {
Data.down.paintIcon(this, g, snakeX[0], snakeY[0]); //需要通过方向属性来判断
}
//游戏状态
if (isStart == false){
g.setColor(Color.WHITE);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("按下空格开始游戏",330,350);
}
//画速度
String s;
if(speed == 0) s = "∞";
else s = 251 - speed + "";
g.setColor(Color.WHITE);
g.setFont(new Font("微软雅黑",Font.BOLD,15));
g.drawString("速度:" + s,30,25);
//画失败判定
if(isFail){
g.setColor(Color.ORANGE);
g.setFont(new Font("微软雅黑",Font.BOLD,30));
g.drawString("游戏失败 按下空格重新开始",280,350);
}
//画积分
g.setColor(Color.WHITE);
g.setFont(new Font("微软雅黑",Font.BOLD,15));
g.drawString("得分:" + score,30,45);
g.drawString("长度:" + (length - 3),30,65);
}
@Override
public void keyTyped(KeyEvent e) {
}
//事件监听,需要通过固定的时间来刷新
@Override
public void actionPerformed(ActionEvent e) {
if(isStart && !isFail){ //如果游戏是开始状态,让小蛇动起来
//吃食物的判定
if(snakeX[0] == foodX && snakeY[0] == foodY){
//长度加一
length += 1;
//加积分
score += (251 - speed)/10;
//再次随机食物
foodX = 25 + 25*random.nextInt(34);
foodY = 75 + 25*random.nextInt(24);
}
//迭代式移动,后一节,移到前一节的位置
for(int i = length - 1;i > 0;i--){
snakeX[i] = snakeX[i-1]; //向前移动一节
snakeY[i] = snakeY[i-1];
}
//判断头部走向
if(fx.equals("R")){
snakeX[0] = snakeX[0] + 25; //头部移动
if(snakeX[0] > 850) snakeX[0] = 25; //边界判断
}else if(fx.equals("D")){
snakeY[0] = snakeY[0] + 25;
if(snakeY[0] > 650) snakeY[0] = 75; //边界判断
}else if(fx.equals("L")){
snakeX[0] = snakeX[0] - 25;
if(snakeX[0] < 25) snakeX[0] = 850; //边界判断
}else if(fx.equals("U")){
snakeY[0] = snakeY[0] - 25;
if(snakeY[0] < 75) snakeY[0] = 650; //边界判断
}
//失败判定,撞到自己算失败
for (int i = 1; i < length; i++) {
if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
isFail = true;
}
}
repaint(); //重画页面
}
}
//键盘监听事件
@Override
public void keyPressed(KeyEvent e) {
boolean isChange = true;
int keyCode = e.getKeyCode(); //获得键盘按键是哪一个
if(keyCode == KeyEvent.VK_SPACE){ //如果按下则调整状态
if(isFail){
//重新开始
isFail = false;
timer.restart();
score = 0;
init(); //重新初始化
}else {
isStart = !isStart;
repaint();
}
}
//反向移动监听
if(fx.equals("U") && (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN)){
isChange = false;
}else if(fx.equals("D") && (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP)){
isChange = false;
}else if (fx.equals("R") && (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT)){
isChange = false;
}else if (fx.equals("L") && (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT)){
isChange = false;
}
if(isChange){
//小蛇移动
if (keyCode == KeyEvent.VK_W || keyCode == KeyEvent.VK_UP){ //Up
fx = "U";
}else if(keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_DOWN){ //Down
fx = "D";
}else if (keyCode == KeyEvent.VK_A || keyCode == KeyEvent.VK_LEFT){ //Left
fx = "L";
}else if(keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_RIGHT){ //Right
fx = "R";
}
}
if(keyCode == KeyEvent.VK_ESCAPE){
System.exit(0);
}
if (keyCode == KeyEvent.VK_R){
init();
}
try{
if (keyCode == KeyEvent.VK_EQUALS || keyCode == KeyEvent.VK_ADD){
speed -= 1;
timer.setDelay(speed);
System.out.println(speed);
}else if (keyCode == KeyEvent.VK_MINUS){
speed += 1;
timer.setDelay(speed);
if(speed >= 250) speed = 250;
System.out.println(speed);
}
}catch (Exception ex){
speed = 0;
timer.setDelay(speed);
}
isChange = true;
}
@Override
public void keyReleased(KeyEvent e) {
}
}
最终的实现效果: