资源描述
1.1 利用Java实现地球系动画完整实现实例(第8部分)
1.1.1 在界面中“画图”——拖放地球和月亮
1、需要补充的知识
(1)Java中的事件编程
(2)MouseListener接口中的各个方法所代表的事件
public void mousePressed(MouseEvent e);// 鼠标按键在组件上单击(按下并释放)时调用。
public void mouseReleased(MouseEvent e); //鼠标按钮在组件上释放时调用。
public void mouseClicked(MouseEvent e);// 鼠标按键在组件上按下时调用。
public void mouseEntered(MouseEvent e);// 鼠标进入到组件上时调用。
public void mouseExited(MouseEvent e);// 鼠标离开组件时调用。
特别是mousePressed和mouseReleased方法的编程
2、EarthPlanetApplet程序
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Rectangle;
import java.awt.Toolkit;
import .URL;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JApplet;
public class EarthPlanetApplet extends JApplet implements Runnable,MouseMotionListener,MouseListener{
private Thread earthMultiThread = null;
private Thread moonMultiThread = null;
private Graphics guiGraphics;
private Image allImagesArray[];
private int currentImageIndex=0;
private int imageWidth = 0;
private int imageHeight = 0;
private boolean allImagesLoaded = false;
private final int NUMBER_IMAGES = 18;
private boolean isRunedByApplication = false;
int currentRotatingAngle=0;
int earthCenterX0,earthCenterY0;
int circleRadius=100;
int currentRotatingCount=0;
public static void main(String[] args) {
EarthPlanetFrame applicationJFrame=null;
applicationJFrame=new EarthPlanetFrame("利用Java实现的地球系动画");
EarthPlanetApplet threadApplet=null;
threadApplet=new EarthPlanetApplet();
applicationJFrame.getContentPane().add("Center", threadApplet);
threadApplet.isRunedByApplication = true;
threadApplet.init();
threadApplet.start();
applicationJFrame.setVisible(true);
}
public EarthPlanetApplet(){
this.addMouseMotionListener(this);
this.addMouseListener(this);
}
public void start(){
if (earthMultiThread == null){
earthMultiThread = new Thread(this);
earthMultiThread.start();
}
if (moonMultiThread == null){
moonMultiThread = new Thread(this);
moonMultiThread.start();
}
}
public void stop(){
if (earthMultiThread != null){
earthMultiThread.stop();
earthMultiThread = null;
}
if (moonMultiThread != null){
moonMultiThread.stop();
moonMultiThread = null;
}
}
public void loadAllEarthImage(){
guiGraphics = getGraphics();
allImagesArray = new Image[NUMBER_IMAGES];
MediaTracker tracker = new MediaTracker(this);
String strImage;
for (int currentIndex = 1; currentIndex <= NUMBER_IMAGES;
currentIndex++){
strImage = "/images/img00" + ((currentIndex < 10) ? "0" : "")
+ currentIndex + ".gif";
URL oneImageURL=getClass().getResource(strImage);
if (isRunedByApplication){
allImagesArray[currentIndex-1] =
Toolkit.getDefaultToolkit().getImage(oneImageURL);
}
else{
allImagesArray[currentIndex-1] = getImage(oneImageURL);
}
tracker.addImage(allImagesArray[currentIndex-1], 0);
}
try {
tracker.waitForAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
allImagesLoaded = !tracker.isErrorAny();
if (!allImagesLoaded){
stop();
guiGraphics.drawString("图像加载错误,可能是没有找到文件!", 10, 40);
return;
}
imageWidth = allImagesArray[0].getWidth(this);
imageHeight = allImagesArray[0].getHeight(this);
earthCenterX0=(getSize().width - imageWidth) / 2;
earthCenterY0=(getSize().height - imageHeight) / 2;
}//在这里初始化
public void run(){
if (!allImagesLoaded){
loadAllEarthImage();
}
repaint();
while (true){
try{
displayImage(guiGraphics);
currentImageIndex++;
if (currentImageIndex == NUMBER_IMAGES)
currentImageIndex = 0;
if(Thread.currentThread()==earthMultiThread){
Thread.sleep(50);
}
else{
Thread.sleep(500);
}
}
catch (InterruptedException e){
stop();
}
}
}
private void displayImage(Graphics g){
if (!allImagesLoaded)
return;
// earthCenterX0=(getSize().width - imageWidth) / 2;
// earthCenterY0=(getSize().height - imageHeight) / 2;
if(Thread.currentThread()==earthMultiThread){
g.drawImage(allImagesArray[currentImageIndex],
earthCenterX0,earthCenterY0, null);
}
else{
g.clearRect((int)(earthCenterX0+circleRadius* Math.cos((currentRotatingAngle-1)*Math.PI/180)),
(int)(earthCenterY0+ circleRadius* Math.sin((currentRotatingAngle-1)*Math.PI/180)),
imageWidth,imageHeight);
g.drawImage(allImagesArray[currentImageIndex],
(int)(earthCenterX0+circleRadius* Math.cos(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterY0+ circleRadius* Math.sin(currentRotatingAngle*Math.PI/180)),
imageWidth/2,imageHeight/2,
null); //注意调整下面的XY坐标,否则轨迹会被覆盖
g.drawLine((int)(earthCenterX0+(circleRadius-10)* Math.cos(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterY0+ (circleRadius-10)* Math.sin(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterX0+(circleRadius-10)* Math.cos(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterY0+ (circleRadius-10)* Math.sin(currentRotatingAngle*Math.PI/180)));
currentRotatingAngle++;
if (currentRotatingAngle>360){
currentRotatingAngle=0;
currentRotatingCount++;
}
g.drawString("转动"+currentRotatingCount+"次",25,313);
g.fillRect(25,300-currentRotatingCount*30,40, currentRotatingCount*30);
}
}
public void paint(Graphics g){
if (allImagesLoaded){
Rectangle r = g.getClipBounds();
g.clearRect(r.x, r.y, r.width, r.height);
displayImage(g);
Color redColor=new Color(255,0,0); //红色
g.setColor(redColor);
Font someOneFont=new Font("Dialog",Font.BOLD,40);
g.setFont(someOneFont);
g.drawString("利用Java实现的地球系动画",100,100);
drawAxisLines(g);
}
else
g.drawString("正在加载图像,请等待...", 10, 20);
}
private void drawAxisLines(Graphics g){
g.drawLine(20,300,300,300); //画出X坐标轴
g.drawLine(20,300,20,20); //画出Y坐标轴
g.drawLine(20,270,15,270);
//画出Y坐标轴上的数据的各个刻度线,共5条
g.drawLine(20,240,15,240);
g.drawLine(20,210,15,210);
g.drawLine(20,180,15,180);
g.drawLine(20,150,15,150);
g.drawLine(20,120,15,120);
g.drawLine(20,90,15,90);
g.drawLine(20,60,15,60);
}
public void mouseDragged(MouseEvent e){
getGraphics().drawLine(e.getX(),e.getY(),e.getX(),e.getY());
repaint();
earthCenterX0=e.getX(); //改变球的图像位置为鼠标拖放的位置
earthCenterY0=e.getY();
}
public void mouseMoved(MouseEvent e){
}
public void mouseClicked(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mousePressed(MouseEvent e){ //拖动过程中终止旋转
stop();
}
public void mouseReleased(MouseEvent e){ //松开鼠标后,复位图像的位置
earthCenterX0=(getSize().width - imageWidth) / 2;
earthCenterY0=(getSize().height - imageHeight) / 2;
repaint();
start();
}
}
注意mouseDragged方法所对应的事件为“鼠标拖放”
3、Applet程序方式执行
4、应用程序方式执行
作业:实现如下功能
当鼠标在程序的窗口区域时,将鼠标光标改变为“手形”。离开时再恢复为原始的形状。
Cursor oldCursor=null;
public void mouseEntered(MouseEvent e) {
oldCursor=this.getCursor();
this.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent e) {
this.setCursor(oldCursor);
}
1.1.2 添加用户界面组件,实现人机交互——添加两个按钮、并控制线程
1、需要补充的知识
(1)Java Swing(摇摆、摆动、摇荡)
Swing是一个用于开发Java应用程序用户界面的开发工具包。它以抽象窗口工具包(AWT)为基础使跨平台应用程序可以使用任何可插拔的外观风格。工具包中所有的包都是以swing作为名称,例如javax.swing,javax.swing.event等。
Swing的产生主要原因就是AWT不能满足图形化用户界面发展的需要。AWT设计的初衷是支持开发小应用程序的简单用户界面。例如AWT缺少剪贴板、打印支持、键盘导航等特性,而且原来的AWT甚至不包括弹出式菜单或滚动窗格等基本元素。
(2)Java中的Swing 基本组件的编程
1) 容器组件:顶层容器(窗体JFrame、对话框JDialog、JApplet)和非顶层容器(面板JPanel)
2) 基本组件:具有一定功能、但不担当容器的组件。这类组件非常多,如标签(JLabel)、按钮(JButton)、文本框(JTextField)、文本域(JTextArea)等。
(3)ActionListener接口中的各个方法所代表的事件
特别是actionPerformed方法的编程
(4)Swing中的GUI布局——JApplet新特性
不可以把组件直接添加到JApplet容器中,JApplet容器也含有一个称为内容面板的容器,应当把组件添加到内容面板中。
不能为JApplet容器设置布局,而应当为JApplet容器的内容面板设置布局。内容面板的默认布局是BorderLayout布局。JApplet容器通过调用方法:getContentPane(),得到内容面板。
2、Matisse4MyEclipse
Matisse是NetBeans中新一代的UI设计工具,Matisse将是一个支持Swing显示布局的工具。Matisse4MyEclipse即Matisse for MyEclipse。
3、JButton
(1)按钮大概是使用最为普遍的用户界面组件
按钮通常带有某种边框,且可以被鼠标或快捷键激活。能够激活它们来完成某个功能,而且很多其他Swing组件都是AbstractButton类的扩展,而AbstractButton类是Swing按钮的基类。
(2)JButton共有4个构造函数
1) JButton():建立一个按钮。
2) JButton(Icon icon):建立一个有图像的按钮。
3) JButton(String icon):建立一个有文字的按钮。
4) JButton(String text,Icon icon):建立一个有图像与文字的按钮。
(3)按钮中增加HTML样式
import javax.swing.JButton;
import javax.swing.JFrame;
public class HTMLButton {
public static void main(String args[]) {
JFrame frame = new JFrame("DefaultButton");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String htmlTag = "<html><font color='#FF0000'><B>确定</B></font></html>";
JButton htmlButton = new JButton(htmlTag);
frame.add(htmlButton);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
4、EarthPlanetApplet程序
Applet的GUI可以在init()方法中构造和显示,在init()方法中构造GUI是安全的,只要不对Applet中的对象调用show()或setVisible(true)方法。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Rectangle;
import java.awt.Toolkit;
import .URL;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;
public class EarthPlanetApplet extends JApplet implements Runnable,MouseMotionListener,MouseListener,ActionListener{
private Thread earthMultiThread = null;
private Thread moonMultiThread = null;
private Graphics guiGraphics;
private Image allImagesArray[];
private int currentImageIndex=0;
private int imageWidth = 0;
private int imageHeight = 0;
private boolean allImagesLoaded = false;
private final int NUMBER_IMAGES = 18;
private boolean isRunedByApplication = false;
int currentRotatingAngle=0;
int earthCenterX0,earthCenterY0;
int circleRadius=100;
int currentRotatingCount=0;
JButton playButton,stopButton;
public static void main(String[] args) {
EarthPlanetFrame applicationJFrame=null;
applicationJFrame=new EarthPlanetFrame("利用Java实现的地球系动画");
EarthPlanetApplet threadApplet=null;
threadApplet=new EarthPlanetApplet();
applicationJFrame.getContentPane().add("Center", threadApplet);
threadApplet.isRunedByApplication = true;
threadApplet.init();
threadApplet.start();
applicationJFrame.setVisible(true);
}
public EarthPlanetApplet(){
this.addMouseMotionListener(this);
this.addMouseListener(this);
}
public void init(){
JPanel buttonPanel=new JPanel();
playButton=new JButton("Play");
playButton.addActionListener(this);
stopButton=new JButton("Stop");
stopButton.addActionListener(this);
buttonPanel.add(playButton);
buttonPanel.add(stopButton);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(buttonPanel,BorderLayout.NORTH);
}
public void start(){
if (earthMultiThread == null){
earthMultiThread = new Thread(this);
earthMultiThread.start();
}
if (moonMultiThread == null){
moonMultiThread = new Thread(this);
moonMultiThread.start();
}
}
public void stop(){
if (earthMultiThread != null){
earthMultiThread.stop();
earthMultiThread = null;
}
if (moonMultiThread != null){
moonMultiThread.stop();
moonMultiThread = null;
}
}
public void loadAllEarthImage(){
guiGraphics = getGraphics();
allImagesArray = new Image[NUMBER_IMAGES];
MediaTracker tracker = new MediaTracker(this);
String strImage;
for (int currentIndex = 1; currentIndex <= NUMBER_IMAGES;
currentIndex++){
strImage = "/images/img00" + ((currentIndex < 10) ? "0" : "")
+ currentIndex + ".gif";
URL oneImageURL=getClass().getResource(strImage);
if (isRunedByApplication){
allImagesArray[currentIndex-1] =
Toolkit.getDefaultToolkit().getImage(oneImageURL);
}
else{
allImagesArray[currentIndex-1] = getImage(oneImageURL);
}
tracker.addImage(allImagesArray[currentIndex-1], 0);
}
try {
tracker.waitForAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
allImagesLoaded = !tracker.isErrorAny();
if (!allImagesLoaded){
stop();
guiGraphics.drawString("图像加载错误,可能是没有找到文件!", 10, 40);
return;
}
imageWidth = allImagesArray[0].getWidth(this);
imageHeight = allImagesArray[0].getHeight(this);
earthCenterX0=(getSize().width - imageWidth) / 2;
earthCenterY0=(getSize().height - imageHeight) / 2;
}
public void run(){
if (!allImagesLoaded){
loadAllEarthImage();
}
repaint();
while (true){
try{
displayImage(guiGraphics);
currentImageIndex++;
if (currentImageIndex == NUMBER_IMAGES)
currentImageIndex = 0;
if(Thread.currentThread()==earthMultiThread){
Thread.sleep(50);
}
else{
Thread.sleep(500);
}
}
catch (InterruptedException e){
stop();
}
}
}
private void displayImage(Graphics g){
if (!allImagesLoaded)
return;
// earthCenterX0=(getSize().width - imageWidth) / 2;
// earthCenterY0=(getSize().height - imageHeight) / 2;
if(Thread.currentThread()==earthMultiThread){
g.drawImage(allImagesArray[currentImageIndex],
earthCenterX0,earthCenterY0, null);
}
else{
g.clearRect((int)(earthCenterX0+circleRadius* Math.cos((currentRotatingAngle-1)*Math.PI/180)),
(int)(earthCenterY0+ circleRadius* Math.sin((currentRotatingAngle-1)*Math.PI/180)),
imageWidth,imageHeight);
g.drawImage(allImagesArray[currentImageIndex],
(int)(earthCenterX0+circleRadius* Math.cos(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterY0+ circleRadius* Math.sin(currentRotatingAngle*Math.PI/180)),
imageWidth/2,imageHeight/2,
null); //注意调整下面的XY坐标,否则轨迹会被覆盖
g.drawLine((int)(earthCenterX0+(circleRadius-10)* Math.cos(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterY0+ (circleRadius-10)* Math.sin(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterX0+(circleRadius-10)* Math.cos(currentRotatingAngle*Math.PI/180)),
(int)(earthCenterY0+ (circleRadius-10)* Math.sin(currentRotatingAngle*Math.PI/180)));
currentRotatingAngle++;
if (currentRotatingAngle>360){
currentRotatingAngle=0;
currentRotatingCount++;
}
g.drawString("转动"+currentRotatingCount+"次",25,313)
展开阅读全文