Java图形用户界面概述
一、Java语言平台无关性组件的实现
图形用户界面是当今流行的操作系统界面。
Java语言为了适应发展趋势,也具有开发图形化的用户界面的功能。
Java语言自身的特点要求其图形用户界面具有平台无关性。
早期的Java版本JDK1.0和JDK1.1采用 的是AWT组件。特点是简单、易于理解。
AWT组件中采用了一种称为对等体(peer)的机制,每个组件都有一个对应的对等体,是用具体的操作系统平台的开发工具开发的,负责在AWT组件与本地平台之间进行交互。
同一个AWT组件在不同的平台上显示出不同的外观,种类不可能太多,这大大限制了Java语言程序的使用和推广。
Java 1.2版,图形用户界面功能被大幅度地扩展,形成了称为Java基础类库(Java Foundation Class,JFC)的一整套API集合,主要包括以下5个部分:
⑴抽象窗口工具;
⑵Swing图形界面类库;
⑶支持二维图形的类库(Java 2D);
⑷支持拖放的类库(Drag and Drop);
⑸支持易用性的类库(Accessibility)。
主要的部分是Swing图形界面类库。
窗体的建立
import java.awt.*;
public class exec
{
public static void main(String args[])
{
Frame f=new Frame("This is a window!");
f.setLocation(100,200);
f.setSize(200,400);
f.setBackground(Color.red);
f.setVisible(true);
}
}
组件的添加
import java.awt.*;
public class exec
{
public static void main(String args[])
{
Frame f=new Frame("This is a window!");
f.setLocation(100,200);
f.setSize(200,400);
f.setBackground(Color.red);
Button b1=new Button("Ok!");
f.add(b1);
f.setVisible(true);
}
}
Swing组件是用纯Java实现的,在不同的平台上其表现是一致的。Swing组件没有本地代码,不依赖于具体的本机操作系统的支持,并且还有能力提供本地系统不支持的其它特性,
这是它与AWT组件的最大区别。
Swing组件实现了平台无关的Java语言。
Swing组件是AWT组件的扩展,它提供了许多新的图形用户界面组件。
因为大部分AWT组件都在Swing组件中进行了重写,所以本章后面我们在介绍组件的时候将以Swing组件为主。
Swing组件的类以字母“J”开头,除了保留有与AWT类似的组件之外,又增加了丰富的高层组件。
Swing组件使用MVC体系结构,支持可存取性,支持使用图标(Icon)和边框,支持键盘操作,还可以让用户通过程序代码来设置不同的外观和感觉。
所谓外观和感觉(Look and Feel)是指程序与用户进行人机交互的方式及实现这种方式的界面。
把绑定在本地平台的组件称为重量级组件,把完全用Java编写的组件称为轻量级组件。
重量级组件包括所有的AWT组件和Swing组件中的JFrame、JApplet、JDialog、JWindow等四个顶层容器;轻量级组件包括除了上述四个顶层容器之外的所有的Swing组件。
重量级组件与平台相关,在不同的平台上可能有不同的外观;而轻量级组件与平台无关,外观不随平台变化。
学习swing
先看一个最为简单的窗体例子,如:
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String args[])
{
JFrame f=new JFrame("This is a window!");
f.setLocation(100,200);
f.setSize(200,400);
FlowLayout fl=new FlowLayout();
f.getContentPane().setLayout(fl);
JButton[] jb=new JButton[10];
for(int i=0;i<jb.length;i++)
{
jb[i]=new JButton();
jb[i].setText(String.valueOf(i));
f.getContentPane().add(jb[i]);
}
f.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String [] args)
{
JFrame f=new JFrame("Hello!");
f.setLocation(10,100);
f.setSize(600,400);
f.getContentPane().setLayout(new FlowLayout());
JButton jb = new JButton("Ok");
f.getContentPane().add(jb);
f.setVisible(true);
}
}
可以给按钮添加图片,如:
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String [] args)
{
JFrame f=new JFrame("Hello!");
f.setLocation(10,100);
f.setSize(600,400);
f.getContentPane().setLayout(new FlowLayout());
ImageIcon ii = new ImageIcon("e.gif");
JButton jb = new JButton(ii);
f.getContentPane().add(jb);
f.setVisible(true);
}
}
二、GUI组件的类层次结构
在Java语言中,所有的组件都是以类的形式定义的。
AWT组件被放在java.awt包中,Swing组件被放在javax.swing包中。
java.lang.Object
├─ Font
├─ Color
├─ CheckboxGroup
├─ MenuComponent
└─ Component
MenuComponent
├─ MenuBar
└─ MenuItem
├─ Menu
│ └─ PopupMenu
└─ CheckboxMenuItem
Component
├─ Button, Canvas, Checkbox, Choice, Label, List
├─ TextComponent
│ └─ TextArea, TextField
└─ Container
├─ Panel
│ └─ Applet──JApplet
├─ ScrollPane
└─ Window──JWindow
├─ Frame──JFrame
└─ Dialog──JDialog
└─ FileDialog
轻量级组件的类层次如下所示
java.awt.Container
├─javax.swing.Box
└─javax.swing.JComponent
├─AbstractButton──接后面
├─JColorChooser
├─JComboBox
├─JFileChooser
├─JInternalFrame
├─JLabel
├─JLayeredPane──JDesktopPane
├─JList
├─JMenuBar
├─JOptionPane
├─JPanel
├─JPopupMenu
├─JProgressBar
├─JRootPane
├─JScrollBar
├─JScrollPane
├─JSeparator
├─JSlider
├─JSplitPane
├─JTabbedPane
├─JTable
├─JTextComponent──接后面
├─JToolBar
├─JToolTip
├─JTree
└─JViewport
AbstractButton
├─JButton
├─JToggleButton─┬─JCheckBox
│ └─JRadioButton
└─JMenuItem──┬─JCheckBoxMenuItem
├─JMenu
└─JRadioButtonMenuItem
JTextComponent
├─JEditorPane──JTextPane
├─JTextArea
└─JTextField─┬─JFormattedTextField
└─JPasswordField
Java语言采用向容器中添加组件的方式构建图形用户界面。
通常采用*容器作为所有组件的承载物,可以向其中添加包括容器在内的各种组件,合理地安排组件的布局,从而构成用户所需的图形用户界面。容器之间的嵌套是完全允
许的。
图形用户界面的构建与布局管理器
一、图形用户界面的构建
一个利用AWT组件生成图形用户界面的例子。
import java.awt.*;
public class GUIDemo1
{
public static void main(String[] args)
{
Frame f = new Frame("候选人输入");
Panel p1 = new Panel();
Panel p2 = new Panel();
Panel p3 = new Panel();
Label l1 = new Label("第一候选人");
Label l2 = new Label("第二候选人");
Label l3 = new Label("第三候选人");
TextField t1 = new TextField(20);
TextField t2 = new TextField(20);
TextField t3 = new TextField(20);
Button b1 = new Button("输入");
Button b2 = new Button("输入");
Button b3 = new Button("输入");
f.setLayout(new GridLayout(3,1));
p1.setLayout(new FlowLayout());
p2.setLayout(new FlowLayout());
p3.setLayout(new FlowLayout());
p1.add(l1);
p1.add(t1);
p1.add(b1);
p1.setBackground(Color.cyan);
p2.add(l2);
p2.add(t2);
p2.add(b2);
p2.setBackground(Color.yellow);
p3.add(l3);
p3.add(t3);
p3.add(b3);
p3.setBackground(Color.pink);
f.add(p1);
f.add(p2);
f.add(p3);
f.setSize( 300 , 160 );
f.setVisible(true);
}
}
组件在容器中的定位与大小可以用两种方法确定:
◆采用布局管理器来决定,是Java语言规定的方法,有很多优越性。Java语言目前提供有FlowLayout,BorderLayout,GridLayout,CardLayout,GridBagLayout等布局管理器。优
先级高。
◆采用Java语言提供的setLocation(),setSize(),setBounds()等方法成员,由程序员手工决定。会导致程序的系统相关性,但可以获得更令人满意的效果。优先级低。
二、FlowLayout布局管理器
是一种最简单的布局管理器,它的布局方式是将放入其中的组件按自左向右的顺序一排一排地依次放置,一排放完再放下一排,放入容器中的组件采用最佳尺寸(Preferred Size)
来确定自身的尺寸。如果容器大小发生变化,则组件的位置会发生变化。在布局管理器中可将行对齐方式设为左对齐、居中对齐或右对齐,默认为居中对齐。
FlowLayout类位于java.awt包中,有三个构造方法:
public FlowLayout()
public FlowLayout(int align)
public FlowLayout(int align, int hgap, int vgap)
参数align代表对齐方式,其值取FlowLayout类中三个常量值FlowLayout.LEFT、FlowLayout.CENTER、FlowLayout.RIGHT之一,hgap和vgap分别指定组件间水平和垂直间隔的像素数
,默认值为5。
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String [] args)
{
JFrame f=new JFrame("Hello!");
f.setLocation(10,100);
f.setSize(600,400);
f.getContentPane().setLayout(new FlowLayout(1,10,100));
JButton jb1=new JButton("Click 1");
JButton jb2=new JButton("Click 2");
JButton jb3=new JButton("Click 3");
f.getContentPane().add(jb1);
f.getContentPane().add(jb2);
f.getContentPane().add(jb3);
f.setResizable(false);//重要
f.setVisible(true);
}
}
三、BorderLayout布局管理器
将容器的区域划分为5个部分:上部、中部、下部、左部和右部,并分别以North,Center,South,East和West命名,当向其中添加组件时须指明添加位置,否则无法显示。
5个位置不一定全都放组件,允许出现空缺。
North和South最为优先,其次是East和West,最后是Center。默认位置为Center。
BorderLayout类位于java.awt包中,有两个构造方法:
public BorderLayout()
public BorderLayout(int hgap, int vgap)
参数hgap和vgap的意义同FlowLayout布局管理器,其默认值为0。
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String [] args)
{
JFrame f=new JFrame("Hello!");
f.setLocation(10,100);
f.setSize(600,400);
f.setMinimumSize(new Dimension(200,100));
f.getContentPane().setLayout(new BorderLayout(5,10));
JButton jb1=new JButton("1");
JButton jb2=new JButton("2");
JButton jb3=new JButton("3");
JButton jb4=new JButton("4");
JButton jb5=new JButton("5");
f.getContentPane().add(jb1,BorderLayout.NORTH);
f.getContentPane().add(jb2,BorderLayout.SOUTH);
f.getContentPane().add(jb3,BorderLayout.EAST);
f.getContentPane().add(jb4,BorderLayout.WEST);
f.getContentPane().add(jb5,BorderLayout.CENTER);
f.setVisible(true);
}
}
四、GridLayout布局管理器
将容器的面积均匀分隔成网格式阵列,每个组件占据一个单元位置,所有的组件的大小保持一致,当容器大小发生变化时,各个组件的大小都将发生变化,但是其在容器中的相对
位置保持不变,并且依然保持大小相同。组件依进入容器的顺序从左到右,从上到下排列。
GridLayout类位于java.awt包中,有两个构造方法:
public GridLayout(int rows, int cols)
public GridLayout(int rows, int cols, int hgap, int vgap)
参数rows和cols分别指定阵列的行数、列数,使用时至少有一个非0,参数hgap和vgap的意义同FlowLayout布局管理器,默认值为0。
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String [] args)
{
JFrame f=new JFrame("Hello!");
f.setLocation(10,100);
f.setSize(600,400);
f.setMinimumSize(new Dimension(200,100));
f.getContentPane().setLayout(new GridLayout(3,3,10,10));
JButton[] jb=new JButton[9];
for(int i=0;i<jb.length;i++)
{
jb[i]=new JButton(String.valueOf(i));
f.getContentPane().add(jb[i]);
}
f.setVisible(true);
}
}
五、CardLayout布局管理器
将容器中的每个组件看作一张卡片,用户一次只能看到一张卡片。每个组件在显示时都将充满整个空间,组件的显示顺序由组件对象本身在容器内部的顺序决定。
在CardLayout类中定义了一组方法,显示指定的卡片。next()方法和previous()方法分别显示后一个组件和前一个组件,first()方法和last()方法分别显示第一个组件和最后一个
组件,show()方法显示具有指定标识符的组件。
CardLayout类同样也是位于java.awt包中,有两个构造方法:
public CardLayout()
public CardLayout(int hgap, int vgap)
参数hgap和vgap分别为卡之间的水平和垂直距离,默认值为0。
import javax.swing.*;
import java.awt.*;
public class GUITest
{
public static void main(String[] args)
{
JFrame frm = new JFrame("Frame with Controls");
frm.getContentPane().setLayout(new CardLayout());
button[] btn = new JButton[10];
for (int i=0; i<10; i++)
{
btn[i] = new JButton("Button " + (i+1));
frm.add(("Button " + (i+1)), btn[i]);
}
frm.setBounds(100, 100, 250, 100);
frm.setVisible(true);
while (true)
{
((CardLayout)frm.getContentPane().getLayout()).previous(frm.getContentPane());
}
}
}
六、GridBagLayout布局管理器
是一个灵活的布局管理器,使用矩形单元格为单位对组件进行布局。每个组件占用一个或多个这样的单元,称为显示区域。放置组件时将依据每个组件的约束参数,最小尺寸,以
及该组件容器的最佳尺寸。为每一个由该布局管理器管理的组件生成一个GridBagConstraints类的对象实例作为其约束参数,该对象实例指定组件在网格中的显示区域以及组件在
其显示区域中的放置方式。
GridBagLayout类也是位于java.awt包中,只有一个构造方法:
public GridBagLayout()
GridBagConstraints类同样是被定义在java.awt包中,其下列字段对设置组件起作用:
gridx和gridy;gridwidth和gridheight;weightx和weighty;anchor;fill;insets;ipadx和ipady。
GridBagConstraints类有一个无参构造方法和一个包含有上面11个参数的有参构造方法,这些字段可以在调用有参构造方法时设定,还可以在程序中直接设定。
import javax.swing.*;
import java.awt.*;
public class GUITest
{
public static void main(String[] args)
{
int gridx, gridy, gridwidth, gridheight, anchor, fill, ipadx, ipady;
double weightx, weighty;
Insets insets;
JFrame frm = new JFrame("Frame with Controls");
GridBagLayout gb = new GridBagLayout();
GridBagConstraints c;
frm.getContentPane().setLayout(gb);
JButton[] btn = new JButton[5];
//Button 1
btn[0] = new JButton("Button 1");
gridx = 0; gridy = 0;
gridwidth = 1; gridheight = 1;
weightx = 10; weighty = 1;
anchor = GridBagConstraints.CENTER;
fill = GridBagConstraints.HORIZONTAL;
insets = new Insets(0, 0, 0, 0);
ipadx = 0; ipady = 0;
c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,weightx, weighty, anchor, fill, insets, ipadx, ipady);
gb.setConstraints(btn[0], c);
frm.add(btn[0]);
//Button 2
btn[1] = new JButton("Button 2");
gridx = 1; gridy = 0;
gridwidth = 2; gridheight = 1;
weightx = 1; weighty = 1;
anchor = GridBagConstraints.CENTER;
fill = GridBagConstraints.HORIZONTAL;
insets = new Insets(0, 0, 0, 0);
ipadx = 50; ipady = 0;
c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,weightx, weighty, anchor, fill, insets, ipadx, ipady);
gb.setConstraints(btn[1], c);
frm.add(btn[1]);
//Button 3
btn[2] = new JButton("Button 3");
gridx = 0; gridy = 1;
gridwidth = 1; gridheight = 1;
weightx = 1; weighty = 1;
anchor = GridBagConstraints.CENTER;
fill = GridBagConstraints.HORIZONTAL;
insets = new Insets(10, 0, 0, 0);
ipadx = 50; ipady = 0;
c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,weightx, weighty, anchor, fill, insets, ipadx, ipady);
gb.setConstraints(btn[2], c);
frm.add(btn[2]);
//Button 4
btn[3] = new JButton("Button 4");
gridx = 1; gridy = 1;
gridwidth = 1; gridheight = 1;
weightx = 1; weighty = 1;
anchor = GridBagConstraints.CENTER;
fill = GridBagConstraints.HORIZONTAL;
insets = new Insets(0, 0, 0, 0);
ipadx = 0; ipady = 50;
c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,weightx, weighty, anchor, fill, insets, ipadx, ipady);
gb.setConstraints(btn[3], c);
frm.add(btn[3]);
//Button 5
btn[4] = new JButton("Button 5");
gridx = 2; gridy = 1;
gridwidth = 1; gridheight = 2;
weightx = 1; weighty = 1;
anchor = GridBagConstraints.SOUTH;
fill = GridBagConstraints.HORIZONTAL;
insets = new Insets(0, 0, 0, 0);
ipadx = 0; ipady = 0;
c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,weightx, weighty, anchor, fill, insets, ipadx, ipady);
gb.setConstraints(btn[4], c);
frm.add(btn[4]);
frm.setBounds(100, 100, 300, 300);
frm.setVisible(true);
}
}
七、javax.swing包中定义的布局管理器
在javax.swing包中又新定义了几个布局管理器,包括BoxLayout、OverlayLayout和SpringLayout布局管理器,以及内嵌在JScrollPane容器中的ScrollPaneLayout布局管理器,和
JViewport的默认布局管理器ViewportLayout。
BoxLayout布局
import javax.swing.*;
import java.awt.*;
public class GUITest
{
public static void main(String[] args)
{
int gridx, gridy, gridwidth, gridheight, anchor, fill, ipadx, ipady;
double weightx, weighty;
Insets insets;
JFrame frm = new JFrame("Frame with Controls");
Container cp=frm.getContentPane();
Box bBox=Box.createHorizontalBox();
cp.add(bBox);
Box vBox1=Box.createVerticalBox();
JLabel lb=new JLabel("这是一个标签!");
vBox1.add(lb);
JButton bt1=new JButton("这是一个按钮!");
bt1.setMaximumSize(new Dimension(100,200));
vBox1.add(bt1);
bBox.add(vBox1);
Box vBox2=Box.createVerticalBox();
bBox.add(vBox2);
JTextField tf1=new JTextField("这是文本框",10);
tf1.setAlignmentX(Component.CENTER_ALIGNMENT);
tf1.setMaximumSize(new Dimension(150,50));
vBox2.add(tf1);
Box vBox2h=Box.createHorizontalBox();
vBox2.add(vBox2h);
Box vBox2h1=Box.createVerticalBox();
vBox2h1.add(Box.createVerticalStrut(20));
vBox2h1.add(new JTextArea("这是文本区域"));
vBox2h1.add(Box.createVerticalStrut(20));
vBox2h1.add(new JTextArea("测试文本区域"));
vBox2h.add(vBox2h1);
Box vBox2h2=Box.createVerticalBox();
vBox2h2.add(new JButton("这是按钮2"));
vBox2h2.add(Box.createVerticalGlue());
vBox2h2.add(new JButton("这是按钮4"));
vBox2h.add(vBox2h2);
frm.setBounds(100, 100, 300, 300);
frm.setVisible(true);
}
}
八、无布局管理器
可用setLayout(null)设置布局管理器为空,即无布局管理器,然后用setLocation(),setSize(),setBounds()等方法人工设置每个组件的大小和位置,由于在设置中需要以屏幕
像素坐标为参照系,所以程序的显示结果将是设备相关的,也就是说当把这样的程序放到另外的显示设备的硬件配置不同的机器上运行时其界面显示效果很可能会发生变化。建议
用户尽量避免使用这种方法。
import javax.swing.*;
import java.awt.*;
public class GUITest
{
public static void main(String[] args)
{
int gridx, gridy, gridwidth, gridheight, anchor, fill, ipadx, ipady;
double weightx, weighty;
Insets insets;
JFrame frm = new JFrame("Frame with Controls");
Container cp=frm.getContentPane();
cp.setBackground(Color.RED);
cp.setLayout(null);
JButton jButton=new JButton("button");
cp.add(jButton);
jButton.setBounds(10,10,50,20);
JLabel jLabel=new JLabel("label");
cp.add(jLabel);
jLabel.setBounds(8,8,50,20);
frm.setBounds(100, 100, 300, 300);
frm.setVisible(true);
}
}
Java语言事件处理机制
一、事件处理机制
Java语言GUI界面通过事件处理机制实现人机交互。
事件是一种人机交互方式,操作界面上发生的物理动作都将导致事件的发生,事件是硬件对软件的驱动。
Java语言事件处理机制分为三个组成部分:事件源、事件对象和事件监听器。
发生事件的GUI组件就是事件源。
Java语言定义了很多事件类,每个操作界面上发生的事件都被认为是事件类的对象实例。
事件监听器是一些接口声明,在接口中声明了事件处理方法。
JDK 1.1版开始采用了事件监听器机制。
程序员如果想要在自己的程序中处理图形用户界面的事件就必须要做两件事:为可能产生事件的GUI组件注册一个事件监听器,在类中实现相应的监听器接口即实现监听器接口中声
明的与程序设计意图有关的方法成员。
当事件发生时,系统将调用注册的事件监听器的相应事件处理方法,从而把事件交付给事件处理方法去处理,从而完成对事件的处理过程。这就是Java语言的事件处理机制。
二、事件类与事件监听器接口
在Java API类库中,事件是以类的形式定义的,程序运行过程中发生的事件都被认为是相应的事件类的对象实例。
在java.awt.event包中定义了一些事件类及其对应的事件监听器接口,既适用于AWT组件又适用于Swing组件。
随着Swing组件的出现,JFC类库中又专门为其定义了事件类及其对应的事件监听器接口,存放在了javax.swing.event包中。
一个实现监听器接口的例子。
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GUIDemo7 implements
MouseMotionListener , MouseListener , WindowListener
{
private JFrame f;
JTextField tf;
public static void main(String args[])
{
GUIDemo7 demo = new GUIDemo7();
demo.go();
}
public void go()
{
f = new JFrame("三个监听器的实例");
JPanel container = new JPanel();
f.setContentPane(container);
container.setLayout(new BorderLayout());
tf = new JTextField(30);
container.add(new JLabel("单击并拖动鼠标") , BorderLayout.NORTH);
container.add(tf , BorderLayout.SOUTH);
f.addMouseListener(this);
f.addMouseMotionListener(this);
f.addWindowListener(this);
f.setSize(240 , 150);
f.setVisible(true);
}
public void mouseClicked(MouseEvent e){ }
public void mouseEntered(MouseEvent e)
{
String s = "鼠标进来了";
tf.setText(s);
}
public void mouseExited(MouseEvent e)
{
String s = "鼠标退出了";
tf.setText(s);
}
public void mousePressed(MouseEvent e){ }
public void mouseReleased(MouseEvent e){ }
public void mouseMoved(MouseEvent e){ }
public void mouseDragged(MouseEvent e)
{
String s = "鼠标拖动 :X="+e.getX()+"Y="+e.getY();
tf.setText(s);
}
public void windowActivated(WindowEvent e){ }
public void windowClosing(WindowEvent e)
{
System.exit(1);
}
public void windowClosed(WindowEvent e){ }
public void windowDeactivated(WindowEvent e){ }
public void windowDeiconified(WindowEvent e){ }
public void windowIconified(WindowEvent e){ }
public void windowOpened(WindowEvent e){ }
}
Java语言为含有1个以上方法的7个监听器接口定义了适配器类Adapter,这些适配器类实际上是对7个接口的实现类,其中将接口的方法成员实现为空方法体,这样当用户在程序中
使用事件机制时可以选择使用适配器类,只需继承适配器类并重写那些需要的方法。
组件的使用
一、组件的分类
Swing组件从功能上可以分成如下几类:
⒈顶层容器:即JFrame、JApplet、JDialog、JWindow等四个重量级组件,需要一个内容面板辅助。
⒉普通容器:使用在各种不同的情况下的中间容器,如JPanel、JScrollPane、JSplitPane、JTabbedPane等,一般可以被添加到顶层容器中。
⒊特殊容器:在GUI上起特殊作用的中间层容器,如JInternalFrame、JLayeredPane、JRootPane、JToolBar、JOptionPane等。
⒋基本控件:可以实现人机交互的组件,如JButton、JToggleButton、JRadioButton、JCheckBox、JComboBox、JList、JSlider、JScrollBar等,通常是界面上的主要角色。
⒌不可编辑信息显示:向用户显示不可编辑信息的组件,如JLabel、JProgressBar、JToolTip等,大多是起一个信息提示的作用。
⒍可编辑的格式化信息的显示:向用户显示能被编辑的格式化信息的组件,如JTable,JTree,JColorChooser和JFileChooser,用来实现用户与机器之间的信息交互工作。
其他一些具有专门用途的组件。
二、顶层框架JFrame
是一个特别常用的界面组件。
使用时需要先取得一个内容面板ContentPane,之后在内容面板上进行组件添加和布局管理。
通常用一个普通容器充当,或者是初始化之后用setContentPane()方法设为内容面板,或者是通过JFrame类的成员方法getContentPane()初始化。
构造方法
JFrame(String title)
新的JFrame对象是一个外部尺寸为0的不可见的组件,所以在程序中要用setSize()方法或pack()方法设定显示尺寸,用setVisible()方法将可见性设为真或用show()方法显示之。
在JFrame对象实例中可能发生窗口事件。
三、面板JPanel及普通容器
JPanel是其中最有代表性、最为常用的普通容器,它只是在界面上圈定一个矩形范围而无明显标记,主要的用途是作内容面板或者为了更好地实现布局效果而作为中间容器。
JPanel一般不处理事件。滚动窗口JScrollPane有专门的布局管理器ScrollPaneLayout,其外部尺寸按推荐尺寸定出,可以通过构造方法给出垂直和水平滚动条的大小,可查看大面
积区域。滚动窗口内部有一个可视点JViewport的对象,作为放置组件的底板。JViewport类提供一个可见视窗,它既可以放在JScrollPane中,也可以作为独立组件使用。
JViewport类有专门的布局管理器ViewportLayout。
一个分隔板JSplitPane对象包含一个分隔器和两个被分隔的组件,拖动分隔器可以改变两个组件对分隔板的分隔比例。可以定义水平或者垂直分隔方向,还可以指定左右两个组件
。选项板JTabbedPane是一个选项组件,由一组标签构成,每个标签代表一个组件,各个标签重叠在一起,每个标签有一个标题露出来供用户随意选择显示哪一个。
四、特殊容器
Swing组件中的JInternalFrame、JLayeredPane、JRootPane、JToolBar、JOptionPane等也是容器,但是与前面见到的容器有所不同,它们的使用往往带有特定的界面设计目的。
JInternalFrame是一种外形类似于JFrame的中间容器,可以被放到顶层窗口中构成嵌套的结构,可以在使用过程中最大化、最小化,使用时必须定义其尺寸大小,不必调用显示方
法。
分层面板JLayeredPane是支持分层布局的中间容器,其中的组件根据设计需要可以重叠放置,JLayeredPane没有默认的布局管理器。向JLayeredPane对象中添加组件时既要说明将
其加到哪一层,又要说明组件在该层中的位置。根面板JRootPane是四种重量级*容器JFrame、JApplet、JDialog、JWindow和内部框架JInternalFrame的基本组件,通常不必建
立一个JRootPane对象,而是在建立一个顶层窗口或内部框架时就得到了一个JRootPane对象。
工具栏JToolBar是一个在一行或一列上聚合多个组件的工具栏,通常是一些工具按钮。在一个容器中,用户可以将工具栏拖动到各个不同的边缘,甚至拖出容器。一般为了方便起
见,工具栏放在一个使用BorderLayout布局的容器中。
JOptionPane是一个使用十分灵活的对话框,可以在程序运行中方便地弹出要求用户提供值或向其发出通知的标准对话框,亦即这个组件既可以作为程序向用户输出信息的消息框,
又可以作为程序要求用户输入确认信息或简单输入的对话框。
五、基本控制组件
是使用数量较多的组件,GUI界面中,进行人机交互功能主要是靠这些组件完成的。
按钮JButton是最常见的组件。可以在其上加载文字标签、图像标签,还可以设置按钮的键盘操作方式或称快捷键。
切换按钮JToggleButton是一种具有两种状态的的按钮,当它打开时就像一个保持在按下状态的按钮,当它关闭时看上去便和一般的按钮一样了,JToggleButton也可以设置图像标
签和键盘操作方式。
单选钮JRadioButton和复选框JCheckBox是属于同一种功能类型的组件,分别用来完成单项选择和多项选择功能,同JButton一样,这两个组件也可以加载图像标签和键盘操作方式
。
组合框JComboBox可以看成是按钮或可编辑字段与下拉列表组合的组件。用户可以从下拉列表中选择值,下拉列表在用户请求时显示,其中含有一个可编辑选项,即当设为可编辑时
,用户可以从选择框上输入选项内容。
列表JList是提供多个选项给用户供选择。可以在其中设定单选或多选。
滑动条JSlider是一个带有尺寸刻度标记的组件,可以是用户在界面上通过滑动头选择需要的数值,可以用ChangeListener监听其上发生的变化事件ChangeEvent。
滚动条JscrollBar允许用户通过在滚动条内移动滑块确定显示区域中的内容,其外形就是常见的形态。
六、不可编辑信息显示组件
JLabel与AWT组件中的Label比较相象,都是为了在界面上设置一个提示性的文本,所不同的是JLabel除了可以显示文本之外还可以将图标设为其内容。
进程条JProgressBar可以反映某个操作的进行程度,通过图像来动态反映完成比例,以检测其进展,使用的时候需要在程序中用其setValue方法动态地将其当前值由最小值逐步变
为最大值。
工具提示JToolTip对象用来在组件上显示提示信息,使用时不必生成该类的对象实例,任何Swing组件都可以使用JComponent类的方法成员setToolTipText()定义和设置提示信息文
本,当鼠标停留在组件上面时,所设定的提示信息就自动弹出。
七、可编辑的格式化信息显示组件
JTable类提供了一个以表格形式显示数据的用户视图,并允许用户编辑其中的数据,可以通过在其上注册TableModelListener监听器监听。
JTree提供了一个用树形结构方式分层显示数据的视图,其中含有一个根结点,还含有两类结点:可以带子结点的分支结点,不能带任何结点的叶结点。JTree对象建立之后必须放
入滚动窗口。点击结点可以展开树的多层结构,这需要通过注册TreeSelectionListener监听器实现。
颜色选择器JColorChooser提供给用户一个可以选择颜色的对话界面,是一个对话框,允许用户在上面选择一种颜色。
文件选择器JFileChooser提供给用户一个可以选择文件的界面,通常以对话框的形式出现,便于用户在存取文件时使用。JFileChooser分“打开文件”和“保存文件”两种模式。
八、文本编辑类组件
单行文本JTextField类和普通文本JTextArea类是最普通的文本编辑框,可以设定为可编辑的和不可编辑的,在程序5.9中我们已经使用过。
密码文本JPasswordField类不反馈输入的具体内容,而只是用星号“*”代替输入的内容在框中显示。
格式化文本JFormattedTextField类可以识别普通文本、HTML文本、rtf文本,这种功能主要是通过EditorKit类完成。
编辑盘JEditorPane类可编辑各种内容的文本组件。文本盘JTextPane类可以用以图形方式表示的属性来标记的文本组件。
九、菜单相关组件
菜单是各种应用程序中使用的一种重要的人机交互工具,是一种既可以执行大量的交互任务又只需要很少的GUI界面使用面积的人机交互工具。
可以在Java语言程序中构建普通菜单与弹出菜单。
前者可以放到提供了setJMenuBar方法的容器中,这包括顶层容器JFrame、JApplet和JDialog,内部框架JInternalFrame和根面板JRootPane;后者可以添加到任一组件上。
与设计菜单有关的类有:
JMenuBar、JPopupMenu、JMenu、JMenuItem、JSeparator、JCheckBoxMenuItem、JRadioButtonMenuItem类等。
菜单项类JMenuItem是菜单结构的最后一层,描述了菜单中的具体功能,点击其对象实例时将产生一个动作事件ActionEvent。
单选按钮菜单项JRadioButtonMenuItem同样也要加入一个ButtonGroup实现相互关联,点击JCheckboxMenuItem将发生ItemEvent,可用ItemListener监听器处理。
JSeparator是在菜单上给出一条分隔线。
由于JMenuItem、JMenu、JCheckBoxMenuItem、JRadioButtonMenuItem等类都是AbstractButton类的子类,所以可以在其上设置图像标签和键盘操作方式。
十、显示效果控制类
⒈Color类
AWT组件和Swing组件都可以设置前景色和背景色,这都要用到Color类。前景色指的是组件上面的文字的颜色,背景色指的是组件表面的空白区的颜色。
⒉Font类
Font类提供字体供用户在设计界面时使用,可以设定显示字体、显示方式、大小。
⒊Icon接口
AbstractButton类的子类和JLabel类都可以加载图标。
实际编程的时候使用ImageIcon类,这是一个实现了Icon接口的类,可以用构造方法获取图标。
注意:滚动条作为一个不能独立使用的组件,一般要和其他组件结合才能有效的发挥功能,如给文本框、表格或者窗体添加滚动条,其中给窗体添加滚动条的做法是让窗体包含一
个具有滚动条的面板。
import javax.swing.*;
import java.awt.*;
public class exec
{
public static void main(String [] args)
{
JFrame f=new JFrame("Hello!");
f.setLocation(10,100);
f.setSize(600,400);
f.getContentPane().setLayout(new BorderLayout());
JPanel jp = new JPanel();
jp.setLayout(new GridLayout(20, 20));
for(int i = 0; i < 400; i++)
{
jp.add(new JButton("Button " + i));
}
int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
JScrollPane jsp = new JScrollPane(jp, v, h);
f.getContentPane().add(jsp, BorderLayout.CENTER);
f.setVisible(true);
}
}