GUI(念法 gu yi)
AWT
Component 和 Container
Frame
示例1:
import java.awt.*;
public class TestFrame {
public static void main( String args[]) {
Frame f = new Frame("My First Test");
f.setLocation(300, 300);
f.setSize( 170,100);
f.setBackground( Color.blue);
f.setResizable(false);
f.setVisible( true);
}
}
示例2:(推荐)
import java.awt.*;
public class Test {
public static void main(String args[]) {
MyFrame f1 = new MyFrame(100,100,200,200,Color.BLUE);
MyFrame f2 = new MyFrame(300,100,200,200,Color.YELLOW);
MyFrame f3 = new MyFrame(100,300,200,200,Color.GREEN);
MyFrame f4 = new MyFrame(300,300,200,200,Color.MAGENTA);
}
}
class MyFrame extends Frame{
static int id = 0;
MyFrame(int x,int y,int w,int h,Color color){
super("MyFrame " + (++id));
setBackground(color);
setLayout(null);
setBounds(x,y,w,h);
setVisible(true);
}
}
Panel
示例1:
import java.awt.*;
public class Test {
public static void main(String args[]) {
Frame f = new Frame("Java Frame with Panel");
Panel p = new Panel(null);
f.setLayout(null); // 少了此句话,将不显示Frame的背景,全部由Panel覆盖
f.setBounds(300,300,500,500);
f.setBackground(new Color(102,95,51));
p.setBounds(50,50,400,400);
p.setBackground(new Color(204,204,255));
f.add(p);
f.setVisible(true);
}
}
示例2:
import java.awt.*;
public class Test {
public static void main(String args[]) {
new MyFrame("MyFrameWithPanel",300,300,400,300);
}
}
class MyFrame extends Frame{
private Panel p1,p2,p3,p4;
MyFrame2(String s,int x,int y,int w,int h){
super(s);
setLayout(null);
p1 = new Panel(null); p2 = new Panel(null);
p3 = new Panel(null); p4 = new Panel(null);
p1.setBounds(0,0,w/2,h/2);
p2.setBounds(0,h/2,w/2,h/2);
p3.setBounds(w/2,0,w/2,h/2);
p4.setBounds(w/2,h/2,w/2,h/2);
p1.setBackground(Color.BLUE);
p2.setBackground(Color.GREEN);
p3.setBackground(Color.YELLOW);
p4.setBackground(Color.MAGENTA);
add(p1);add(p2);add(p3);add(p4);
setBounds(x,y,w,h);
setVisible(true);
}
}
PS: Panel 的 setBounds 方法中设置的位置大小是相对于相对装入的 Frame 窗口位置和大小的。
布局管理器
FlowLayout
示例1:
import java.awt.*;
public class Test {
public static void main(String args[]) {
Frame f = new Frame("Flow Layout");
Button button1 = new Button("Ok");
Button button2 = new Button("Open");
Button button3 = new Button("Close");
f.setLayout(new FlowLayout(FlowLayout.CENTER));
f.add(button1);
f.add(button2);
f.add(button3);
//f.setSize(100,100);
f.pack(); // pack打包,刚好包住 f 里面的组件,自适应。
f.setVisible(true);
}
}
示例2:
import java.awt.*;
public class Test {
public static void main(String args[]) {
Frame f = new Frame("Java Frame");
FlowLayout l =
new FlowLayout(FlowLayout.CENTER, 20, 40);
f.setLayout(l);
f.setLocation(300,400);
f.setSize(300,200);
f.setBackground(new Color(204,204,255));
for(int i = 1; i<=7; i++){
f.add(new Button("BUTTON"));
}
f.setVisible(true);
}
}
BorderLayout
示例:
import java.awt.*;
public class Test {
public static void main(String args[]) {
Frame f;
f = new Frame("Border Layout");
Button bn = new Button("BN");
Button bs = new Button("BS");
Button bw = new Button("BW");
Button be = new Button("BE");
Button bc = new Button("BC");
f.add(bn, BorderLayout.NORTH);
f.add(bs, BorderLayout.SOUTH);
f.add(bw, BorderLayout.WEST);
f.add(be, BorderLayout.EAST);
f.add(bc, BorderLayout.CENTER);
f.setSize(200,200);
f.setVisible(true);
}
}
GridLayout
示例:
import java.awt.*;
public class Test {
public static void main(String args[]) {
Frame f = new Frame("GridLayout Example");
Button b1 = new Button("b1");
Button b2 = new Button("b2");
Button b3 = new Button("b3");
Button b4 = new Button("b4");
Button b5 = new Button("b5");
Button b6 = new Button("b6");
f.setLayout (new GridLayout(3,2));
f.add(b1);
f.add(b2);
f.add(b3);
f.add(b4);
f.add(b5);
//f.add(b6);
f.pack();
f.setVisible(true);
}
}
问题:请使用 Container 的嵌套实现下面布局?
代码:(实现原理:Panel 嵌套 Panel)
import java.awt.*;
public class Test {
public static void main(String args[]) {
Frame f = new Frame("Frame");
f.setLayout(new GridLayout(2,1));
f.setBounds(400,200, 500, 300);
Panel p1 = new Panel(new BorderLayout());
Panel p2 = new Panel(new BorderLayout());
Panel p11 = new Panel(new GridLayout(2,1));
Panel p22 = new Panel(new GridLayout(2,2));
p11.add(new Button("BUTTON"));
p11.add(new Button("BUTTON"));
p1.add(p11, BorderLayout.CENTER);
p1.add(new Button("BUTTON"), BorderLayout.WEST);
p1.add(new Button("BUTTON"), BorderLayout.EAST);
for(int i=0; i<4; i++) {
p22.add(new Button("BUTTON"));
}
p2.add(p22, BorderLayout.CENTER);
p2.add(new Button("BUTTON"), BorderLayout.WEST);
p2.add(new Button("BUTTON"), BorderLayout.EAST);
f.add(p1);
f.add(p2);
f.setVisible(true);
}
}
布局管理器总结
事件监听
示例:
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String args[]) {
Frame f = new Frame("Test");
Button b = new Button("Press Me!");
Monitor bh = new Monitor();
b.addActionListener(bh);
f.add(b,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
}
class Monitor implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("a button has been pressed");
}
}
TextField 类
示例1:
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
new TFFrame();
}
}
class TFFrame extends Frame {
TFFrame() {
TextField tf = new TextField();
add(tf);
tf.addActionListener(new TFActionListener());
// tf.setEchoChar('*');
pack();
setVisible(true);
}
}
class TFActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
TextField tf = (TextField)e.getSource();
System.out.println(tf.getText());
tf.setText("");
}
}
示例2:
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
new TFFrame();
}
}
class TFFrame extends Frame {
TextField tf1, tf2, tfsum;
Label lb = null;
Button btn = null;
TFFrame() {
tf1 = new TextField(10);
tf2 = new TextField(10);
tfsum = new TextField(15);
lb = new Label("+");
btn = new Button("=");
btn.addActionListener(new TFActionListener(this));
setLayout(new FlowLayout());
add(tf1);
add(lb);
add(tf2);
add(btn);
add(tfsum);
pack();
setVisible(true);
}
}
class TFActionListener implements ActionListener {
private TFFrame tf;
TFActionListener(TFFrame tf) {
this.tf = tf;
}
@Override
public void actionPerformed(ActionEvent e) {
int t1 = Integer.parseInt(tf.tf1.getText());
int t2 = Integer.parseInt(tf.tf2.getText());
tf.tfsum.setText("" + (t1 + t2));
}
}
private TFFrame tf;
TFActionListener(TFFrame tf) { this.tf = tf;}
当我们需要获取其他的对象的时候,传递的不是另一个对象的成员变量,而是将整个对象的引用传递过来,这种编程模式叫做 “门面模式” 。网上有详细解释。
内部类
示例:
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
new TFFrame("Frame of sum");
}
}
class TFFrame extends Frame {
TextField tf1, tf2, tfsum;
Label lb = null;
Button btn = null;
TFFrame(String s) {
super(s);
tf1 = new TextField(10);
tf2 = new TextField(10);
tfsum = new TextField(15);
lb = new Label("+");
btn = new Button("=");
btn.addActionListener(new TFActionListener());
setLayout(new FlowLayout());
add(tf1);
add(lb);
add(tf2);
add(btn);
add(tfsum);
pack();
setVisible(true);
}
class TFActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
int t1 = Integer.parseInt(tf1.getText());
int t2 = Integer.parseInt(tf2.getText());
tfsum.setText("" + (t1 + t2));
}
}
}
内部类:将 class TFActionListener implements ActionListener 放到了 TFFrame 类的内部。
Graphics 类 paint 方法
什么叫重画该 Component 的时候?
打比方说 Component 是一个窗口,那么改变窗口大小的时候,最小化最大化窗口的时候,切换到其他界面再切回来的时候都会重画窗口,都会导致 paint 方法自动被调用。
示例:
import java.awt.*;
public class Test {
public static void main(String[] args) {
new PaintFrame().launchFrame();
}
}
class PaintFrame extends Frame {
public void launchFrame() {
setBounds(200,200,640,480);
setVisible(true);
}
public void paint(Graphics g) {
Color c = g.getColor(); // 作用为保护现场
g.setColor(Color.red);
g.fillOval(50, 50, 30, 30);
g.setColor(Color.green);
g.fillRect(80,80,40,40);
g.setColor(c); // 作用为恢复现场
}
}
鼠标事件适配器
示例:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Test{
public static void main(String args[]) {
new MyFrame("Draw Point");
}
}
class MyFrame extends Frame {
ArrayList points = null;
MyFrame(String s) {
super(s);
points = new ArrayList();
setLayout(null);
setBounds(300,300,400,300);
this.setBackground(new Color(204,204,255));
setVisible(true);
this.addMouseListener(new Monitor());
}
@Override
public void paint(Graphics g) {
Iterator i = points.iterator();
while(i.hasNext()){
Point p = (Point)i.next();
g.setColor(Color.RED);
g.fillOval(p.x,p.y,10,10);
}
}
public void addPoint(Point p){
points.add(p);
}
}
class Monitor extends MouseAdapter {
public void mousePressed(MouseEvent e) {
MyFrame f = (MyFrame)e.getSource();
f.addPoint(new Point(e.getX(),e.getY()));
f.repaint(); // 当有鼠标点击时重绘,保证在界面未重画的时候,强制重画界面
}
}
repaint() 方法调用了 -- update() 调用了 --paint() 方法。基本上所有的 GUI 图形绘制都是采用这样的方法。
Window 事件 和 匿名类
示例:
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String args[]) {
new MyFrame55("MyFrame");
}
}
class MyFrame55 extends Frame {
MyFrame55(String s) {
super(s);
setLayout(null);
setBounds(300, 300, 400, 300);
this.setBackground(new Color(204, 204, 255));
setVisible(true);
//this.addWindowListener(new MyWindowMonitor());
this.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(0);
}
});
}
/*
class MyWindowMonitor extends WindowAdapter {
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(-1);
}
}
*/
}
其中:
this.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(0);
}
});
/*
class MyWindowMonitor extends WindowAdapter {
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(-1);
}
}
*/
为匿名类。
在实际的项目中看到一个很奇怪的现象,Java可以直接new一个接口,然后在new里面粗暴的加入实现代码。就像下面这样。那么问题来了,new出来的对象没有实际的类作为载体,这不是很奇怪吗?
思考以下代码的输出是什么?
Runnable x = new Runnable() {
@Override
public void run() {
System.out.println(this.getClass());
}
};
x.run();
实际答案是出现xxxx$1这样一个类名,它是编译器给定的名称。
键盘事件的测试程序
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String args[]) {
new MyFrame("Key Frame");
}
}
class MyFrame extends Frame {
MyFrame(String s) {
super(s);
setBounds(300, 200, 200, 200);
addKeyListener(new MyKeyListener());
addWindowListener(new MyWindowListener());
setVisible(true);
}
class MyKeyListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP) {
System.out.println("UP!");
}
}
}
class MyWindowListener extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}