• WAP手机版 保存到桌面加入收藏设为首页
科技文本

《Java编程语言:原理与范例》课后实验源代码

时间:2018-10-29 21:20:19   作者:文件下载QQ:1002732220   来源:   阅读:302   评论:0
内容摘要:第一章实验一packagech01;importjava.text.SimpleDateFormat;importjava.util.Date;classTimerextendsThread{privateSimpleDateFormatsdf=newSimpleDateFormat("yyyy年MM月dd日HH:mm...

第一章

实验一

package ch01;

import java.text.SimpleDateFormat;

import java.util.Date;

 

class Timer extends Thread {

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");

 

    public void run() {

        while (true) {

            System.out.print("\r现在时间是:");

            Date now = new Date();

            System.out.print(sdf.format(now));

            try {

                sleep(1000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    }

}

 

public class Clock {

    public static void main(String[] args) {

        Timer timer = new Timer();

        timer.start();

    }

}

实验二

package ch01;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.util.Random;

 

import javax.swing.JButton;

import javax.swing.JFrame;

 

public class MagicButton extends MouseAdapter {

    JFrame win;

    JButton button = new JButton("你点不到我");

    Random rand = new Random();

 

    void initUI() {

        win = new JFrame();

        win.setLayout(null);

 

        button.setSize(100, 40);

        button.addMouseListener(this);

 

        win.add(button);

        win.setSize(400, 300);

        win.setResizable(false);

        win.setLocationRelativeTo(null);

        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        win.setVisible(true);

    }

 

    public static void main(String[] args) {

        MagicButton demo = new MagicButton();

        demo.initUI();

    }

 

    public void mouseEntered(MouseEvent e) {

        int mouseX = button.getX() + e.getX();

        int mouseY = button.getY() + e.getY();

 

        while (true) {

            int buttonX = rand.nextInt(win.getWidth() - button.getWidth());

            int buttonY = rand.nextInt(win.getHeight() - button.getHeight());

            button.setLocation(buttonX, buttonY);

 

            if (!button.getBounds().contains(mouseX, mouseY)) {

                break;

            }

        }

    }

}


 

 

 

 

 

 

 

第二章

实验一

/*********************************

2.  交换两个变量的值(不允许使用中间变量)。

 **********************************/

package ch03;

 

public class Exp2_2 {

public static void main(String[] args) {

int a = 2, b = 3;

int s = a * b;

a = s / a;

b = s / a;

System.out.println("a=" + a + ", b=" + b);

}

}

实验二

/*********************************

3.  逆序输出一个7位整数,如8639427输出为7249368(不允许使用循环语句)。

 **********************************/

package ch03;

 

public class Exp2_3 {

public static void main(String[] args) {

long a = 8639427;

System.out.print(a % 10);

System.out.print(a / 10 % 10);

System.out.print(a / 100 % 10);

System.out.print(a / 1000 % 10);

System.out.print(a / 10000 % 10);

System.out.print(a / 100000 % 10);

System.out.print(a / 1000000 % 10);

}

}

实验三

/*********************************

4.  对于int型变量a,以最快的速度计算34×a的值。

 **********************************/

package ch03;

 

public class Exp2_4 {

public static void main(String[] args) {

int a = 3;

int b = (a << 5) + (a << 1);

System.out.println(a + "*34=" + b);

}

}

实验四

/*********************************

5.  字符型变量ch中存放着一个大小写未知的英文字母,判断其大小写后,将ch的值转为小写或大写字母(不允许使用加减运算符和if语句)。

 **********************************/

package ch03;

 

public class Exp2_5 {

public static void main(String[] args) {

char ch = 'E';

ch = (char) ((ch & 32) == 0 ? ch | 32 : ch & (Integer.MAX_VALUE - 32));

System.out.println("ch1=" + ch);

}

}

实验5

/*********************************

6.  使用嵌套的条件运算符,求a、b、c中的最大者。

 **********************************/

package ch03;

 

public class Exp2_6 {

public static void main(String[] args) {

int a = 2, b = 4, c = 3;

int max = (a > b ? a : b) > c ? (a > b ? a : b) : c;

System.out.println("max=" + max);

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第三章

实验一

/*********************************

2. 使用循环结构逆序输出任意位数的整数。

 **********************************/

package ch04;

 

import java.util.Scanner;

 

public class Exp3_2 {

public static void main(String[] args) {

Scanner s = new Scanner(System.in);

System.out.println("输入整数:");

long n = s.nextLong();

while (n > 0) {

System.out.print(n % 10);

n /= 10;

}

}

 

}

实验二

/*********************************

3.  输出以下由数字组成的菱形(要求将输出行数存放于变量中以便随时更改)。

          1  

       1  2  1  

    1  2  3  2  1  

 1  2  3  4  3  2  1  

    1  2  3  2  1  

       1  2  1  

          1  

 **********************************/

package ch04;

 

import java.util.Scanner;

 

public class Exp3_3 {

public static void main(String[] args) {

int rows;

Scanner s = new Scanner(System.in);

System.out.print("输入行数:");

rows = s.nextInt();

 

for (int i = -rows / 2; i <= rows / 2; i++) {

System.out.printf("%-" + (3 * Math.abs(i) + 1) + "s", "");

for (int j = Math.abs(i) - rows / 2; j <= rows / 2 - Math.abs(i); j++) {

System.out.printf("%-3d", rows / 2 + 1 - Math.abs(i) - Math.abs(j));

}

System.out.println();

}

}

 

}

实验三

/*********************************

4.  输出以上由数字组成的三角形(要求将输出行数存放于变量中以便随时更改)。

1   3   6   10  15  21  

2   5   9   14  20  

4   8   13  19  

7   12  18  

11  17  

16  

 **********************************/

package ch04;

 

import java.util.Scanner;

 

public class Exp3_4 {

public static void main(String[] args) {

int rows;

Scanner s = new Scanner(System.in);

System.out.print("输入行数:");

rows = s.nextInt();

 

int firstNumOfRow = 1, nextNumOfRow;

 

for (int i = 1; i <= rows; i++) {

firstNumOfRow += i - 1;

int firstStepOfRow = i + 1;

nextNumOfRow = firstNumOfRow;

for (int j = 1; j <= rows + 1 - i; j++) {

System.out.printf("%-4d", nextNumOfRow);

nextNumOfRow += firstStepOfRow++;

}

System.out.println();

}

}

 

}

实验四

/*********************************

5.  计算多项式8+88+888+8888+88888+... 的前8项之和。

输出结果:

98765424

 **********************************/

package ch04;

 

public class Exp3_5 {

public static void main(String[] args) {

long sum = 0;

for (int i = 1; i <= 8; i++) {

long num = 0;

for (int j = 1; j <= i; j++) {

num = num * 10 + 8;

}

sum += num;

}

System.out.println(sum);

}

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第四章

实验一

/*********************************

1.  产生10个100以内的随机整数以填充一维数组,实现以下功能。

① 找出最大以及最小值。

② 查找给定整数a在数组中最后一次出现的位置,若不存在则提示。

③ 判断数组是否呈非递减排列。

④ 将数组元素翻转存放。

 **********************************/

package ch05;

 

import java.util.Random;

import java.util.Scanner;

 

public class Exp4_1 {

int[] init() {

int[] a = new int[10];

Random r = new Random();

for (int i = 0; i < a.length; i++) {

a[i] = r.nextInt(100);

}

return a;

}

 

void print(int[] a) {

for (int i = 0; i < a.length; i++) {

System.out.printf("%-5d", a[i]);

}

System.out.println();

}

 

int findMax(int[] a) {

int max = a[0];

for (int i = 1; i < a.length; i++) {

if (max < a[i]) {

max = a[i];

}

}

return max;

}

 

int findMin(int[] a) {

int min = a[0];

for (int i = 1; i < a.length; i++) {

if (min > a[i]) {

min = a[i];

}

}

return min;

}

 

int findLastLocation(int[] a, int x) {

for (int i = a.length - 1; i >= 0; i--) {

if (a[i] == x) {

return i;

}

}

return -1;

}

 

boolean isAsc(int[] a) {

for (int i = 0; i < a.length - 1; i++) {

if (a[i] > a[i + 1]) {

return false;

}

}

return true;

}

 

void reverse(int[] a) {

for (int i = 0; i < a.length / 2; i++) {

int temp = a[i];

a[i] = a[a.length - i - 1];

a[a.length - i - 1] = temp;

 

}

}

 

public static void main(String[] args) {

Exp4_1 t = new Exp4_1();

int[] a = t.init();

t.print(a);

 

System.out.println("max=" + t.findMax(a));

System.out.println("min=" + t.findMin(a));

System.out.print("输入要查找的数:");

Scanner s = new Scanner(System.in);

int x = s.nextInt();

int i = t.findLastLocation(a, x);

if (i == -1) {

System.out.println(x + " 在数组中不存在。");

} else {

System.out.printf("Last location of %d: %d。\n", x, i);

}

 

if (t.isAsc(a)) {

System.out.println("数组是非递减排列!");

} else {

System.out.println("数组不是非递减排列!");

}

 

t.reverse(a);

System.out.println("翻转后的数组:");

t.print(a);

}

}

实验二

/*********************************

2.  将a插入到一个长度不小于10且元素呈递增排列的一维数组中,并保证插入之后的数组依然递增(若a在插入前的数组中存在,则输出提示并忽略)。

 **********************************/

package ch05;

 

import java.util.Scanner;

 

public class Exp4_2 {

int a[] = { 2, 4, 5, 7, 9, 11, 15, 17, 20, 22, Integer.MAX_VALUE };

 

void print(boolean isAfterInsert) {

int end = isAfterInsert ? a.length : a.length - 1;

for (int i = 0; i < end; i++) {

System.out.printf("%-5d", a[i]);

}

System.out.println();

}

 

int findInsertLocation(int x) {

int i = 0;

for (; i < a.length - 1; i++) {

if (a[i] == x) {

return -1;

} else if (a[i] > x) {

return i;

}

}

return i;

}

 

void insert(int i, int x) {

for (int j = a.length - 2; j >= i; j--) {

a[j + 1] = a[j];

}

a[i] = x;

}

 

public static void main(String[] args) {

Exp4_2 t = new Exp4_2();

t.print(false);

 

System.out.print("输入要插入的数:");

Scanner s = new Scanner(System.in);

int x = s.nextInt();

 

int i = t.findInsertLocation(x);

if (i == -1) {

System.out.println(x + " 在数组中已经存在,放弃插入!");

} else {

t.insert(i, x);

t.print(true);

}

}

 

}

实验三

/*********************************

3.  找出阶数不小于8的方阵的鞍点值及位置(鞍点值在该行上最大、该列上最小),若无鞍点则提示。

 **********************************/

package ch05;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.Scanner;

 

/**

 * 鞍点对象类

 */

class AnDian {

private int row; // 鞍点所在行下标

private int col; // 鞍点所在列下标

private int value; // 鞍点值

 

// 完全构造方法

public AnDian(int row, int col, int value) {

this.row = row;

this.col = col;

this.value = value;

}

 

// getters and setters

public int getRow() {

return row;

}

 

public void setRow(int row) {

this.row = row;

}

 

public int getCol() {

return col;

}

 

public void setCol(int col) {

this.col = col;

}

 

public int getValue() {

return value;

}

 

public void setValue(int value) {

this.value = value;

}

}

 

/**

 * 测试类(整体上是若干个并列的2重循环,时间复杂度较3重循环低)

 */

public class Exp4_3 {

int[][] a; // 矩阵

int maxOfRows[]; // 存放每行的最大值

int minOfCols[]; // 存放每列的最小值

final int LIMIT = 3; // 矩阵元素值的上限(为测试方便此处写死,也可在运行时由用户输入)

 

// 初始化矩阵

void initArray() {

Scanner scanner = new Scanner(System.in);

System.out.print("输入矩阵行数:");

int m = scanner.nextInt(); // 矩阵行数

System.out.print("输入矩阵列数:");

int n = scanner.nextInt(); // 矩阵列数

 

// 构造各数组

a = new int[m][n];

maxOfRows = new int[m];

minOfCols = new int[n];

 

// 以随机数填充矩阵

Random random = new Random();

for (int i = 0; i < a.length; i++) {

for (int j = 0; j < a[i].length; j++) {

a[i][j] = random.nextInt(LIMIT);

}

}

 

// 记录每行的最大值

int max;

for (int i = 0; i < a.length; i++) {

max = a[i][0];

for (int j = 1; j < a[i].length; j++) {

if (max < a[i][j]) {

max = a[i][j];

}

}

maxOfRows[i] = max;

}

 

// 记录每列的最小值

int min;

for (int j = 0; j < a[0].length; j++) {

min = a[0][j];

for (int i = 1; i < a.length; i++) {

if (min > a[i][j]) {

min = a[i][j];

}

}

minOfCols[j] = min;

}

}

 

// 打印矩阵

void printArray() {

System.out.println("得到的矩阵为:");

for (int i = 0; i < a.length; i++) {

for (int j = 0; j < a[i].length; j++) {

System.out.printf("%-8d", a[i][j]);

}

System.out.println();

}

}

 

// 找鞍点(可能有多个),返回类型为线性表类型(List),尖括号语法为泛型,表示线性表的元素为AnDian对象,具体看教材

List<AnDian> findAnDian() {

List<AnDian> anDians = new ArrayList<AnDian>(); // 构造线性表对象

for (int i = 0; i < a.length; i++) { // 扫描矩阵中的每个元素

for (int j = 0; j < a[i].length; j++) {

// 是当前行最大且当前列最小

if (a[i][j] == maxOfRows[i] && a[i][j] == minOfCols[j]) {

AnDian p = new AnDian(i, j, a[i][j]); // 构造AnDian对象

anDians.add(p); // 加入AnDian对象到线性表

}

}

}

return anDians; // 返回线性表

}

 

// 测试入口

public static void main(String[] args) {

Exp4_3 o = new Exp4_3();

o.initArray();

o.printArray();

List<AnDian> anDians = o.findAnDian();

 

System.out.println("------------------------");

if (anDians.size() == 0) { // 返回的线性表元素个数为0

System.out.println("没有鞍点。");

} else {

int i = 0;

for (AnDian e : anDians) { // 迭代性for循环的语法也可用于线性表类型

System.out.printf("鞍点%-4d:a[%-3d][%-3d] = %-8d\n", ++i, e.getRow(), e.getCol(), e.getValue());

}

}

}

}

实验四

/*********************************

4.  编写如下图所示的程序以模拟命令行的copy命令。

 **********************************/

package ch05;

 

public class Exp4_4 {

public static void main(String[] args) {

if (args.length != 2) {

System.err.println("命令语法不正确,使用格式为:java  Exp4_4  要复制的文件   复制到的路径");

return;

}

System.out.println("成功将\"" + args[0] + "\" 复制到 \"" + args[1] + "\"。");

}

}

实验五/*********************************

5.  输出如上图所示的循环移位方阵(第一行存于一维数组,循环右移该行元素一个位置以产生下一行,以此类推)。

7    4    8    9    1    5    

5    7    4    8    9    1    

1    5    7    4    8    9    

9    1    5    7    4    8    

8    9    1    5    7    4    

4    8    9    1    5    7   

 **********************************/

package ch05;

 

public class Exp4_5 {

void shift(int[] a) {

int last = a[a.length - 1];

for (int i = a.length - 2; i >= 0; i--) {

a[i + 1] = a[i];

}

a[0] = last;

}

 

void print(int[] a) {

for (int i = 0; i < a.length; i++) {

System.out.printf("%-5d", a[i]);

}

System.out.println();

}

 

public static void main(String[] args) {

Exp4_5 t = new Exp4_5();

int[] a = { 7, 4, 8, 9, 1, 5 };

t.print(a);

for (int i = 0; i < a.length - 1; i++) {

t.shift(a);

t.print(a);

}

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第五章

实验一

/*********************************

2.  在例6.17的基础上,将draw方法改为计算形状自身面积的calcArea方法并在测试类中测试。

提示:可根据需要在Shape的每个子类中增加用以计算面积所必须的字段,如为Square类增加边长

字段、Circle类增加半径字段等,然后编写含相应字段的构造方法以构造具体的形状对象。

 

输出结果:

s1的面积:4.0

s2的面积:6.0

s3的面积:12.566370614359172

 **********************************/

package ch06;

 

class Shape {

public double calcArea() {

return 0;

}

}

 

class Square extends Shape {

float width;

 

public Square(int width) {

this.width = width;

}

 

public double calcArea() {

return width * width;

}

}

 

class Triangle extends Shape {

float a, b, c;

 

public Triangle(float a, float b, float c) {

this.a = a;

this.b = b;

this.c = c;

}

 

public double calcArea() {

float s = (a + b + c) / 2;

return Math.sqrt(s * (s - a) * (s - b) * (s - c));

}

}

 

class Circle extends Shape {

float radius;

 

public Circle(float radius) {

this.radius = radius;

}

 

public double calcArea() {

return Math.PI * radius * radius;

}

}

 

public class Exp5_2 {

public static void main(String[] args) {

Shape s1 = new Square(2);

Shape s2 = new Triangle(3, 4, 5);

Shape s3 = new Circle(2);

System.out.println("s1的面积:" + s1.calcArea());

System.out.println("s2的面积:" + s2.calcArea());

System.out.println("s3的面积:" + s3.calcArea());

}

}

实验二

/*********************************

3.  编写TimeCounter类,其静态方法startCount(int  begin)方法根据指定的初始

秒数begin在命令行显示倒计时(每隔1秒刷新,时间为0时退出程序),然后在main方法

中调用startCount方法。

 **********************************/

package ch06;

 

public class Exp5_3 {

static void startCount(int begin) {

while (begin > 0) {

System.out.println(begin);

long init = System.currentTimeMillis();

while (true) {

long now = System.currentTimeMillis();

if (now - init >= 1000) {

begin--;

break;

}

}

}

System.out.println("时间到!");

}

 

public static void main(String[] args) {

startCount(5);

}

}

实验三

/*********************************

4.  编写Complex类表示数学上的复数概念,具体包括:

① real和image字段,分别表示复数的实部和虚部。

② 读取和设置real/image字段的get和set方法。

③ 根据实部和虚部参数构造复数对象的构造方法。

④ 打印当前复数对象内容以及与另一复数相加的方法,原型为:

void  printInfo();  

Complex  add(Complex  anotherComplex);

⑤ 重写父类Object的equals方法,相等逻辑为“若2个复数对象的实部和虚部分别对应相等,则这2个复数相等”。

最后编写一个带main方法的测试类ComplexTest,分别测试Complex中的各个方法。

 **********************************/

package ch06;

 

class Complex {

float real;

float image;

 

public float getReal() {

return real;

}

 

public void setReal(float real) {

this.real = real;

}

 

public float getImage() {

return image;

}

 

public void setImage(float image) {

this.image = image;

}

 

public Complex(float real, float image) {

this.real = real;

this.image = image;

}

 

void printInfo() {

System.out.println(real + (image > 0 ? "+" : "-") + Math.abs(image) + "i");

}

 

Complex add(Complex anotherComplex) {

Complex c = new Complex(0, 0);

c.setReal(this.real + anotherComplex.getReal());

c.setImage(this.image + anotherComplex.getImage());

return c;

}

 

public boolean equals(Object obj) {

Complex c = (Complex) obj;

return this.real == c.getReal() && this.image == c.getImage();

}

}

 

public class Exp5_4 {

public static void main(String[] args) {

Complex c1 = new Complex(1, -2);

Complex c2 = new Complex(2, 6);

Complex c3 = c1.add(c2);

Complex c4 = c2.add(c1);

 

System.out.print("c1=");

c1.printInfo();

 

System.out.print("c2=");

c2.printInfo();

 

System.out.print("c3=");

c3.printInfo();

 

System.out.print("c4=");

c4.printInfo();

 

System.out.println(c1.equals(c2) ? "c1=c2" : "c1!=c2");

System.out.println(c3.equals(c4) ? "c3=c4" : "c3!=c4");

}

}

实验四

/*********************************

5.  查阅java.util包下的GregorianCalendar类的API文档,编写MyDate类继承该类,并实现以下方法:

MyDate(int year, int month, int day); // 根据指定的年月日构造日期对象

int getYear();          // 得到当前日期的年份

int getMonth();        // 得到当前日期的月份

int getDayOfYear();   // 得到当前日期是本年的第几天

int getDayOfMonth();  // 得到当前日期是本月的第几天

int getDayOfWeek();   // 得到当前日期是本周的第几天(即星期几)

MyDate getBeforeDate(int beforeDays);// 得到当前日期之前若干天对应的日期对象

MyDate getAfterDate(int afterDays);  // 得到当前日期之后若干天对应的日期对象

int daysBetweenWith(MyDate d);        // 得到当前日期与指定日期d相隔多少天

最后编写一个带main方法的测试类MyDateTest,分别测试MyDate中的各个方法。

提示:① 可通过父类GregorianCalendar相应方法的组合以实现上述各方法。

② 注意父类中根据年月日创建日历对象的构造方法中,月份参数是从0开始的。

 **********************************/

package ch06;

 

import java.util.GregorianCalendar;

 

class MyDate extends GregorianCalendar {

MyDate(int year, int month, int day) {

super(year, month - 1, day);

}

 

int getYear() {

return super.get(YEAR);

}

 

int getMonth() {

return super.get(MONTH) + 1;

}

 

int getDayOfYear() {

return super.get(DAY_OF_YEAR);

}

 

int getDayOfMonth() {

return super.get(DAY_OF_MONTH);

}

 

int getDayOfWeek() {

return super.get(DAY_OF_WEEK);

}

 

MyDate getBeforeDate(int beforeDays) {

long time = super.getTimeInMillis() - beforeDays * 24L * 60 * 60 * 1000;

GregorianCalendar gc = new GregorianCalendar();

gc.setTimeInMillis(time);

return new MyDate(gc.get(YEAR), gc.get(MONTH) + 1, gc.get(DAY_OF_MONTH));

}

 

MyDate getAfterDate(int afterDays) {

long time = super.getTimeInMillis() + afterDays * 24L * 60 * 60 * 1000;

GregorianCalendar gc = new GregorianCalendar();

gc.setTimeInMillis(time);

return new MyDate(gc.get(YEAR), gc.get(MONTH) + 1, gc.get(DAY_OF_MONTH));

}

 

int daysBetweenWith(MyDate d) {

long t1 = super.getTimeInMillis();

long t2 = d.getTimeInMillis();

return (int) (Math.abs(t1 - t2) / (24 * 60 * 60 * 1000));

}

 

void print(String name) {

System.out.printf("%-4s: %d-%d-%d\n", name, getYear(), getMonth(), getDayOfMonth());

}

}

 

public class Exp5_5 {

public static void main(String[] args) {

MyDate d1 = new MyDate(2014, 3, 12);

MyDate d2 = new MyDate(2012, 5, 5);

MyDate d3 = new MyDate(2013, 3, 12);

 

d1.print("d1");

d2.print("d2");

d3.print("d3");

 

System.out.println("d3 是该星期的第 " + d3.getDayOfWeek() + " 天");

System.out.println("d3 是该月的第 " + d3.getDayOfMonth() + " 天");

System.out.println("d3 是该年的第 " + d3.getDayOfYear() + " 天");

 

d1.getAfterDate(50).print("d1 的 50 天后");

d2.getBeforeDate(365).print("d2 的 365 天前");

System.out.println("d2 和 d3 间相差 " + d2.daysBetweenWith(d3) + " 天");

}

}

第六章

实验一

/*********************************

2.  编写程序实现以下逻辑。

① 抽象类Animal具有一个抽象方法walk

② 接口Flyable具有一个方法fly

③ 类Bird继承Animal并实现Flyable

编写测试类BirdTest,在main方法中构造一个Bird对象并调用其walk和fly方法

(重写这2个方法时,打印一行用于模拟的字符串即可)。

 **********************************/

package ch07;

 

abstract class Animal {

abstract void walk();

}

 

interface Flyable {

void fly();

}

 

class Bird extends Animal implements Flyable {

void walk() {

System.out.println("Bird walking");

}

 

public void fly() {

System.out.println("Bird flying");

}

}

 

public class Exp6_2 {

public static void main(String[] args) {

Bird b = new Bird();

b.walk();

b.fly();

}

}

实验二

/*********************************

3.  接口MobilePhone定义了以下方法:

void on();         // 开机

void off();        // 关机

void charge();    // 充电

void call();       // 打电话

void play();       // 娱乐

 

分别采用如下两种方式创建两个实现MobilePhone接口的类的对象,

并在测试类中分别对这两个对象调用上述方法。

① 编写类IPhone4S实现MobilePhone接口。

② 使用实现了MobilePhone接口的匿名内部类。

 **********************************/

package ch07;

 

interface MobilePhone {

void on();

 

void off();

 

void charge();

 

void call();

 

void play();

}

 

class IPhone4S implements MobilePhone {

 

public void on() {

System.out.println("IPhone4S on");

}

 

public void off() {

System.out.println("IPhone4S off");

}

 

public void charge() {

System.out.println("IPhone4S charge");

}

 

public void call() {

System.out.println("IPhone4S call");

}

 

public void play() {

System.out.println("IPhone4S play");

}

}

 

public class Exp6_3 {

public static void main(String[] args) {

MobilePhone ip = new IPhone4S();

ip.on();

ip.off();

ip.charge();

ip.call();

ip.play();

 

MobilePhone htc = new MobilePhone() {

public void on() {

System.out.println("HTC on");

}

 

public void off() {

System.out.println("HTC off");

}

 

public void charge() {

System.out.println("HTC charge");

}

 

public void call() {

System.out.println("HTC call");

}

 

public void play() {

System.out.println("HTC play");

}

};

htc.on();

htc.off();

htc.charge();

htc.call();

htc.play();

}

}

实验三

/*********************************

4.  编写程序模拟用以表示直线的Line类,具体包含以下逻辑:

① 表示直线起点和终点的嵌套类Point,其包含描述横纵坐标的x、y字段。

② 表示直线方向的嵌套枚举Direction,其包含表示上下左右等方向的枚举常量。

Line类中编写必要的代码,然后在测试类LineTest中构造几个Line对象并输出每个对象的有关信息。

 **********************************/

package ch07;

 

import ch07.Line.Direction;

 

class Line {

class Point {

private int x;

private int y;

 

public Point(int x, int y) {

this.x = x;

this.y = y;

}

 

public int getX() {

return x;

}

 

public void setX(int x) {

this.x = x;

}

 

public int getY() {

return y;

}

 

public void setY(int y) {

this.y = y;

}

}

 

enum Direction {

UP, DOWN, LEFT, RIGHT;

}

 

private Point start;

private Point end;

private Direction direction;

 

void draw() {

System.out.printf("绘制直线:起点(%d, %d),终点(%d, %d),方向(%s)", start.getX(), start.getY(), end.getX(), end.getY(), direction.toString());

}

 

public Point getStart() {

return start;

}

 

public void setStart(Point start) {

this.start = start;

}

 

public Point getEnd() {

return end;

}

 

public void setEnd(Point end) {

this.end = end;

}

 

public Direction getDirection() {

return direction;

}

 

public void setDirection(Direction direction) {

this.direction = direction;

}

}

 

public class Exp6_4 {

public static void main(String[] args) {

Line line = new Line();

line.setStart(line.new Point(1, 2));

line.setEnd(line.new Point(5, 8));

line.setDirection(Direction.DOWN);

line.draw();

}

}

 

 

 

第七章

实验一

/*********************************

1.  编写满足以下要求的GUI程序。

① 顶部两个文本框只接受大于0小于11的整数。

② 文本框数字改变时,自动刷新下部网格区域的按钮。

③ 鼠标进入按钮时,在该按钮上显示“★”。

④ 鼠标移出按钮时,隐藏该按钮上的文字。

 **********************************/

package ch08;

 

import java.awt.BorderLayout;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

 

// 处理文本框输入事件的监听器

class MyKeyListener extends KeyAdapter {

public void keyTyped(KeyEvent e) {

char c = e.getKeyChar(); // 得到输入的字符

if (!(c >= KeyEvent.VK_0 && c <= KeyEvent.VK_9)) { // 不是数字字符

e.consume(); // 吃掉

}

}

}

 

// 处理鼠标进入退出按钮事件的监听器

class MyMouseListener extends MouseAdapter {

public void mouseEntered(MouseEvent e) {

JButton b = (JButton) e.getSource();

b.setText("★");

}

 

public void mouseExited(MouseEvent e) {

JButton b = (JButton) e.getSource();

b.setText("");

}

}

 

public class Exp7_1 extends JFrame implements ActionListener {

int rows = 5, cols = 4;

JTextField rowTf = new JTextField("" + rows);

JTextField colTf = new JTextField("" + cols);

JPanel center = new JPanel(); // 存放按钮的面板

 

MyKeyListener keyListener = new MyKeyListener();

MyMouseListener mouseListener = new MyMouseListener();

 

void addButtons() { // 将按钮加入center面板

center.setLayout(new GridLayout(rows, cols, 2, 2));

for (int i = 0; i < rows; i++) {

for (int j = 0; j < cols; j++) {

JButton b = new JButton();

b.addMouseListener(mouseListener);

center.add(b);

}

}

}

 

void initUI() {

JPanel top = new JPanel(new GridLayout(1, 4));

top.add(new JLabel("行数:"));

rowTf.addActionListener(this);

rowTf.addKeyListener(keyListener);

top.add(rowTf);

 

top.add(new JLabel("列数:"));

colTf.addActionListener(this);

rowTf.addKeyListener(keyListener);

top.add(colTf);

 

this.addButtons();

 

super.setLayout(new BorderLayout());

super.add(top, BorderLayout.NORTH);

super.add(center, BorderLayout.CENTER);

}

 

public void actionPerformed(ActionEvent e) {

if (e.getSource() == rowTf) {

rows = Integer.parseInt(rowTf.getText()); // 已经处理了键盘输入事件,此时的文本框文字一定可以解析为数字

// 判断行数是否超过了范围

if (rows > 10) {

rows = 10;

rowTf.setText("10");

} else if (rows < 1) {

rows = 1;

rowTf.setText("1");

}

} else {

cols = Integer.parseInt(colTf.getText());

// 判断行数是否超过了范围

if (cols > 10) {

cols = 10;

colTf.setText("10");

} else if (cols < 1) {

cols = 1;

colTf.setText("1");

}

}

center.removeAll(); // 删除面板中的所有组件

this.addButtons(); // 重新添加按钮到面板

center.validate(); // 通知系统重新排列面板

center.repaint(); // 重绘面板

}

 

public static void main(String[] args) {

Exp7_1 t = new Exp7_1();

t.initUI();

t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

t.setResizable(false);

t.setSize(600, 400);

t.setVisible(true);

}

}

实验二

/*********************************

2.  在窗口中按下鼠标左键并拖曳时,绘制矩形(要求使用适配器类)。

 **********************************/

package ch08;

 

import java.awt.Color;

import java.awt.Container;

import java.awt.Graphics;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

 

import javax.swing.JFrame;

 

// 鼠标按下和拖曳事件监听器

class MyMouserListener2 extends MouseAdapter {

private int x1, y1; // 按下坐标

private int x2, y2; // 拖曳坐标

 

private Container canvas; // 画布区域

 

public MyMouserListener2(Container canvas) {

this.canvas = canvas;

}

 

// 按下

public void mousePressed(MouseEvent e) {

x1 = e.getX();

y1 = e.getY();

}

 

// 拖曳

public void mouseDragged(MouseEvent e) {

Graphics g = canvas.getGraphics();

// 清除画布区域

g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());

g.setColor(Color.RED);

x2 = e.getX();

y2 = e.getY();

// 四种情况

if (x2 > x1 && y2 > y1) {

g.drawRect(x1, y1, x2 - x1, y2 - y1);

} else if (x2 > x1 && y2 < y1) {

g.drawRect(x1, y2, x2 - x1, y1 - y2);

} else if (x2 < x1 && y2 > y1) {

g.drawRect(x2, y1, x1 - x2, y2 - y1);

} else if (x2 < x1 && y2 < y1) {

g.drawRect(x2, y2, x1 - x2, y1 - y2);

}

 

}

}

 

public class Exp7_2 extends JFrame {

void initUI() {

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setResizable(false);

setSize(600, 400);

setVisible(true);

}

 

public static void main(String[] args) {

Exp7_2 t = new Exp7_2();

t.initUI();

MyMouserListener2 listener = new MyMouserListener2(t);

t.addMouseListener(listener);

t.addMouseMotionListener(listener);

}

}

实验三

/*********************************

3.  编写满足以下要求的GUI程序。

① 3个滚动条的可选值范围均为0~255,分别对应R、G、B颜色分量。

② 根据选择的单选按钮,拖动任意一个滚动条时,将3个滚动条组合而成的颜色作为下方文本框的前景色或背景色。

③ 初始状态下,单选按钮选择项、滚动条值、文本框前景或背景色应保持一致。

④ 在单选按钮间切换时,应将滚动条的值改变为相应颜色的颜色分量。

 **********************************/

package ch08;

 

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Font;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.AdjustmentEvent;

import java.awt.event.AdjustmentListener;

 

import javax.swing.ButtonGroup;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JRadioButton;

import javax.swing.JScrollBar;

import javax.swing.JTextField;

 

public class Exp7_3 extends JFrame implements ActionListener, AdjustmentListener {

JRadioButton foreColorRb = new JRadioButton("前景色", true);

JRadioButton backColorRb = new JRadioButton("背景色");

 

JScrollBar redScrollBar = new JScrollBar(JScrollBar.HORIZONTAL, 0, 10, 0, 265);

JScrollBar greenScrollBar = new JScrollBar(JScrollBar.HORIZONTAL, 0, 10, 0, 265);

JScrollBar blueScrollBar = new JScrollBar(JScrollBar.HORIZONTAL, 0, 10, 0, 265);

 

JTextField tf = new JTextField("测试文字");

 

void initUI() {

ButtonGroup group = new ButtonGroup();

group.add(foreColorRb);

group.add(backColorRb);

 

// 两个单选按钮所在的面板

JPanel rbPanel = new JPanel();

rbPanel.add(foreColorRb);

rbPanel.add(backColorRb);

 

// 三个滚动条及其标签所在的面板

JPanel scrPanel = new JPanel(new GridLayout(3, 1, 0, 10));

JPanel p1 = new JPanel(new BorderLayout());

p1.add(new JLabel("红:"), BorderLayout.WEST);

p1.add(redScrollBar, BorderLayout.CENTER);

scrPanel.add(p1);

 

JPanel p2 = new JPanel(new BorderLayout());

p2.add(new JLabel("绿:"), BorderLayout.WEST);

p2.add(greenScrollBar, BorderLayout.CENTER);

scrPanel.add(p2);

 

JPanel p3 = new JPanel(new BorderLayout());

p3.add(new JLabel("蓝:"), BorderLayout.WEST);

p3.add(blueScrollBar, BorderLayout.CENTER);

scrPanel.add(p3);

 

// 用来存放 rbPanel 和 scrPanel 的面板

JPanel top = new JPanel(new BorderLayout());

top.add(rbPanel, BorderLayout.NORTH);

top.add(scrPanel, BorderLayout.CENTER);

 

setLayout(new BorderLayout(0, 20));

tf.setFont(new Font("宋体", Font.PLAIN, 60));

tf.setBackground(Color.WHITE);

tf.setForeground(Color.BLACK);

// 加入top 面板 和 文本框到窗口

add(top, BorderLayout.NORTH);

add(tf, BorderLayout.CENTER);

 

// 为按钮和滚动条增加监听器

foreColorRb.addActionListener(this);

backColorRb.addActionListener(this);

redScrollBar.addAdjustmentListener(this);

greenScrollBar.addAdjustmentListener(this);

blueScrollBar.addAdjustmentListener(this);

 

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setResizable(false);

setSize(600, 400);

setVisible(true);

}

 

public void actionPerformed(ActionEvent e) {

if (e.getSource() == backColorRb) { // 点击的是背景色按钮

Color c = tf.getBackground(); // 得到背景色

redScrollBar.setValue(c.getRed()); // 设置滚动条的值

greenScrollBar.setValue(c.getGreen());

blueScrollBar.setValue(c.getBlue());

} else if (e.getSource() == foreColorRb) {

Color c = tf.getForeground();

redScrollBar.setValue(c.getRed());

greenScrollBar.setValue(c.getGreen());

blueScrollBar.setValue(c.getBlue());

}

}

 

public void adjustmentValueChanged(AdjustmentEvent e) {

// 拖动滚动条,改变文本框前景或背景色

int r = redScrollBar.getValue();

int g = greenScrollBar.getValue();

int b = blueScrollBar.getValue();

 

Color c = new Color(r, g, b);

if (backColorRb.isSelected()) {

tf.setBackground(c);

} else {

tf.setForeground(c);

}

}

 

public static void main(String[] args) {

Exp7_3 t = new Exp7_3();

t.initUI();

}

}

实验四

/*********************************

5.  编写GUI程序模拟Windows的图片查看器。

① 窗口下部区域显示若干图片的缩略图。

② 当图片较多时,显示水平滚动条。

③ 可任意选择缩略图。

④ 选择某个缩略图后,在窗口上部区域显示完整图片。

⑤ 点击前一个(后一个)按钮时,切换到上一张(下一张)图片,若当前选择的是首个(末个)图片时,则前一个(后一个)按钮不可用。

 **********************************/

package ch08;

 

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Cursor;

import java.awt.Image;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import java.io.File;

import java.net.URISyntaxException;

import java.net.URL;

 

import javax.swing.BorderFactory;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

 

public class Exp7_5 extends JFrame {

 

private JPanel[] thumbPanels; // 缩略图面板数组

private JLabel[] thumbLabels; // 缩略图标签数组

private File[] imageFiles; // 图片文件数组

private JScrollPane bottom; // 下部的可滚动面板

private int currentImageId = -1; // 当前查看的图片id

private JLabel fullImageLabel; // 完整图片标签

 

private JButton next; // 下一张按钮

private JButton pre; // 上一张按钮

 

// 获得path路径下所有的图片,并生成面板

private JPanel[] getThumbPanels(String path) throws URISyntaxException {

URL url = super.getClass().getClassLoader().getResource(path);

File dir = new File(url.toURI()); // 图片根目录

imageFiles = dir.listFiles(); // 得到目录下的所有文件

thumbPanels = new JPanel[imageFiles.length];

thumbLabels = new JLabel[imageFiles.length];

 

// 鼠标点击缩略图标签的事件监听器

MouseListener mouseListener = new MouseAdapter() {

public void mouseClicked(MouseEvent e) {

JLabel clickedLabel = (JLabel) (e.getSource());// 得到点击的那个标签

for (int i = 0; i < thumbLabels.length; i++) {// 所有标签边框复位

thumbLabels[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));

if (thumbLabels[i] == clickedLabel) {

currentImageId = i; // 修改当前查看的图片id

}

}

clickedLabel.setBorder(BorderFactory.createLineBorder(Color.RED, 5));// 点击的标签加框

ImageIcon image = new ImageIcon(imageFiles[currentImageId].getAbsolutePath());

// 伸缩图片到上部完整图片标签大小

image.setImage(image.getImage().getScaledInstance(fullImageLabel.getWidth(), fullImageLabel.getHeight(), Image.SCALE_DEFAULT));

fullImageLabel.setIcon(image);

checkButtons();// 更新上一张/下一张按钮的状态

}

 

// 鼠标进入缩略图标签时改变鼠标指针

public void mouseEntered(MouseEvent e) {

JLabel imageLabel = (JLabel) (e.getSource());

imageLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

}

};

 

for (int i = 0; i < imageFiles.length; i++) {

ImageIcon image = new ImageIcon(imageFiles[i].getAbsolutePath());

 

JPanel p = new JPanel(new BorderLayout());

thumbLabels[i] = new JLabel();

// 缩放图片到缩略图标签大小

thumbLabels[i].setIcon(new ImageIcon(image.getImage().getScaledInstance(100, 80, Image.SCALE_DEFAULT)));

thumbLabels[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));

thumbLabels[i].addMouseListener(mouseListener); // 加鼠标事件监听器

 

JLabel textLabel = new JLabel(imageFiles[i].getName()); // 图片下方文字标签

textLabel.setHorizontalAlignment(JLabel.CENTER);

p.add(thumbLabels[i], BorderLayout.CENTER);

p.add(textLabel, BorderLayout.SOUTH);

thumbPanels[i] = p;

}

return thumbPanels;

}

 

void initUI() throws URISyntaxException {

fullImageLabel = new JLabel();

fullImageLabel.setBorder(BorderFactory.createLineBorder(Color.RED));

 

next = new JButton(new ImageIcon(super.getClass().getClassLoader().getResource("ch08/icons/next.png")));

pre = new JButton(new ImageIcon(super.getClass().getClassLoader().getResource("ch08/icons/pre.png")));

 

// 上一张/下一张按钮点击事件的监听器

ActionListener listener = new ActionListener() {

public void actionPerformed(ActionEvent e) {

if (e.getSource() == next) {

currentImageId++;

} else {

currentImageId--;

}

 

// 复位所有缩略图标签的边框

for (int i = 0; i < thumbLabels.length; i++) {

thumbLabels[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));

}

// 选中相应的缩略图标签

thumbLabels[currentImageId].setBorder(BorderFactory.createLineBorder(Color.RED, 5));

// 滚到到该缩略图标签

bottom.getHorizontalScrollBar().setValue(thumbPanels[currentImageId].getLocation().x);

 

// 改变上部的完整图片标签

ImageIcon image = new ImageIcon(imageFiles[currentImageId].getAbsolutePath());

image.setImage(image.getImage().getScaledInstance(fullImageLabel.getWidth(), fullImageLabel.getHeight(), Image.SCALE_DEFAULT));

fullImageLabel.setIcon(image);

checkButtons();

}

};

next.addActionListener(listener);

pre.addActionListener(listener);

 

JPanel buttonsPanel = new JPanel();

buttonsPanel.add(pre);

buttonsPanel.add(next);

 

// 上部面板(包含完整图片标签和2个按钮)

JPanel top = new JPanel(new BorderLayout(0, 10));

top.add(fullImageLabel, BorderLayout.CENTER);

top.add(buttonsPanel, BorderLayout.SOUTH);

top.setSize(705, 410);

top.setLocation(5, 5);

add(top);

 

// 下部缩略图面板

JPanel thumbPanel = new JPanel();

bottom = new JScrollPane(thumbPanel);

JPanel[] thumbPanels = getThumbPanels("ch08/images");

for (int i = 0; i < thumbPanels.length; i++) {

thumbPanel.add(thumbPanels[i]);

}

 

setLayout(null);

bottom.setSize(705, 130);

bottom.setLocation(5, 430);

add(bottom);

 

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setResizable(false);

setSize(720, 600);

setVisible(true);

}

 

private void checkButtons() {

if (currentImageId == 0) { // 第一张

pre.setEnabled(false);

}

if (currentImageId == imageFiles.length - 1) { // 最后一张

next.setEnabled(false);

}

if (currentImageId > 0 && currentImageId < imageFiles.length - 1) {

pre.setEnabled(true);

next.setEnabled(true);

}

}

 

public static void main(String[] args) throws URISyntaxException {

Exp7_5 t = new Exp7_5();

t.initUI();

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

第八章

实验一

/*********************************

1.  点击窗口的关闭按钮时,弹出包含“是”和“否”选项的模态对话框,

点击“是”则关闭窗口,否则不关闭。

 **********************************/

package ch09;

 

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

 

import javax.swing.JFrame;

import javax.swing.JOptionPane;

 

public class Exp8_1 extends JFrame {

 

void initUI() {

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

int b = JOptionPane.showConfirmDialog(Exp8_1.this, "确认要关闭按窗口吗?", "提示", JOptionPane.YES_NO_OPTION);

if (b == JOptionPane.YES_OPTION) {

System.exit(-1);

}

}

});

setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

setResizable(false);

setSize(600, 400);

setVisible(true);

}

 

public static void main(String[] args) {

Exp8_1 t = new Exp8_1();

t.initUI();

}

}

实验二

/*********************************

2.  编写GUI程序模拟IE浏览器,具体要求如下。

① 在窗口顶部有一个可编辑的下拉列表,以输入网址。

② 若输入的网址之前未输入过,则添加到下拉列表中(模拟IE的历史记录)。

③ 输入或选择了一个网址后,在窗口下部的编辑器面板中显示相应网页。

 **********************************/

package ch09;

 

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.IOException;

 

import javax.swing.JComboBox;

import javax.swing.JEditorPane;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

import javax.swing.JScrollPane;

import javax.swing.JTextField;

 

public class Exp8_2 extends JFrame {

String home = "http://www.baidu.com"; // 首页

JComboBox cb = new JComboBox(); // 地址栏

JEditorPane page; // 页面展现面板

 

void initUI() throws IOException {

cb.setEditable(true);

cb.addItem(home);

 

// 输入网址并回车,或选择不同选项时的时间监听器

cb.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

// 获得输入的网址(去掉首尾空格)

String s = ((JTextField) cb.getEditor().getEditorComponent()).getText().trim();

if (s != null && s.length() > 0) {

// 写回地址栏

((JTextField) cb.getEditor().getEditorComponent()).setText(s);

try {

page.setPage(s); // 加载页面

} catch (IOException e1) {

JOptionPane.showMessageDialog(Exp8_2.this, "加载页面出错,请检查输入的地址!");

return;

}

int count = cb.getItemCount(); // 得到所有下拉列表选项

boolean exist = false; // 判断输入的地址是否已存在

for (int i = 0; i < count; i++) {

Object item = cb.getItemAt(i);

if (item.toString().equalsIgnoreCase(s)) {

exist = true;

break;

}

}

if (!exist) { // 不存在加入下拉列表

cb.addItem(s);

}

}

}

});

 

setLayout(new BorderLayout());

add(cb, BorderLayout.NORTH);

 

page = new JEditorPane(home);

page.setEditable(false);

add(new JScrollPane(page), BorderLayout.CENTER);

 

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setSize(600, 400);

setVisible(true);

}

 

public static void main(String[] args) throws IOException {

Exp8_2 t = new Exp8_2();

t.initUI();

}

}

实验三

/*********************************

3.  编写手机库存管理界面,具体要求如下。

① 表格(中间3列)的初始数据存于二维数组中,其中单价和总价列为Float类型,数量列为Integer类型。

② 编号列从1开始递增,总价列为计算列(即根据单价和数量求得)。

③ 根据输入的商品名称,以某种背景色高亮显示所有包含该名称的行。

④ 点击删除按钮,在表格中删除选中的行(若未有选中行,则该按钮不可用),并保证编号列的递增。

⑤ 点击增加按钮,在表格最后新增一行以输入数据(当焦点离开该行的商品名称列时,需检查输入的名称是否与其他商品名称重复)。

 **********************************/

package ch09;

 

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Component;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.BorderFactory;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JTable;

import javax.swing.JTextField;

import javax.swing.ListSelectionModel;

import javax.swing.event.ListSelectionEvent;

import javax.swing.event.ListSelectionListener;

import javax.swing.table.AbstractTableModel;

import javax.swing.table.DefaultTableCellRenderer;

import javax.swing.table.TableColumnModel;

 

// 表格模型类

class MobilePhoneTableModel extends AbstractTableModel {

String[] columnNames; // 列名称

Class<?>[] columnTypes; // 列类型

Object[][] data; // 行数据

 

// 构造方法

public MobilePhoneTableModel(String[] columnNames, Class<?>[] columnTypes, Object[][] data) {

this.columnNames = columnNames;

this.columnTypes = columnTypes;

this.data = data;

}

 

// data 字段的读写方法

public Object[][] getData() {

return data;

}

 

public void setData(Object[][] data) {

this.data = data;

}

 

/*** 以下是重写父类的方法(AbstractTableModel实现了TableModel接口) ***/

public int getRowCount() {// 得到表格总行数

return data.length;

}

 

public int getColumnCount() {// 得到表格总列数

return columnNames.length;

}

 

public String getColumnName(int col) {// 得到指定列的名称

return columnNames[col];

}

 

public Class<?> getColumnClass(int col) {// 得到指定列的类型

return columnTypes[col];

}

 

public Object getValueAt(int row, int col) {// 得到指定行列的数据

if (col == 0) { // 行号列

return row + 1;

} else if (col == 4) { // 总价列

return (Float) data[row][1] * (Integer) data[row][2];

}

return data[row][col - 1]; // 其余列

}

 

public boolean isCellEditable(int row, int col) {// 设置指定行列是否可编辑

return col != 0 && col != 4; // 行号和总价列不允许修改

}

 

// 编辑表格单元时触发此方法

public void setValueAt(Object value, int row, int col) {

if (col == 1) { // 名称列

value = ((String) value).trim(); // 名称去掉首尾空格

if (((String) value).length() < 1) {

JOptionPane.showMessageDialog(JFrame.getFrames()[0], "商品名称不能为空!", "提示", JOptionPane.WARNING_MESSAGE);

return;

}

// 检查是否与其他名称相同

for (int i = 0; i < getRowCount(); i++) {

if (i == row) { // 不与自己比较

continue;

}

String name = (String) getValueAt(i, 1);

if (((String) value).equalsIgnoreCase(name)) {

JOptionPane.showMessageDialog(JFrame.getFrames()[0], "商品名称已存在!", "提示", JOptionPane.WARNING_MESSAGE);

return;

}

}

}

// 检查通过,修改相应数据

data[row][col - 1] = value;

fireTableDataChanged();// 通知表格更新

fireTableCellUpdated(row, col);

}

}

 

// 表格渲染器类

class MobilePhoneTableRenderer extends DefaultTableCellRenderer {

private int[] rowSelected; // 标记每一行是否被选择

 

// get和set方法

public int[] getRowSelected() {

return rowSelected;

}

 

public void setRowSelected(int[] rowSelected) {

this.rowSelected = rowSelected;

}

 

// 渲染每个单元格时都会执行此方法

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

if (rowSelected[row] == 0) { // 未选中的行

setBackground(Color.WHITE);

} else {

setBackground(Color.LIGHT_GRAY);

}

return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

}

}

 

public class Exp8_3 extends JFrame {

String[] columnNames = { "编号", "商品名称", "单价", "数量", "总价" };

Class<?>[] columnTypes = { Integer.class, String.class, Float.class, Integer.class, Float.class };

Object[][] data = { { "iPhone 5", 5000F, 15 }, { "HTC One X", 4600F, 23 }, { "Galaxy S III", 4300F, 4 }, { "小米2", 2400F, 30 }, { "HTC G12", 2100F, 3 } };

 

JTable table;

MobilePhoneTableRenderer renderer;

 

JTextField tf = new JTextField(30);

JButton searchBtn = new JButton("查找");

JButton deleteBtn = new JButton("删除");

JButton addBtn = new JButton("增加");

 

void initUI() {

final MobilePhoneTableModel model = new MobilePhoneTableModel(columnNames, columnTypes, data);

renderer = new MobilePhoneTableRenderer();

renderer.setRowSelected(new int[model.getRowCount()]);

 

table = new JTable(model);

table.setBorder(BorderFactory.createEtchedBorder());

table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 只允许单选

// 选中表格行时

table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {

if (e.getFirstIndex() >= 0) {

deleteBtn.setEnabled(true); // 启用删除按钮

}

}

});

 

TableColumnModel colModel = table.getColumnModel();

for (int i = 0; i < colModel.getColumnCount(); i++) { // 为表格设置渲染器

colModel.getColumn(i).setCellRenderer(renderer);

}

 

JPanel top = new JPanel(new FlowLayout(FlowLayout.LEADING));

top.add(new JLabel("名称:"));

top.add(tf);

top.add(searchBtn);

searchBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

// 根据名称查找所有行

String name = tf.getText();

if (name != null && name.length() > 0) {

name = name.trim();

tf.setText(name);

int rows = table.getRowCount();

int[] rowSelected = new int[rows];

for (int i = 0; i < rows; i++) {

String _name = (String) table.getValueAt(i, 1);

if (_name.toUpperCase().contains(name.toUpperCase())) {

rowSelected[i] = 1;

} else {

rowSelected[i] = 0;

}

}

renderer.setRowSelected(rowSelected);

table.updateUI();// 更新表格

}

}

});

 

