这次不想完全按照书上来写, 按自己学的顺序和方法来写, 记录一下自己的学习过程吧;
目录
1.初体验
2.画简单几何图形
3.涂色
4.自定义字体
5.显示图片
1.初体验
先试试看怎么写出来一个gui界面吧, 第一段代码如下:
import javax.swing.*;
import java.awt.*;
class test18 {
public static void main(String[] args) {
EventQueue.invokeLater(()->{
myFrame me = new myFrame();
me.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
me.setTitle("TestOfGUI");
me.setVisible(true);
});
}
}
class myFrame extends JFrame{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HIGHT = 200;
public myFrame(){
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
setSize(screenWidth/2, screenHeight/2);
setLocationByPlatform(true);
}
}
现在慢慢分析一下上面是怎么写的, 首先在主函数里用了一个EventQueue.invokeLater
函数, 大概是一个把传入的东西加入任务执行队列的意思;
那么传入了什么东西呢, 传入了一个lambda表达式, 先定义一个myFrame, 然后设置了一些默认的关闭操作(点红叉的时候默认退出程序), 然后设置了一下title, 设置了可见性;
myFrame me = new myFrame();
me.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
me.setTitle("TestOfGUI");
me.setVisible(true);
然后看一下myFrame是什么东西:
首先是继承自JFrame的, 首先定义了一个Toolkit工具集, 要注意定义的时候要用Tollkit.getDefaultToolkit()
不能直接new一个Toolkit, 然后获取了当前屏幕的宽和高, 然后设置了窗口的大小, 是当前屏幕宽和高的二分之一(也可以直接定义绝对数值, 单位是像素, 但是这样会导致在不同分辨率的机器上运行的界面差别很大 ), 然后设置了由平台系统自动定位初始位置;
这些图形化相关的类的继承关系如下:
2.画简单几何图形
用java的awt包来画一些简单的几何图形,测试代码如下:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
public class GuiTest {
public static void main(String[] args) {
EventQueue.invokeLater(()->{
myFrame me = new myFrame();
me.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
me.setTitle("Recluse");
me.setVisible(true);
});
}
}
class myFrame extends JFrame{
public myFrame(){
add(new DrawComponent());
pack();
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screen = kit.getScreenSize();
setSize(screen.width/2,screen.height/2);
setLocationByPlatform(true);
}
}
class DrawComponent extends JComponent{
public void paintComponent(Graphics g){
double left=100,right=400;
Graphics2D gg = (Graphics2D)g;
Rectangle2D rec = new Rectangle2D.Double(left,left,right,right);
gg.draw(rec);
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
gg.draw(new Ellipse2D.Double(left*j,left*i,left,left));
}
}
gg.draw(new Ellipse2D.Double(left,2*left,right,2*left));
gg.draw(new Line2D.Double(left,left,right+left,right+left));
gg.draw(new Line2D.Double(right+left,left,left,right+left));
}
public Dimension getPreferredSize(){
return new Dimension(0,0);
}
}
效果是这样:
这些图形的继承关系如下:
贴一下awt和swing包中的常用框架和组件类的方法:
图形的一些属性的get方法 :
3.涂色
可以用gg.setColor(Color.RED);
来设置颜色;
可以用gg.fill(rect)
来填充一个图形;
Color 类用于定义颜色, 在 java.awt.Color 类中提供了 13 个预定义的常量, 它们分別表 示 13 种标准颜色;
BLACK, BLUE, CYAN, DARK. GRAY, CRAY, GREEN, LIGHT_CRAY, MACENTA, ORANGE, PINK, RED, WHITE, YELLOW
可以通过提供红、 绿和蓝三色成分来创建一个 Color 对象, 以达到定制颜色的目的; 三种颜色都是用 0 ~ 255 ( 也就是一个字节)之间的整型数值表示, 调用 Color 的构造器格式为:
Color(int redness, int greenness, int blueness);
下面是一个定制颜色的例子:
gg.setPaint(new Color(0, 128, 128)); // a dull blue-green
gg.drawString("Welcome!",75, 125);
4.自定义字体
首先可以先查看系统中有哪些可用的字体:
import java.awt.*;
public class zxr {
public static void main(String[] args) {
String fontname[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for(String font : fontname){
System.out.println(font);
}
}
}
调用GraphicsEnvironment类中的getLocalGraphicsEnvironment方法然后获得可用字体getAvailableFontFamilyNames;
可以这样来自定义字体:
Font myfont = new Font("DialogInput",Font.BOLD,14);
gg.setFont(myfont);
gg.drawString("HelloAluKa",100,60);
不同的机器上有不同的字体, AWT定义了几个标准的字体:
SansSerif
Serif
Monospaced
Dialog
Dialoglnput
这些字体在不同的机器上会自适应相应的实际字体,比如在windows上SansSerif会自动映射成Arial;
也可以从网络上获取本地没有的字体, 比如:
然后有一个比较烦的关于字体的显示布局:
差不多就是这样, 然后上一些关于字体的常用方法:
5.显示图片
测试代码如下:
import javax.swing.*;
import java.awt.*;
public class ImageTest {
public static void main(String[] args) {
EventQueue.invokeLater(()->{
JFrame frame = new ImageFrame();
frame.setTitle("Recluse");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
class ImageFrame extends JFrame{
public ImageFrame(){
add(new ImageComponent());
pack();
}
}
class ImageComponent extends JComponent{
private static final int DEFAULT_WIDTH=500;
private static final int DEFAULT_HEIGHT=500;
private Image image;
public ImageComponent(){
image = new ImageIcon("IMG_3225.JPG").getImage();
}
public void paintComponent(Graphics g){
if(image==null) return;
int imagewidth = image.getWidth(null);
int imageheight = image.getHeight(null);
g.drawImage(image,0,0,null);
for(int i=0;i*imagewidth<=getWidth();i++){
for(int j=0;j*imageheight<=getHeight();j++){
g.copyArea(0,0,imagewidth,imageheight,i*imagewidth,j*imageheight);
}
}
}
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH,DEFAULT_HEIGHT);
}
}
效果如下:
那大概分析一下, 第一段都是差不多的, 就是在任务队列里加入一个窗口
EventQueue.invokeLater(()->{
JFrame frame = new ImageFrame();
frame.setTitle("Recluse");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
然后也是一样, 创建一个类继承JFrame然后初始化的时候画图, 然后pack:
add(new ImageComponent());
pack();
然后自定义一个ImageComponent类继承JComponent类, 里面定义一个Image类, 然后在构造函数里面传入一个图片:
image = new ImageIcon("IMG_3225.JPG").getImage();
然后写一个paintComponent函数覆写原函数:
public void paintComponent(Graphics g){
if(image==null) return;
int imagewidth = image.getWidth(null);
int imageheight = image.getHeight(null);
g.drawImage(image,0,0,null);
for(int i=0;i*imagewidth<=getWidth();i++){
for(int j=0;j*imageheight<=getHeight();j++){
g.copyArea(0,0,imagewidth,imageheight,i*imagewidth,j*imageheight);
}
}
}
先获取image的width和height, 然后用drawImage来画图第一张图, 最后用copyArea来拷贝一定区域内的图片(传进来一个起始点坐标, 和要复制的区域的宽和高, 然后是拷贝到的位置和起始坐标的dx和dy距离)
最后用getPreferredSize去改变窗口大小;
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH,DEFAULT_HEIGHT);
}
然后是一些常用的显示图片用的常用方法:
差不多就这样吧, 一些简单的2D GUI内容, 以后用Swing再说吧:D
晚安 ?