https://www.bilibili.com/video/BV1DJ411B75F/

简介

图形用户界面 Graphical User Interface,简称 GUI,又称图形用户接口

GUI核心技术:Swing AWT

不再流行的原因

  1. 界面不美观
  2. 需要jre环境

为什么学习

  1. 可以写小工具。
  2. 有可能需要维护swing界面,概率极小。
  3. 了解MVC架构,了解监听。

AWT

AWT(Abstract Window Toolkit),抽象窗口工具包

  1. 包含了很多类和接口。
  2. 元素:窗口,按钮,文本框。
  3. java.awt

组件和容器

  1. Frame是一个顶级窗口。
  2. Panel无法单独显示,不许添加到某个容器中。
  3. 布局管理器
    1. 流式布局
    2. 东西南北中
    3. 表格布局

Frame窗口

package com.qing.demo01;

import java.awt.*;

//GUI的第一个界面
public class TestFrame {
public static void main(String[] args) { //Frame 看源码学习
Frame frame = new Frame("我的第一个Java图形界面窗口");
//设置可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(400, 400);
//设置背景颜色
frame.setBackground(new Color(144, 97, 79));
//弹出的初始位置
frame.setLocation(200,200);
//设置大小固定
frame.setResizable(false);
}
}



回顾封装,展示多窗口

package com.qing.demo01;

import java.awt.*;

public class TestFrame2 {
public static void main(String[] args) {
//展示多个窗口
MyFrame myFrame1 = new MyFrame(100, 100, 300, 200, Color.red);
MyFrame myFrame2 = new MyFrame(400, 100, 300, 200, Color.orange);
MyFrame myFrame3 = new MyFrame(100, 300, 300, 200, Color.yellow);
MyFrame myFrame4 = new MyFrame(400, 300, 300, 200, Color.green);
}
} //定义MyFrame,继承Frame
class MyFrame extends Frame {
static int id = 0;//计数器,窗口编号 public MyFrame(int x, int y, int w, int h, Color color) {
super("MyFrame" + (++id));
setBackground(color);
setBounds(x, y, w, h);
setVisible(true);
}
}

Panel面板

package com.qing.demo01;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; //Panel 可以看成是一个空间,但是不能单独存在
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel(); //设置布局
frame.setLayout(null);
//设置坐标
frame.setBounds(200, 200, 500, 500);
frame.setBackground(new Color(54, 207, 52));
//panel设置坐标,相对于frame
panel.setBounds(50, 50, 400, 400);
panel.setBackground(new Color(244, 41, 81));
//frame添加panel
frame.add(panel);
//设置可见性
frame.setVisible(true); //监听事件,监听窗口关闭事件
//适配器模式
frame.addWindowListener(new WindowAdapter() {
//使用匿名内部类
//窗口点击关闭的时候需要做的事情
@Override
public void windowClosing(WindowEvent e) {
//结束程序:0正常结束;非0异常结束,如1
System.exit(0);
}
});
}
}

布局管理器

  1. 流式布局:自左而右,自上而下。
package com.qing.demo01;

import java.awt.*;

public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame(); //组件-按钮
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3"); //设置为流式布局,默认居中,可以设置为靠左,靠右
// frame.setLayout(new FlowLayout());
frame.setLayout(new FlowLayout(FlowLayout.LEFT)); frame.setSize(400, 400);
frame.setVisible(true); //把按钮添加到Frame
frame.add(button1);
frame.add(button2);
frame.add(button3);
}
}

  1. 东西南北中
package com.qing.demo01;

import java.awt.*;

public class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame(); //组件-按钮
Button east = new Button("EAST");
Button west = new Button("WEST");
Button south = new Button("SOUTH");
Button north = new Button("NORTH");
Button center = new Button("CENTER"); frame.add(east, BorderLayout.EAST);
frame.add(west, BorderLayout.WEST);
frame.add(south, BorderLayout.SOUTH);
frame.add(north, BorderLayout.NORTH);
frame.add(center, BorderLayout.CENTER); frame.setSize(400, 400);
frame.setVisible(true);
}
}

  1. 表格布局
package com.qing.demo01;

import java.awt.*;