JPanel center = new JPanel(new BorderLayout());

center.add(table, BorderLayout.CENTER);

 

JPanel bottom = new JPanel(new FlowLayout(FlowLayout.TRAILING));

deleteBtn.setEnabled(false);

bottom.add(deleteBtn);

bottom.add(addBtn);

 

deleteBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

int i = table.getSelectedRow();

Object[][] old_data = model.getData();

// 新的数据行(除去旧数据的选中行)

Object[][] new_data = new Object[old_data.length - 1][];

int k = 0;

for (int j = 0; j < old_data.length; j++) {

if (j != i) {

new_data[k++] = old_data[j];

}

}

model.setData(new_data);

renderer.setRowSelected(new int[new_data.length]);

model.fireTableDataChanged();

table.clearSelection();

deleteBtn.setEnabled(false);

}

});

 

addBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

Object[][] old_data = model.getData();

// 新的数据行(末尾增加一行)

Object[][] new_data = new Object[old_data.length + 1][];

int k = 0;

for (int j = 0; j < old_data.length; j++) {

new_data[k++] = old_data[j];

}

new_data[k] = new Object[3]; // 增加的行

new_data[k][0] = "";

new_data[k][1] = 0F;

new_data[k][2] = 0;

model.setData(new_data);

renderer.setRowSelected(new int[new_data.length]);

