1、前提知识
- 布局:Layout
- 什么是布局?界面元素的排布和变化规律
- 案例:计算器
- 开发布局,用到Java中的哪个包?
- java.awt
- 文档浏览
2、案例引入:界面上放10个按钮
import javax.swing.*;
import java.awt.*;
class LayoutTest1 extends JFrame{
private JPanel jpl = new JPanel();
public LayoutTest1(){
FlowLayout fl = new FlowLayout(FlowLayout.LEFT, 20, 50);
jpl.setLayout(fl);
JButton[] bts = new JButton[10];
for(int i=0; i<10; i++){
bts[i] = new JButton("按钮"+i);
jpl.add(bts[i]);
}
this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public static void main (String[] args) {
new LayoutTest1();
}
}
3、布局方式1:流式布局(FlowLayout)
- 从左到右,从上到下排布;JPanel默认是这种布局方式
- 该布局由java.awt.FlowLoyout管理;通过容器的setLayout函数可以设置
4、布局方式2:网格布局(GridLayout)
- 将容器分为多行多列;例如计算器中的数字面板
- 案例:界面上放置24个按钮,6行,4列
- 案例:界面上添加一个国际象棋棋盘,8*8,黑白交错
package frame;
import javax.swing.*;
import java.awt.*;
class Test extends JFrame{
private JPanel jpl = new JPanel();
public Test(){
jpl.setLayout(new GridLayout(6,4,5,5));
JButton[] bts = new JButton[24];
for(int i=0; i<24; i++){
bts[i] = new JButton("按钮"+i);
jpl.add(bts[i]);
}
this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public static void main (String[] args) {
new Test();
}
}
package frame;
import javax.swing.*;
import java.awt.*;
class Test extends JFrame{
private JPanel jpl = new JPanel();
public Test(){
jpl.setLayout(new GridLayout(8,8));
JPanel[][] pls = new JPanel[8][8];
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
pls[i][j] = new JPanel();
if((i+j)%2==0){
pls[i][j].setBackground(Color.white);
}else{
pls[i][j].setBackground(Color.black);
}
jpl.add(pls[i][j]);
}
}
this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public static void main (String[] args) {
new Test();
}
}
5、布局方式3:边界布局(BorderLayout)
- 将容器分为东西南北中五个位置;上北下南左西右东
import javax.swing.*;
import java.awt.*;
class LayoutTest1 extends JFrame{
private JPanel jpl = new JPanel();
public LayoutTest1(){
jpl.setLayout(new BorderLayout());
jpl.add(new JButton("按钮东"), BorderLayout.EAST);
jpl.add(new JButton("按钮西"), BorderLayout.WEST);
jpl.add(new JButton("按钮南"), BorderLayout.SOUTH);
jpl.add(new JButton("按钮北"), BorderLayout.NORTH);
jpl.add(new JButton("按钮中"), BorderLayout.CENTER);
this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public static void main (String[] args) {
new LayoutTest1();
}
}
6、布局方式4:空布局(万能布局)
- 将容器的Layout设置为null,然后用坐标来确定容器中的元素位置
import javax.swing.*;
import java.awt.*;
class LayoutTest1 extends JFrame{
private JPanel jpl = new JPanel();
public LayoutTest1(){
jpl.setLayout(null);
JButton jbt = new JButton("按钮");
jbt.setLocation(300,200);
jbt.setSize(200,400);
jpl.add(jbt);
this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public static void main (String[] args) {
new LayoutTest1();
}
}
——————习题——————
1、界面上一副图片,鼠标进入图片,图片自动避开到另一个地方
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class LayoutTest1 extends JFrame implements MouseListener{
private JPanel jpl = new JPanel();
private Icon ico = new ImageIcon("img.jpg");
private JLabel jlb = new JLabel(ico);
public LayoutTest1(){
jlb.addMouseListener(this);
jpl.setLayout(null);
jlb.setLocation(300,200);
jlb.setSize(ico.getIconWidth(),ico.getIconHeight());
jpl.add(jlb); this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
int X = (int)(Math.random() * 800);
int Y = (int)(Math.random() * 600);
jlb.setLocation(X,Y);
}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public static void main (String[] args) {
new LayoutTest1();
}
}
2、界面上一副图片,鼠标可以将图片从一个地方拖到另一个地方
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class LayoutTest1 extends JFrame implements MouseMotionListener {
private JPanel jpl = new JPanel();
private Icon ico = new ImageIcon("img.jpg");
private JLabel jlb = new JLabel(ico);
public LayoutTest1(){
this.addMouseMotionListener(this);
jpl.setLayout(null);
jlb.setLocation(300,200);
jlb.setSize(ico.getIconWidth(),ico.getIconHeight());
jpl.add(jlb); this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public void mouseDragged(MouseEvent e){
int X = e.getX(); int Y = e.getY();
jlb.setLocation(X,Y);
}
public void mouseMoved(MouseEvent e){}
public static void main (String[] args) {
new LayoutTest1();
}
}
3、界面上一副图片,通过键盘上下左右键控制其移动
KeyListener
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class LayoutTest1 extends JFrame implements KeyListener {
private JPanel jpl = new JPanel();
private Icon ico = new ImageIcon("img.jpg");
private JLabel jlb = new JLabel(ico);
public LayoutTest1(){
this.addKeyListener(this);
jpl.setLayout(null);
jlb.setLocation(300,200);
jlb.setSize(ico.getIconWidth(),ico.getIconHeight());
jpl.add(jlb); this.add(jpl);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
int X = jlb.getX(); int Y = jlb.getY();
if(code==KeyEvent.VK_UP){
Y-=ico.getIconHeight();
}else if(code==KeyEvent.VK_DOWN){
Y+=ico.getIconHeight();
}else if(code==KeyEvent.VK_LEFT){
X-=ico.getIconWidth();
}else if(code==KeyEvent.VK_RIGHT){
X+=ico.getIconWidth();
}
jlb.setLocation(X,Y);
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public static void main (String[] args) {
new LayoutTest1();
}
}
7、绘图的前提
- 画架:JFrame
- 画布:JPanel
- 画笔:??
- 现场编程案例:在界面上放置一个画布
- 基本结构:编写画布(JPanel子类),放置在JFrame上
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel{
public void paint(Graphics g){
System.out.println("Hello");
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
8、画笔
- JPanel有一个paint函数,函数中包含画笔
- public void paint(Graphics g)
- 该函数中的参数,可以当成画笔使用
- 该函数在界面刷新时自动调用
- 绘图功能,写在paint函数中,用Graphics作为画笔
- Graphics有drawXXX和fillXXX函数绘图;setColor函数设置颜色
- 案例:界面上绘制椭圆和线段,用不同颜色
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel{
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(100,100,200,300);
g.setColor(Color.blue);
g.fillOval(100,200,200,100);
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
9、界面手工刷新:调用paint
- 用画布的repaint函数调用paint
- 案例:界面上不断出现随机位置,随机颜色,随机大小的椭圆
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel implements Runnable{
public MyCanvas(){
new Thread(this).start();
}
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(new Color((int)(Math.random()*256), (int)(Math.random()*256), (int)(Math.random()*256)));
int X = (int)(Math.random()*this.getWidth());
int Y = (int)(Math.random()*this.getHeight());
int W = (int)(Math.random()*100);
int H = (int)(Math.random()*100);
g2d.fillOval(X,Y,W,H);
}
public void run(){
while(true){
try { Thread.sleep(100); } catch(Exception ex){}
this.repaint();
}
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
10、画笔Graphics升级版:Graphics2D
- 可以将Graphics对象直接转成Graphics2D使用
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel implements Runnable{
public MyCanvas(){
new Thread(this).start();
}
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(10));
g2d.setColor(new Color((int)(Math.random()*256), (int)(Math.random()*256), (int)(Math.random()*256)));
int X = (int)(Math.random()*this.getWidth());
int Y = (int)(Math.random()*this.getHeight());
int W = (int)(Math.random()*100);
int H = (int)(Math.random()*100);
g2d.drawOval(X,Y,W,H);
}
public void run(){
while(true){
try { Thread.sleep(100); } catch(Exception ex){}
this.repaint();
}
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
11、绘制图像
- 使用画笔的drawImage函数
- 案例:将img.jpg绘制在界面上
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel {
Image img = Toolkit.getDefaultToolkit().createImage("img.jpg");
public void paint(Graphics g){
g.drawImage(img,100,100,this);
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
- 直接绘制图像
- drawImage(Image img,int x,int y, ImageObserver observer)
- 案例:将img.jpg缩放绘制在界面上
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel {
Image img = Toolkit.getDefaultToolkit().createImage("img.jpg");
public void paint(Graphics g){
g.drawImage(img,100,100,this);
g.drawImage(img,500,500, 200, 200, this);
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
- 缩放绘制图像
drawImage(Image img,int x,int y, int width,
int height,ImageObserver observer)案例:图像自动在界面上放大
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel implements Runnable {
int W = 0;
int H = 0;
Image img = Toolkit.getDefaultToolkit().createImage("img.jpg");
MyCanvas(){
new Thread(this).start();
}
public void paint(Graphics g){
g.drawImage(img,100,100, W, H, this);
}
public void run(){
while(true){
W+=10; H+=8;
repaint();
try{ Thread.sleep(100); } catch(Exception e){}
}
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
- 裁剪绘制图像
- drawImage(Image img,int dx1,int dy1,
int dx2, int dy2,
int sx1, int sy1,
int sx2, int sy2,
ImageObserver observer) - 案例:将图像的下半部分绘制在界面,充满界面
- drawImage(Image img,int dx1,int dy1,
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel {
Image img = Toolkit.getDefaultToolkit().createImage("img.jpg");
public void paint(Graphics g){
g.drawImage(img,0,0, this.getWidth(), this.getHeight(),
0, img.getHeight(this)/2, img.getWidth(this),img.getHeight(this) ,
this);
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
- 旋转绘制图像
- 旋转绘制,实际上是画布旋转
- 使用Graphics2D的rotate函数
- rotate(double theta, double x, double y)
- 绕圆心旋转某弧度
import javax.swing.*;
import java.awt.*;
class MyCanvas extends JPanel {
Image img = Toolkit.getDefaultToolkit().createImage("img.jpg");
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.rotate(Math.PI/4, 100+img.getWidth(this)/2,100+img.getHeight(this)/2);
g.drawImage(img,100,100,this);
}
}
class PaintTest extends JFrame{
MyCanvas mc = new MyCanvas();
public PaintTest(){
this.add(mc);
this.setSize(800,600);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new PaintTest();
}
}
本文含有隐藏内容,请 开通VIP 后查看