public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame(); //组件-按钮
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6"); //表格布局,2行3列
frame.setLayout(new GridLayout(2, 3)); frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6); // frame.setSize(400, 400);
frame.pack();//自适应
frame.setVisible(true);
}
}

  1. 组合布局
package com.qing.demo01;

import java.awt.*;

public class TestDemo {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setSize(400,300);
frame.setLocation(200,200);
frame.setBackground(new Color(134,205,90));
frame.setVisible(true);
frame.setLayout(new GridLayout(2,1)); //四个面板
Panel p1 = new Panel(new BorderLayout());
Panel p2 = new Panel(new BorderLayout());
Panel p3 = new Panel(new GridLayout(2,1));
Panel p4 = new Panel(new GridLayout(2,2)); //添加按钮到面板
p1.add(new Button("p1-east"),BorderLayout.EAST);
p1.add(new Button("p1-west"),BorderLayout.WEST);
p2.add(new Button("p2-east"),BorderLayout.EAST);
p2.add(new Button("p2-west"),BorderLayout.WEST);
p3.add(new Button("p1-center-p3-1"));
p3.add(new Button("p1-center-p3-2"));
p4.add(new Button("p2-center-p4-1"));
p4.add(new Button("p2-center-p4-2"));
p4.add(new Button("p2-center-p4-3"));
p4.add(new Button("p2-center-p4-4"));
//添加面板到面板
p1.add(p3,BorderLayout.CENTER);
p2.add(p4,BorderLayout.CENTER);
//添加面板到frame窗口
frame.add(p1);
frame.add(p2);
}
}

事件监听

package com.qing.demo02;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; public class TestActionEvent {
public static void main(String[] args) {
Frame frame = new Frame();
Button button = new Button("big");
//给按钮添加动作监听
button.addActionListener(new MyActionListener()); frame.add(button,BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
windowClose(frame);
}
//关闭窗体的事件
private static void windowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
//事件监听
class MyActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("点击事件");
}
}



多个按钮,共享一个事件监听

package com.qing.demo02;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; public class TestActionTwo {
public static void main(String[] args) {
//两个按钮,实现同一个监听
//开始-停止
Frame frame = new Frame("开始-停止");
Button button1 = new Button("start");
Button button2 = new Button("stop"); //可以显式的定义触发会返回的命令,如果不显式定义,则会返回默认的值label。
//可以多个按钮只写一个监听类,通过定义的命令判断是哪个按钮
button2.setActionCommand("button2-stop"); MyMonitor myMonitor = new MyMonitor(); button1.addActionListener(myMonitor);
button2.addActionListener(myMonitor); frame.add(button1,BorderLayout.NORTH);
frame.add(button2,BorderLayout.SOUTH); frame.pack();
frame.setVisible(true);
windowClose(frame);
}
//关闭窗体的事件
private static void windowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
} class MyMonitor implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮的信息:" + e.getActionCommand());
}
}

输入框监听

package com.qing.demo02;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; public class TestText01 {
public static void main(String[] args) {
//启动
new MyFrame();
}
} class MyFrame extends Frame {
public MyFrame() {
//文本框
TextField textField = new TextField();
add(textField); //监听文本框输入的文字
MyActionListener2 myActionListener2 = new MyActionListener2();
//回车就会触发事件
textField.addActionListener(myActionListener2);
//输入文字显示为*,输入密码时使用
// textField.setEchoChar('*'); setVisible(true);
pack();
}
} class MyActionListener2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
TextField textField = (TextField) e.getSource();//获取资源,强转为文本框对象
System.out.println(textField.getText());
textField.setText("");//清空输入
}
}

简易计算器