model.fireTableDataChanged();

table.clearSelection();

}

});

 

setLayout(new BorderLayout());

add(top, BorderLayout.NORTH);

add(center, BorderLayout.CENTER);

add(bottom, BorderLayout.SOUTH);

 

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setResizable(false);

setSize(600, 400);

setTitle("手机库存");

setVisible(true);

}

 

public static void main(String[] args) {

Exp8_3 t = new Exp8_3();

t.initUI();

}

}

实验四

/*********************************

5.  编写GUI程序模拟Photoshop的图片多开功能,具体要求如下。

① 程序运行时,首先弹出文件打开对话框。

② 对话框指定了文件类型过滤器,只列出扩展名为jpg、bmp、png的图片文件。

③ 在对话框中选择了多个文件并确定后,在窗口中显示相同个数的内部窗口,且每个内部窗口显示一个图片。

④ 鼠标停留在图片上时,弹出以文件名为内容的工具提示。

 **********************************/

package ch09;

 

import java.awt.Image;

import java.io.File;

import java.io.IOException;

 

import javax.swing.ImageIcon;

import javax.swing.JDesktopPane;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JInternalFrame;

import javax.swing.JLabel;

import javax.swing.filechooser.FileFilter;

import javax.swing.filechooser.FileNameExtensionFilter;

 

