一、Java圖形用戶界面(gui)介紹
1灭红、Java GUI簡介
??圖形用戶界面(Graphics User Interface口注,GUI)是用戶與程序交互的窗口寝志,比命令行的界面更加直觀并且更好操作。
??Sun已經(jīng)提供了一個(gè)跨平臺(tái)GUI開發(fā)工具包AWT抽象窗口工具箱(Abstract Window Toolkit)毫缆。
??Sun又創(chuàng)建了一個(gè)新的GUI框架swing悔醋。解決了AWT存在的Icd問題兽叮。
??IBM認(rèn)為swing比較消耗內(nèi)存,創(chuàng)建了一個(gè)新的GUI庫账阻,這就是SWT泽本。
??IBM為了方便開發(fā)SWT程序,在SWT基礎(chǔ)上又創(chuàng)建了一個(gè)更易用规丽,功能強(qiáng)大的圖開包"JFace"。
??AWT(Abstract Window Toolkit):抽象窗口工具包冰抢,早期編寫圖形界面應(yīng)用程序的包挎扰。 AWT的圖形函數(shù)與操作系統(tǒng)提供的圖形函數(shù)有著一一對(duì)應(yīng)的關(guān)系。也就是說遵倦,當(dāng)我們利用 AWT構(gòu)件圖形用戶界面的時(shí)候,實(shí)際上是在利用操作系統(tǒng)的圖形庫似谁。
????????AWT的層次關(guān)系
??Swing:為解決 AWT 存在的問題而新開發(fā)的圖形界面包棘脐。Swing是對(duì)AWT的改良和擴(kuò)展龙致。 不僅提供了AWT 的所有功能目代,還用純粹的Java代碼對(duì)AWT的功能進(jìn)行了大幅度的擴(kuò)充榛了,與平臺(tái)無關(guān)煞抬。
????????Swing組件層次關(guān)系
2革答、AWT和Swing的區(qū)別與聯(lián)系
??AWT和Swing都是java中的包。
??AWT(Abstract Window Toolkit):抽象窗口工具包途茫,早期編寫圖形界面應(yīng)用程序的包溪食。
??Swing:為解決 AWT 存在的問題而新開發(fā)的圖形界面包。Swing是對(duì)AWT的改良和擴(kuò)展栅组。
??AWT和Swing的實(shí)現(xiàn)原理不同:
??AWT的圖形函數(shù)與操作系統(tǒng)提供的圖形函數(shù)有著一一對(duì)應(yīng)的關(guān)系玉掸。也就是說登疗,當(dāng)我們利用 AWT構(gòu)件圖形用戶界面的時(shí)候嫌蚤,實(shí)際上是在利用操作系統(tǒng)的圖形庫脱吱。
??不同的操作系統(tǒng)其圖形庫的功能可能不一樣箱蝠,在一個(gè)平臺(tái)上存在的功能在另外一個(gè)平臺(tái)上則可能不存在垦垂。為了實(shí)現(xiàn)Java語言所宣稱的"一次編譯,到處運(yùn)行"的概念间校,AWT不得不通過犧牲功能來實(shí)現(xiàn)平臺(tái)無關(guān)性页慷。因此,AWT 的圖形功能是各操作系統(tǒng)圖形功能的“交集”滓彰。
??因?yàn)锳WT是依靠本地方法來實(shí)現(xiàn)功能的揭绑,所以AWT控件稱為“重量級(jí)控件”郎哭。
??而Swing,不僅提供了AWT 的所有功能诚纸,還用純粹的Java代碼對(duì)AWT的功能進(jìn)行了大幅度的擴(kuò)充畦徘。例如:并不是所有的操作系統(tǒng)都提供了對(duì)樹形控件的支持抬闯,Swing則利用了AWT中所提供的基本作圖方法模擬了一個(gè)樹形控件。
??由于 Swing是用純粹的Java代碼來實(shí)現(xiàn)的杯缺,因此Swing控件在各平臺(tái)通用睡榆。因?yàn)镾wing不使用本地方法,故Swing控件稱為“輕量級(jí)控件”包雀。
??AWT和Swing之間的區(qū)別:
??1)才写、AWT 是基于本地方法的C/C++程序奖蔓,其運(yùn)行速度比較快;Swing是基于AWT的Java程序厨疙,其運(yùn)行速度比較慢疑务。
??2)暑始、AWT的控件在不同的平臺(tái)可能表現(xiàn)不同廊镜,而Swing在所有平臺(tái)表現(xiàn)一致唉俗。
??在實(shí)際應(yīng)用中,應(yīng)該使用AWT還是Swing取決于應(yīng)用程序所部署的平臺(tái)類型雹姊。例如:
??1)吱雏、對(duì)于一個(gè)嵌入式應(yīng)用瘾境,目標(biāo)平臺(tái)的硬件資源往往非常有限,而應(yīng)用程序的運(yùn)行速度又是項(xiàng)目中至關(guān)重要的因素犬绒。在這種矛盾的情況下兑凿,簡單而高效的AWT當(dāng)然成了嵌入式Java的第一選擇。
??2)咐鹤、在普通的基于PC或者是工作站的標(biāo)準(zhǔn)Java應(yīng)用中,硬件資源對(duì)應(yīng)用程序所造成的限制往往不是項(xiàng)目中的關(guān)鍵因素聘殖。所以在標(biāo)準(zhǔn)版的Java中則提倡使用Swing行瑞,也就是通過犧牲速度來實(shí)現(xiàn)應(yīng)用程序的功能突照。
??在java中讹蘑,AWT包的名稱是java.awt筑舅,Swing包的名稱是javax.swing。
二版仔、Swing的基本使用
1误墓、幾個(gè)常用的組件
??1谜慌、文本框(JTextField)
??2、密碼框(JPasswordField)
??3变泄、標(biāo)簽(JLable)
??4恼琼、復(fù)選框組件(JCheckBox)
??5、單選框組件(JRadioButton):同一組單選按鈕必須先創(chuàng)建ButtonGroup滑燃,然后把單選框組件放入到ButtonGroup中表窘。
??6、下拉框(JComboBox)
??7瘤袖、列表框(JList)
??8昂验、滾動(dòng)窗格(JScrollPane)
??9既琴、列表框(JList)和滾動(dòng)窗格(JScrollPane)一般會(huì)一起使用。
??10逆济、拆分窗格(JSpitPane):屬于容器類組件磺箕。
??11、JTextArea:多行文本框简僧。
??12岛马、JTabbedPane:選項(xiàng)卡窗格(業(yè)簽組件)阅茶。
??13脸哀、JMenuBar:菜單條組件
??14扭吁、JMenu:菜單組件
??15、JMenuItem:菜單項(xiàng)組件
??16蝌诡、JToolBar:容器類組件
2枫吧、Java布局管理
??Java為我們提供了幾個(gè)常用的布局管理器類九杂,例如:FlowLayout宣蠕、BorderLayout抢蚀、GridLayout镰禾、GridBagLayout等。
??1屋休、java.awt FlowLayout(流布局) 將組件按從左到右而后從上到下的順序依次排列博投,一行不能放完則折到下一行繼續(xù)放置盯蝴。流式布局可以以左對(duì)齊、居中對(duì)齊虑绵、右對(duì)齊的方式排列組件闽烙。
??流式布局不限制他所管理的組件的大小黑竞,允許他們有最佳的大小。當(dāng)容器最縮放時(shí)扎酷,組件的位置可以改變遏匆,但組件的大小不改變。JPanel的默認(rèn)布局為流式布局管理凡纳。
??2荐糜、java.awt BorderLayout(邊界布局) 將組件按東、南丛版、西偏序、北、中五個(gè)區(qū)域放置豫缨,每個(gè)方向最多只能放置一個(gè)組件端朵。
??JFrame窗體冲呢,JDialog對(duì)話框組件默認(rèn)布局方法為邊界布局(BorderLayout),邊界布局的五個(gè)部分不是都要添加邻薯,中間部分會(huì)自動(dòng)調(diào)節(jié)大小乘凸。
??3营勤、java.awt GridLayout(網(wǎng)格布局) 形似一個(gè)無框線的表格,每個(gè)單元格中放一個(gè)組件寿羞。將容器分割成多行多列赂蠢,組件被填充到每個(gè)網(wǎng)格中,添加到容器中的組件首先放置在左上角的網(wǎng)格中霞幅,然后從左到右放置其他組件量瓜,當(dāng)占滿該行的所有網(wǎng)格后绍傲,接著繼續(xù)在下一行從左到右放置組件。
??組件的相對(duì)位置不隨容器的縮放而改變猎塞,但大小會(huì)改變荠耽,所有組件的大小相同比藻。
??可以通過GridLayout(int rows, int cols, int hgap, int vgap)來指定網(wǎng)格的行/列,水平間隙/垂直間隙慢叨。
??java.awt GridBagLayout 非常靈活务蝠,可指定組件放置的具體位置及占用單元格數(shù)目。
??4轩拨、一個(gè)界面只可以有一個(gè)JFrame窗體組件气嫁,但可以有多個(gè)Jpanel面板組件够坐,而JPanel上也可使用各種布局管理器,這樣可以組合使用達(dá)到較為復(fù)雜的布局效果梯影。
??JPanel是JComponent的子類庶香。默認(rèn)布局為流式布局(FlowLayout),屬于容器類組件感猛,可以加入別的組件陪白。
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MultiLayout extends JFrame {
private static final long serialVersionUID = 1L;
// 定義組件
JPanel jp1, jp2;
JButton jb1, jb2, jb3, jb4, jb5, jb6;
public static void main(String[] args) {
new MultiLayout();
}
public MultiLayout() {
// 創(chuàng)建組件
// JPanel布局默認(rèn)是FlowLayout流布局
jp1 = new JPanel();
jp2 = new JPanel();
jb1 = new JButton("西瓜");
jb2 = new JButton("蘋果");
jb3 = new JButton("荔枝");
jb4 = new JButton("葡萄");
jb5 = new JButton("桔子");
jb6 = new JButton("香蕉");
// 設(shè)置布局管理器(Jpanel默認(rèn)流布局)
jp1.add(jb1);
jp1.add(jb2);
jp2.add(jb3);
jp2.add(jb4);
jp2.add(jb5);
// 把Panel加入JFrame
this.add(jp1, BorderLayout.NORTH);
this.add(jb6, BorderLayout.CENTER);
this.add(jp2, BorderLayout.SOUTH);
// 設(shè)置窗體
// 窗體大小
this.setSize(300, 250);
// 屏幕顯示初始位置
this.setLocation(200, 200);
// 顯示
this.setVisible(true);
// 退出窗體后將JFrame同時(shí)關(guān)閉
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
??5咱士、 GroupLayout(分組布局) ,它將組件按層次分組序厉,以決定它們?cè)?Container 中的位置弛房。GroupLayout 主要供生成器使用,但也可以手工編碼捞奕。分組由 Group 類的實(shí)例來完成拄轻。GroupLayout 支持兩種組。串行組 (sequential group) 按順序一個(gè)接一個(gè)地放置其子元素院促。并行組 (parallel group)能夠以四種方式對(duì)齊其子元素斧抱。
??每個(gè)組可以包含任意數(shù)量的元素,其中元素有 Group弄抬、Component 或間隙 (gap)掂恕。間隙可被視為一個(gè)具有最小大小弛槐、首選大小和最大大小的不可見組件。此外店枣,GroupLayout 還支持其值取自 LayoutStyle 的首選間隙叹誉。
??GroupLayout是一個(gè)很重要的布局管理器,在jdk 1.6才加入钧唐,配合其它的管理器可以實(shí)現(xiàn)很好的界面蕉斜。GroupLayout必須要設(shè)置它的GroupLayout.setHorizontalGroup和GroupLayout.setVerticalGroup宅此。
??GroupLayout.setHorizontalGroup是指按照水平來確定,下面例子“賬號(hào)”和“密碼”是一個(gè)級(jí)別的弱匪,其它的組件也是一個(gè)級(jí)別的璧亮。
??GroupLayout.setVerticalGroup。是按照垂直來確定的帘饶。他們的級(jí)別是按照Group去設(shè)置組件的優(yōu)先級(jí)別群扶,級(jí)別越高就顯示越上面。
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
public class GroupLayoutTest extends JFrame {
private static final long serialVersionUID = -5159330521192113057L;
public static void main(String[] args) {
new GroupLayoutTest();
}
JLabel label1;
JLabel label2;
JLabel label3;
JTextField tf;
JPasswordField psf;
JRadioButton rb1;
JRadioButton rb2;
JButton bt1;
JButton bt2;
public GroupLayoutTest() {
this.setVisible(true);
this.setSize(250, 220);
this.setVisible(true);
this.setLocation(400, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label1 = new JLabel("登陸界面");
label2 = new JLabel("賬號(hào):");
label3 = new JLabel("密碼:");
tf = new JTextField();
psf = new JPasswordField();
rb1 = new JRadioButton("記住密碼");
rb2 = new JRadioButton("自動(dòng)登陸");
bt1 = new JButton("登陸");
// 為指定的 Container 創(chuàng)建 GroupLayout
GroupLayout layout = new GroupLayout(this.getContentPane());
this.getContentPane().setLayout(layout);
// 創(chuàng)建GroupLayout的水平連續(xù)組缴饭,颗搂,越先加入的ParallelGroup丢氢,優(yōu)先級(jí)級(jí)別越高先改。
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
// 添加間隔
hGroup.addGap(5);
hGroup.addGroup(layout.createParallelGroup().addComponent(label2).addComponent(label3));
hGroup.addGap(5);
hGroup.addGroup(layout.createParallelGroup().addComponent(label1).addComponent(psf).addComponent(rb1)
.addComponent(rb2).addComponent(tf).addComponent(bt1));
hGroup.addGap(5);
// 設(shè)置水平分組
layout.setHorizontalGroup(hGroup);
// 創(chuàng)建GroupLayout的垂直連續(xù)組,稍浆,越先加入的ParallelGroup猜嘱,優(yōu)先級(jí)級(jí)別越高朗伶。
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
vGroup.addGap(10);
vGroup.addGroup(layout.createParallelGroup().addComponent(label1));
vGroup.addGap(10);
vGroup.addGroup(layout.createParallelGroup().addComponent(label2).addComponent(tf));
vGroup.addGap(5);
vGroup.addGroup(layout.createParallelGroup().addComponent(label3).addComponent(psf));
vGroup.addGroup(layout.createParallelGroup().addComponent(rb1));
vGroup.addGroup(layout.createParallelGroup().addComponent(rb2));
vGroup.addGroup(layout.createParallelGroup(Alignment.TRAILING).addComponent(bt1));
vGroup.addGap(10);
// 設(shè)置垂直組
layout.setVerticalGroup(vGroup);
}
}
三论皆、Java繪圖技術(shù)
?? 坐標(biāo)原點(diǎn)位于左上角猾漫,以像素為單位悯周。像素是計(jì)算機(jī)屏幕上最小的顯示單位陪竿。 在java的坐標(biāo)系中,第一個(gè)是X坐標(biāo)闰挡,表示當(dāng)前位置為水平方向礁哄,距離坐標(biāo)原點(diǎn)X個(gè)像素;第二個(gè)是Y坐標(biāo)花枫,表示當(dāng)前位置為垂直方向掏膏,距離坐標(biāo)原點(diǎn)Y個(gè)像素党涕。
?? 計(jì)算機(jī)在屏幕上顯示的內(nèi)容都是由屏幕上的每一個(gè)像素組成的叁怪。 例如焰雕,計(jì)算機(jī)顯示器的分辨率是800×600矢否,表示計(jì)算機(jī)屏幕上的每一行由800個(gè)點(diǎn)組成腥刹,共有600行,整個(gè)計(jì)算機(jī)屏幕共有480000個(gè)像素∠畏澹現(xiàn)在的計(jì)算機(jī)可以支持更高的分辨率,也就是說威彰,屏幕上可以顯示更多的像素穴肘。因此, 像素是一個(gè)密度單位豹缀,而厘米是長度單位,兩者無法比較啸如。
??Component類提供了兩個(gè)和繪圖相關(guān)最重要的方法:
??1鸣剪、paint(Graphics g)繪制組件的外觀筐骇;
??2江滨、repaint()刷新組件的外觀。
??當(dāng)組件第一次在屏幕顯示的時(shí)候告唆,程序會(huì)自動(dòng)的調(diào)用paint()方法來繪制組件晶密,在以下情況paint()將會(huì)被調(diào)用:
??1、窗口最小化懂牧,再最大化尊勿;
??2、窗口的大小發(fā)生變化躯保;
??3澎语、repaint函數(shù)被調(diào)用。
1盯孙、Graphics類
??Graphics類可以理解就是畫筆祟滴,為我們提供了各種繪制圖形的方法:
??1、畫直線 drawLine(int x1, int y1, int x2, int y2);
??2骑晶、畫矩形邊框 drawRect(int x, int y, int width, int height);
??3、畫橢圓邊框 drawOval(int x, int y, int width, int height);
??4匙头、填充矩形 fillRect(int x, int y, int width, int height);
??5仔雷、填充橢圓 fillOval(int x, int y, int width, int height);
??6、畫圖片 drawImage(Image img, int x, int y,..);
??7电抚、畫字符串 drawString(String str, int x, int y);
??8竖共、設(shè)置畫筆的字體 setFont(Font font);
??9、設(shè)置畫筆的顏色 setColor(Color c);
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GraphicsTest extends JFrame {
// 定義組件
MyPanel1 mp = null;
public static void main(String[] args) {
new GraphicsTest();
}
public GraphicsTest() {
// 構(gòu)建組件
mp = new MyPanel1();
// 加入組件
this.add(mp);
// 設(shè)置窗體
this.setSize(400, 300);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
/**
* @Description: 定義一個(gè)MyPanel(我自己的面板是用于繪圖和顯示繪圖的區(qū)域)
*/
class MyPanel1 extends JPanel {
private static final long serialVersionUID = 1L;
// 重寫(覆蓋)JPanel的paint方法
public void paint(Graphics g) {
// 1借帘、調(diào)用父類函數(shù)肺然,完成初始化任務(wù)
super.paint(g);
// 畫一個(gè)直線
g.drawLine(10, 10, 40, 10);
// 畫矩形邊框
g.drawRect(50, 50, 40, 40);
// 畫橢圓邊框
g.drawOval(130, 130, 60, 60);
// 畫填充矩形
g.setColor(Color.blue);
g.fillRect(10, 150, 70, 70);
// 畫填充橢圓
// 設(shè)置畫筆顏色
g.setColor(Color.red);
g.fillOval(270, 140, 100, 80);
// 如何畫出字
g.setColor(Color.red);
g.setFont(new Font("黑體", Font.BOLD, 40));
g.drawString("祖國萬歲", 150, 100);
// 畫弧形
g.drawArc(100, 100, 120, 200, 50, 100);
}
}
2狰挡、Graphics2D類
??Java語言在Graphics類提供繪制各種基本的幾何圖形的基礎(chǔ)上释涛,擴(kuò)展Graphics類提供一個(gè)Graphics2D類,它擁用更強(qiáng)大的二維圖形處理能力它匕,提供窖认、坐標(biāo)轉(zhuǎn)換、顏色管理以及文字布局等更精確的控制烧给。
??繪圖屬性
??Graphics2D定義了幾種方法喝噪,用于添加或改變圖形的狀態(tài)屬性×穸Γ可以通過設(shè)定和修改狀態(tài)屬性,指定畫筆寬度和畫筆的連接方式盗似;設(shè)定平移平项、旋轉(zhuǎn)、縮放或修剪變換圖形接癌;以及設(shè)定填充圖形的顏色和圖案等鸳粉。圖形狀態(tài)屬性用特定的對(duì)象存儲(chǔ)园担。
2.1、stroke屬性
??stroke屬性控制線條的寬度艰山、筆形樣式咏闪、線段連接方式或短劃線圖案。該屬性的設(shè)置需要先創(chuàng)建BasicStroke對(duì)象纵装,再調(diào)用setStroke()方法來設(shè)置据某。創(chuàng)建BasicStroke對(duì)象的方法有:
??BasicStroke(float w):指定線條寬w。
??BasicStroke(float w, int cap, int join):
??cap是端點(diǎn)樣:CAP_BUTT(無修飾)挽唉,CAP_ROUND(半圓形末端)筷狼,CAP_SQUARE(方形末端,默認(rèn)值)塑顺。
??Join定義兩線段交匯處的連接方式:JOIN_BEVEL(無修飾)俏险,JOIN_MTTER(尖形末端首昔,默認(rèn)值)勒奇,JOIN_ROUND(圓形末端)巧骚。
2.2、paint屬性
??paint屬性控制填充效果竣蹦。先調(diào)用以下方法確定填充效果沧奴,理用setPaint()方法設(shè)置。
??GradientPaint(float x1, float y1, Color c1, float x2, flaot y2, Color c2):從(x1, y1)到(x2, y2)顏色從c1漸變到c2纲菌。其中:參數(shù)c1, c2決定這個(gè)漸變色是從顏色c1漸變到顏色c2疮绷。參數(shù)x1, y1, x2, y2決定了漸變的強(qiáng)弱,即要求從點(diǎn)(x1, y1)出發(fā)到達(dá)點(diǎn)(x2, y2)椅贱,顏色從c1變成c2只冻。
??GradientPaint(float x1, float y1, Color c1, float x2, float y2, Color c2, Boolean cyclic):如果希望漸變到終點(diǎn)又是起點(diǎn)的顏色,應(yīng)將cyclic設(shè)置為true山橄。
2.3住诸、transform屬性
??transform 屬性用來實(shí)現(xiàn)常用的圖形平移、縮放和斜切等變換操作丧诺。首先創(chuàng)建AffineTransform對(duì)象奄薇,然后調(diào)用setTransform()方法設(shè)置transform屬性。最后呵晚,用具有指定屬性的Graphics2D對(duì)象繪制圖形饵隙。創(chuàng)建AffineTransform對(duì)象的方法有:
??getRotateinstrance(double theta):旋轉(zhuǎn)theta弧度。
??getRotateInstance(double theta, dioble x, double y):繞旋轉(zhuǎn)中心(x, y)旋轉(zhuǎn)芯急。
??getScaleInstance(double sx, double sy):x和y 方向分別按sx, sy比例變換驶俊。
??getTranslateInstance(double tx, double ty):平移變換。
??getShearInstance(double shx, double shy):斜切變換榕酒,shx和shy指定斜拉度故俐。
??也可以先創(chuàng)建一個(gè)沒有transform屬性的AffineTransform對(duì)象,然后用以下方法指定圖形平移杖挣、旋轉(zhuǎn)刚陡、縮放變換屬性株汉。
??transelate(double dx, double dy):將圖形在x軸方向平移dx像素。
??scale(double sx, double sy):圖形在x軸方向縮放sx倍蝙云,縱向縮放sy倍路召。
??rotate(double arc, double x, double y):圖形以點(diǎn)(x, y)為軸點(diǎn),旋轉(zhuǎn)arc弧度身隐。
??例如唯灵,創(chuàng)建AffineTransform對(duì)象:
??AffineTransform trans = new AffineTransform();
??為AffineTransform對(duì)象指定繞點(diǎn)旋轉(zhuǎn)變換屬性:
??Trans.rotate(50.0*3.1415927/180.0,90,80);
??接著為Graphics2D 的對(duì)象g2d設(shè)置具有上述旋轉(zhuǎn)變換功能的“畫筆”:
??Graphics2D g2d = (Graphics2D)g; g2d.setTranstorm(trans);
??最后,以圖形對(duì)象為參數(shù)調(diào)用具有變換功能的Graphics2D 對(duì)象的draw()方法垢揩。例如,設(shè)已有一個(gè)二次曲線對(duì)象curve斑匪,以下代碼實(shí)現(xiàn)用上述旋轉(zhuǎn)功能的g2d對(duì)象繪制這條二次曲線:
??g2d.draw(curve);
2.4锋勺、clip屬性
??clip屬性用于實(shí)現(xiàn)剪裁效果。設(shè)置剪裁屬性可調(diào)用setClip()方法確定剪裁區(qū)的Shape苍姜。連續(xù)多個(gè)setClip()得到它們交集的剪裁區(qū)衙猪。
2.5、composit屬性
??composit屬性設(shè)置圖形重疊區(qū)域的效果垫释。先用方法AlphaComposite.getInstance(int rule, float alpha)得到AlphaComposite對(duì)象棵譬,再通過setComposite()方法設(shè)置混合效果预伺。Alpha值的范圍為0.0f(完全透明)-0.1f(完全不透明)。
2.6脏嚷、Graphics2D類的繪圖方法
??Graphics2D類仍然保留Graphics類的繪圖方法瞒御,同時(shí)增加了許多新方法。新方法將幾何圖形(線段趾唱、圓等)作為一個(gè)對(duì)象來繪制蜻懦。在java.awt.geom包中聲明的一系列類,分別用于創(chuàng)建各種身體圖形對(duì)象阻肩。主要有:
??Line2D線段類,RoundRectangle2D圓角矩形類乔煞,Ellipse2D橢圓類,Arc2D圓弧類逗宜,QuadCurve2D二次曲線類空骚,CubicCurve2D三次曲線類。
??要用Graphics2D類的新方法畫一個(gè)圖形囤屹。先在重畫方法paintComponent()或paint()中,把參數(shù)對(duì)象g強(qiáng)制轉(zhuǎn)換成Graphics2D對(duì)象乡括;然后智厌,用上述圖形類提供的靜態(tài)方法Double()創(chuàng)建該圖形的對(duì)象;最后敷扫,以圖形對(duì)象為參數(shù)調(diào)用Graphics2D對(duì)象的draw()方法繪制這個(gè)圖形诚卸。例如以下代碼用Graphics2D的新方法繪制線段和圓角矩形:
??// 將對(duì)象g類型從Graphics轉(zhuǎn)換成Graphics2D
??Graphics2D g2d = (Graphics2D)g;
??Line2D line = new Line2D.Double(30.0, 30.0, 340.0, 30.0);
??g2d.draw(line);
??RoundRectangle2D rRect = new RoundRectangle2D.Double(13.0, 30.0, 100.0, 70.0, 40.0, 20.0);
??g2d.draw(rRect);
??也可以先用java.awt.geom包提供的Shape對(duì)象惨险,并用單精度Float坐標(biāo)或雙精度Double坐標(biāo)創(chuàng)建Shape對(duì)象脊髓,然后再用draw()方法繪制。例如恭朗,以下代碼先創(chuàng)建圓弧對(duì)象依疼,然后繪制圓弧:
??Shape arc = new Arc2D.Float(30, 30, 150, 150, 40, 100, Arc2D.OPEN);
??g2d.draw(arc); //繪制前面創(chuàng)建的圖形對(duì)象arc.
??Graphics2D的幾何圖形類
??1膀值、線段:
??// 聲明并創(chuàng)建線段對(duì)象(起點(diǎn)是(2,3)沧踏,終點(diǎn)是(200,300))
??Line2D line = new Line2D.Double(2,3,200,300);
??2秘案、矩形:
??// 聲明并創(chuàng)建矩形對(duì)象潦匈,矩形的左上角是(20,30)赤惊,寬是300凰锡,高是40。
??Rectangle2D rect = new Rectangle2D.Double(20, 30, 80, 40);
??3处面、圓角矩形:
??// 左上角是(20菩掏,30),寬是130智绸,高是100,圓角的長軸是18斯稳,短軸是15迹恐。
??RoundRectangle2D rectRound = new RoundRectangle2D.Double(20, 30, 130, 100, 18, 15);
??4、橢圓:
??// 左上角 (20憎茂,30)锤岸,寬是100,高是50
??Ellipse2D ellipse = new Ellipse2D.Double(20, 30, 100, 50);
??5拳氢、圓弧:
??// 外接矩形的左上角(10馋评,30),寬85透乾,高60磕秤,起始角是5度,終止角是90度汉操。
??Arc2D arc1 = new Arc2D.Double(10, 30, 85, 60, 5, 90, Arc2D.OPEN);
??Arc2D arc2 = new Arc2D.Double(20,65,90,70,0,180,Arc2D.CHORD);
??Arc2D arc3 = new Arc2D.Double(40,110,50,90,0,270,Arc2D.PIE);
??// 參數(shù)Arc2D.OPEN蒙兰、Arc2D.CHORD、Arc2D.PIE分別表示圓弧是開弧采缚、弓弧和餅弧挠他。
??6、二次曲線:
??二次曲線用二階多項(xiàng)式表示:y(x) = ax2+bx+c贸呢。一條二次曲線需要三個(gè)點(diǎn)確定:始點(diǎn)拢军、控制點(diǎn)和終點(diǎn)。
??QuadCurve2D curve1 = new QuadCurver2D.Double(20,10,90,65,55,115);
??QuadCurve2D curve2 = new QuadCurver2D.Double(20,10,15,63,55,115);
??QuadCurve2D curve3 = new QuadCurver2D.Double(20,10,54,64,55,115);
??// 方法Double()中的6個(gè)參數(shù)分別是二次曲線的始點(diǎn)固蛾、控制點(diǎn)和終點(diǎn)赌渣。以上3條二次曲線的開始點(diǎn)和終點(diǎn)分別相同。
??7、三次曲線:
??三次曲線用三階多項(xiàng)式表示:y(x)=ax3+bx2+cx+d斜姥。一條三次曲線需要四個(gè)點(diǎn)確定:始點(diǎn)沧竟、兩個(gè)控制點(diǎn)和終點(diǎn)悟泵。
??CubicCurve2D curve1 = new CubicCurve2D.Double(12,30,50,75,15,15,115,93);
??CubicCurve2D curve2 = new CubicCurve2D.Double(12,30,15,70,20,25,35,94);
??CubicCurve2D curve3 = new CubicCurve2D.Double(12,30,50,75,20,95,95,95);
??方法Double()中的8個(gè)參數(shù)分別是三次曲線的始點(diǎn)闪水、兩個(gè)控制點(diǎn)和終點(diǎn)。
??一般的方程曲線的繪制過程用一個(gè)循環(huán)控制朽肥。通過循環(huán)產(chǎn)生自變量的值持钉,按照方程計(jì)算出函數(shù)值,再作必要的坐標(biāo)轉(zhuǎn)換:原點(diǎn)定位的平移變換始腾,圖像縮小或放大的縮放變換空执,得到曲線的圖像點(diǎn),并繪制這個(gè)點(diǎn)山林。以繪制以下曲線方程為例:
??Y=sin(x)+cos(x)
繪制的部分代碼可以寫成如下:
double x0, y0, x1, y1, x2, y2, scale;
x0 = 100; y0 = 80;
scale = 20.0;
for(x1 = -3.1415926d; x1 <= 2*3.1415926d; x1 += 0.01d) {
y1 = Math.sin(x1) + Math.cos(x1);
x2 = x0 + x1 * scale; y2 = y0 + y1 * scale; //(x2,y2)是圖像點(diǎn)
g.fillOval((int)x2, (int)y2, 1, 1); // 畫一個(gè)圓點(diǎn)作為圖像點(diǎn)
}
四邢羔、事件處理機(jī)制
??Java事件處理是采取“委派事件模型”。所謂“委派事件模型”是指當(dāng)事件發(fā)生時(shí)框冀,產(chǎn)生事件的對(duì)象(即事件源)敏簿,會(huì)把此“信息”傳遞給“事件的監(jiān)聽者”處理的一種方式,而這里所說的“信息”實(shí)際上就是java.awt.event事件類庫里的某個(gè)類所創(chuàng)建的對(duì)象温数。我們暫時(shí)把它稱為“事件的對(duì)象”蜻势。
??1、事件源(event source)
??事件源是一個(gè)產(chǎn)生(或觸發(fā))事件的對(duì)象够傍,如文本框、按鈕等冕屯。當(dāng)這個(gè)事件源對(duì)象的某些狀態(tài)以某種方式發(fā)生變化時(shí),就會(huì)產(chǎn)生某種類型的事件(一個(gè)事件源可能會(huì)生成多個(gè)不同類型的事件)痰洒。如果某個(gè)組件(對(duì)象)希望得到事件源產(chǎn)生的事件浴韭,就需要在這個(gè)事件源上注冊(cè),一個(gè)事件源是一個(gè)能夠注冊(cè)監(jiān)聽器并且為它們發(fā)送事件對(duì)象的對(duì)象仓犬。
??2舍肠、事件(event object)
事件就是承載事件源狀態(tài)改變時(shí)的信息對(duì)象∵辞或者說肌括,事件是事件源事件監(jiān)聽器傳輸事件源狀態(tài)信息的載體。在用戶與GUI組件進(jìn)行交互時(shí)就會(huì)生成事件黑滴,比如當(dāng)鼠標(biāo)在面板中移動(dòng)時(shí)紧索,就會(huì)生成一個(gè)鼠標(biāo)移動(dòng)事件的對(duì)象,而這個(gè)對(duì)象保存著當(dāng)前鼠標(biāo)在面板中位置信息晚缩。java.awt.event包和javax.swing.event包中定義了各種事件類型媳危,常見的事件類有:
事件類 | 說明 |
---|---|
ActionEvent | 通常在按下按鈕,或雙擊一個(gè)列表項(xiàng)或選中某個(gè)菜單時(shí)發(fā)生 |
AdjustmentEvnet | 當(dāng)操作一個(gè)滾動(dòng)條時(shí)發(fā)生 |
ComponentEvent | 當(dāng)一個(gè)組件隱藏鸣皂、移動(dòng)、改變大小時(shí)發(fā)送 |
ContainerEvent | 當(dāng)一個(gè)組件從容器中加入或者刪除時(shí)發(fā)生 |
FocusEvent | 當(dāng)一個(gè)組件獲得或是失去焦點(diǎn)時(shí)發(fā)生 |
ItemEvent | 當(dāng)一個(gè)復(fù)選框或是列表項(xiàng)被選中時(shí)齐邦,當(dāng)一個(gè)選擇框或選擇菜單被選中 |
KeyEvent | 當(dāng)從鍵盤的按鍵被按下第租,松開時(shí)發(fā)生 |
MouseEvent | 當(dāng)鼠標(biāo)被拖動(dòng)我纪、移動(dòng)、點(diǎn)擊趟据、按下.. |
TextEvent | 當(dāng)文本區(qū)和文本域的文本發(fā)生改變時(shí)發(fā)生 |
WindowEvent | 當(dāng)一個(gè)窗口激活术健、關(guān)閉、失效咳促、恢復(fù)勘伺、最小化... |
??3、事件監(jiān)聽器接口
??事件源產(chǎn)生一個(gè)事件冲茸,可以傳送給事件監(jiān)聽者處理缅帘,那么怎樣才能編寫一個(gè)事件監(jiān)聽者呢?
??事件監(jiān)聽者實(shí)際上就是一個(gè)類逗栽,該類實(shí)現(xiàn)了某個(gè)事件監(jiān)聽器接口铃诬,它就可以作為一個(gè)事件監(jiān)聽者,對(duì)接受到的事件進(jìn)行處理趣席。
??事件監(jiān)聽器接口有多種,不同的事件監(jiān)聽器接口可以監(jiān)聽不同的事件想罕,一個(gè)類可以實(shí)現(xiàn)一個(gè)事件監(jiān)聽接口,也可以實(shí)現(xiàn)多個(gè)監(jiān)聽接口惭适,這些接口在java.awt.event和javax.swing.event包中定義楼镐。