package com.qing.demo02;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; //简易计算器
public class TestCalc {
public static void main(String[] args) {
//启动
new Calculator();
}
} //计算器类
class Calculator extends Frame {
public Calculator() {
//3个文本框
TextField num1 = new TextField(10);//字符数
TextField num2 = new TextField(10);//字符数
TextField num3 = new TextField(10);//字符数
//1个按钮
Button button = new Button("=");
button.addActionListener(new MyActionListener3(num1,num2,num3));
//1个标签
Label label = new Label("+");
//布局
setLayout(new FlowLayout()); add(num1);
add(label);
add(num2);
add(button);
add(num3); pack();
setVisible(true);
}
} //监听器类
class MyActionListener3 implements ActionListener {
//获取3个文本框变量
private TextField num1,num2,num3; public MyActionListener3(TextField num1, TextField num2, TextField num3) {
this.num1 = num1;
this.num2 = num2;
this.num3 = num3;
} public MyActionListener3() {
} @Override
public void actionPerformed(ActionEvent e) {
//1.获得加数和被加数
int i1 = Integer.parseInt(num1.getText());
int i2 = Integer.parseInt(num2.getText());
//2.加法运算后,填入第三个文本框
num3.setText(String.valueOf(i1 + i2));
//3.清楚加数和被加数文本框
num1.setText("");
num2.setText("");
}
}

使用组合优化计算器

组合:在一个类中组合另外一个类

package com.qing.demo02;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; //简易计算器
public class TestCalc {
public static void main(String[] args) {
//启动
new Calculator().loadFrame();
}
} //计算器类
class Calculator extends Frame {
//属性
TextField num1,num2,num3; //方法
public void loadFrame() {
num1 = new TextField(10);//字符数
num2 = new TextField(10);//字符数
num3 = new TextField(10);//字符数
Button button = new Button("=");
Label label = new Label("+"); button.addActionListener(new MyActionListener3(this)); setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3); pack();
setVisible(true);
}
} //监听器类
class MyActionListener3 implements ActionListener { //组合:在一个类中组合另外一个类
Calculator calculator; public MyActionListener3(Calculator calculator) {
this.calculator = calculator;
} public MyActionListener3() {
} @Override
public void actionPerformed(ActionEvent e) {
//1.获得加数和被加数
int i1 = Integer.parseInt(calculator.num1.getText());
int i2 = Integer.parseInt(calculator.num2.getText());
//2.加法运算后,填入第三个文本框
calculator.num3.setText(String.valueOf(i1 + i2));
//3.清楚加数和被加数文本框
calculator.num1.setText("");
calculator.num2.setText("");
}
}

使用内部类优化计算器

内部类优点

  1. 更好的封装。
  2. 可以访问外部类的属性和方法。
package com.qing.demo02;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; //简易计算器
public class TestCalc {
public static void main(String[] args) {
//启动
new Calculator().loadFrame();
}
} //计算器类
class Calculator extends Frame {
//属性
TextField num1,num2,num3; //方法
public void loadFrame() {
num1 = new TextField(10);//字符数
num2 = new TextField(10);//字符数
num3 = new TextField(10);//字符数
Button button = new Button("=");
Label label = new Label("+"); button.addActionListener(new MyActionListener3()); setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3); pack();
setVisible(true);
} //监听器类
//内部类最大的好处就是可以访问外部类的属性和方法。
private class MyActionListener3 implements ActionListener { @Override
public void actionPerformed(ActionEvent e) {
//1.获得加数和被加数
int i1 = Integer.parseInt(num1.getText());
int i2 = Integer.parseInt(num2.getText());
//2.加法运算后,填入第三个文本框
num3.setText(String.valueOf(i1 + i2));
//3.清楚加数和被加数文本框
num1.setText("");
num2.setText("");
}
}
}

画笔

package com.qing.demo03;

import javafx.scene.paint.Paint;

import java.awt.*;

public class TestPaint {
public static void main(String[] args) {
new MyPaint().loadFrame();
}
} class MyPaint extends Frame {
public void loadFrame() {
setBounds(200,200,600,400);
setVisible(true);
}
//画笔
@Override
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawOval(100,100,200,200); g.setColor(Color.green);
g.fillRect(150,150,100,100);
}
}

鼠标监听

package com.qing.demo03;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator; //鼠标监听
public class TestMouseListener {
public static void main(String[] args) {
new MyFrame("画图");
}
} class MyFrame extends Frame {
//窗口,画笔,鼠标点击坐标集合,鼠标监听获取坐标
//坐标集合
ArrayList<Point> points;
public MyFrame(String title) {
super(title);
setBounds(200,200,400,300);
points = new ArrayList();
setVisible(true);
//鼠标监听,每次点击,将坐标放入集合,重画,将集合中的坐标重画一次
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
points.add(new Point(e.getX(),e.getY()));
repaint();
}
});
} @Override
public void paint(Graphics g) {
Iterator<Point> iterator = points.iterator();
while (iterator.hasNext()) {
Point point = iterator.next();
g.setColor(Color.GREEN);
g.fillOval(point.x,point.y,20,20);
}
}
}