public class Exp8_5 extends JFrame {

 

void initUI() throws IOException {

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setSize(800, 600);

setVisible(true);

}

 

// 选择图片文件

File[] selectFiles() {

JFileChooser fc = new JFileChooser();

FileFilter filter = new FileNameExtensionFilter("图片文件", "bmp", "jpg", "png", "gif");

fc.setFileFilter(filter);// 设置文件过滤器

fc.setFileHidingEnabled(false);// 显示隐藏文件

fc.setMultiSelectionEnabled(true);// 允许多选

fc.setDialogTitle("请选择图片(可多选)");// 设置对话框标题栏文字

if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {

return fc.getSelectedFiles();

}

return null;

}

 

// 打开图片文件并显示在内部窗口中

void openFiles(File[] files) {

if (files != null && files.length > 0) {

int i = 0;

// 内部窗口所在容器

JDesktopPane desktop = new JDesktopPane();

add(desktop);// 加入顶层窗口

 

for (File file : files) {

final JInternalFrame jif = new JInternalFrame(file.getName());

ImageIcon pic = new ImageIcon(file.getAbsolutePath());

// 缩放图片到指定大小

pic.setImage(pic.getImage().getScaledInstance(320, 240, Image.SCALE_DEFAULT));

JLabel label = new JLabel(pic);

jif.add(label);

jif.setLocation(i * 30, i * 30);

jif.setSize(400, 300);

jif.setResizable(true);

jif.setMaximizable(true);

jif.setIconifiable(true);

jif.setClosable(true);

jif.setToolTipText(file.getName());

desktop.add(jif); // 加入容器

jif.setVisible(true);

i++;

}

}

}

 

public static void main(String[] args) throws IOException {

Exp8_5 t = new Exp8_5();

t.initUI();

t.openFiles(t.selectFiles());

}

}


相关评论
网站客服QQ:1002732220 手机号:18710392703  陕ICP备18017874号

      <kbd id='IQ2QSp5tQ'></kbd><address id='IQ2QSp5tQ'><style id='IQ2QSp5tQ'></style></address><button id='IQ2QSp5tQ'></button>

              <kbd id='IQ2QSp5tQ'></kbd><address id='IQ2QSp5tQ'><style id='IQ2QSp5tQ'></style></address><button id='IQ2QSp5tQ'></button>