窗口监听

package com.qing.demo03;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; public class TestWindowListener {
public static void main(String[] args) {
new WindowFrame();
}
} class WindowFrame extends Frame {
int count = 0;
public WindowFrame() {
setBackground(new Color(159, 193, 84));
setBounds(200,200,400,300);
setVisible(true);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing");
System.exit(0);
} @Override
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated");
setTitle("激活窗口" + (++count) + "次");
}
});
}
}

键盘监听

package com.qing.demo03;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; public class TestKeyListener {
public static void main(String[] args) {
new KeyFrame();
}
} class KeyFrame extends Frame {
public KeyFrame() {
setBounds(200,200,400,300);
setVisible(true); this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println(keyCode);
setTitle(String.valueOf(keyCode));
if (keyCode == KeyEvent.VK_UP) {
System.out.println("上键");
}
}
});
}
}

Swing

窗口,面板

package com.qing.demo04;

import javax.swing.*;
import java.awt.*; public class JFrameDemo01 {
public static void main(String[] args) {
new MyJframe().init();
}
} class MyJframe extends JFrame {
public void init() {
setBounds(200,200,400,300);
setVisible(true);
//关闭事件
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); JLabel label = new JLabel("欢迎来到武侠世界!");
add(label);
//标签居中
label.setHorizontalAlignment(SwingConstants.CENTER); //获得一个容器
Container container = getContentPane();
container.setBackground(Color.ORANGE); }
}

弹窗

package com.qing.demo04;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; public class JDialogDemo extends JFrame {
public JDialogDemo() {
setVisible(true);
setBounds(200,200,400,400);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); Container container = getContentPane();
//绝对布局
container.setLayout(null); JButton button = new JButton("点击送秘籍");
button.setBounds(30,30,200,50);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new MyJdialog();
}
});
container.add(button);
} public static void main(String[] args) {
new JDialogDemo();
}
} class MyJdialog extends JDialog {
public MyJdialog() {
setVisible(true);
setBounds(300,300,150,250);
setTitle("九阳真经"); Container container = getContentPane();
//绝对布局
container.setLayout(null);
}
}

标签,图标,图片图标

package com.qing.demo04;

import javax.swing.*;
import java.awt.*; public class IconDemo extends JFrame implements Icon { private int width;
private int height; public IconDemo() {
} public IconDemo(int width, int height) {
this.width = width;
this.height = height;
} public static void main(String[] args) {
new IconDemo().init();
} public void init() {
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100,100,400,300); Container container = getContentPane(); IconDemo icon = new IconDemo(15,15);
//图标放在标签,也可以放在按钮上
JLabel label = new JLabel("icon",icon,SwingConstants.CENTER);
container.add(label);
} @Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.fillOval(x,y,width,height);
} @Override
public int getIconWidth() {
return this.width;
} @Override
public int getIconHeight() {
return this.height;
}
}

package com.qing.demo04;

import javax.swing.*;
import java.awt.*;
import java.net.URL; public class ImageIconDemo extends JFrame { public ImageIconDemo(){
setVisible(true);
setBounds(200,200,400,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); Container container = getContentPane(); //获取当前类路径下的图片
URL url = ImageIconDemo.class.getResource("qing.jpg");
ImageIcon imageIcon = new ImageIcon(url);
JLabel label = new JLabel();
label.setIcon(imageIcon);
label.setHorizontalAlignment(SwingConstants.CENTER); container.add(label);
} public static void main(String[] args) {
new ImageIconDemo();
}
}

面板

package com.qing.demo05;

import javax.swing.*;
import java.awt.*; public class JPanelDemo extends JFrame {
public JPanelDemo() {
setVisible(true);
setBounds(200,200,400,300);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); Container container = getContentPane();
//后面的参数是间距
container.setLayout(new GridLayout(2,1,10,10)); JPanel panel1 = new JPanel(new GridLayout(1,3,15,15));
JPanel panel2 = new JPanel(new GridLayout(2,2,5,5)); panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2")); container.add(panel1);
container.add(panel2);
} public static void main(String[] args) {
new JPanelDemo();
}
}

按钮

  1. 普通按钮
  2. 单选按钮 new JRadioButton(); 分组 new ButtonGroup();
  3. 多选按钮 new JCheckBox();

列表

  1. 下拉框 new JCombobox();
  2. 列表 new JList();

文本框

  1. 文本框 new JTextField();
  2. 密码框 new JPasswordField();
  3. 文本域 new JTextArea();

GUI总结

070_GUI编程的更多相关文章

  1. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  2. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  3. 读书笔记:JavaScript DOM 编程艺术(第二版)

    读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...

  4. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  5. C#异步编程(一)

    异步编程简介 前言 本人学习.Net两年有余,是第一次写博客,虽然写的很认真,当毕竟是第一次,肯定会有很多不足之处, 希望大家照顾照顾新人,有错误之处可以指出来,我会虚心接受的. 何谓异步 与同步相对 ...

  6. UE4新手之编程指南

    虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...

  7. C#与C++的发展历程第三 - C#5.0异步编程巅峰

    系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 3. C#与C++的发展历程第三 - C#5.0异步编程的巅峰 C#5.0 ...

  8. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

  9. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

随机推荐

  1. 宜宾1178.9873(薇)xiaojie:宜宾哪里有xiaomei

    宜宾哪里有小姐服务大保健[微信:1178.9873倩儿小妹[宜宾叫小姐服务√o服务微信:1178.9873倩儿小妹[宜宾叫小姐服务][十微信:1178.9873倩儿小妹][宜宾叫小姐包夜服务][十微信 ...

  2. pytest文档52-命令行参数--setup-show查看fixture的执行过程

    前言 使用命令行运行 pytest 用例的时候,看不到 fixture 的执行过程. 如果我们想知道fixture的执行过程和先后顺序,可以加上 --setup-show 命令行参数,帮助查看 fix ...

  3. net core 微服务 快速开发框架 Viper 初体验2020-10-17

    1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...

  4. widows安装ffmpeg

    首先下载ffmpeg的windows版本https://ffmpeg.zeranoe.com/builds/ 解压到d盘 win+r cmd 说明成功了

  5. ImageMagick:用identify检查图片是否完整?(jpg/gif/png图片是否损坏)

    一,常用图片格式的结束标志是什么? 1,Jpg格式的文件在16进制中的表示是以 ff d9 两个字节结尾 2,  gif格式的文件,结尾是 3b 3,  png格式的文件,结尾是  00 00 00 ...

  6. 笔趣阁小说 selenium爬取

    import re from time import sleep from lxml import etree from selenium import webdriver options = web ...

  7. 第五章 Linux操作系统关机、重启、注销及其查看ip命令

    一.更新系统时间与网络时间同步 1.  安装ntpdate工具 # yum -y install ntp ntpdate 2.  设置系统时间与网络时间同步 # ntpdate cn.pool.ntp ...

  8. 如何在construct3上开发游戏&游戏展示

    前言 为了更快体验做出游戏的快乐,我们可以直接采用construct3 提供的游戏模板.这里我用的是基础模板中的塔防游戏.我们在这个的基础上加进来"植物大战僵尸"的一些元素,包括内 ...

  9. linux硬盘分区及挂载

    今天买的一台服务器发现其硬盘容量与购买界面的描述不符,于是我去问了客服才知道有一块硬盘需要自己挂载,所以记录自己硬盘分区以及挂载操作得此文. 测试环境 ​ 由于时间限制,本人仅在centos 8下测试 ...

  10. JAVA递归实现线索化二叉树

    JAVA递归实现线索化二叉树 基础理论 首先,二叉树递归遍历分为先序遍历.中序遍历和后序遍历. 先序遍历为:根节点+左子树+右子树 中序遍历为:左子树+根节点+右子树 后序遍历为:左子树+右子树+根节 ...