Java Swing 概述
在学习GUI编程时,必须要很好的理解和掌握两个概念,即容器类(Container)和组件类(Component)。
java.x swing包中的JComponent类是java.awt包中Container类的一个直接子类,
是java.awt包中Component类的一个间接子类。
学习GUI编程主要是学习使用Component类的一些重要的子类。以下是GUI编程经常提到的基本知识点。
- Java把Component类的子类或间接子类创建的对象成为一个组件。
- Java把Container的子类或间接子类创建的对象成为一个容器。
- 可以向容器添加组件。Contianer类提供一个public方法。add()。容器可以调用这个方法把组件添加到容器中。
- 容器调用*removeAll()方法可以移掉容器中的全部组件:调用remove(Component c)*方法可以 移掉容器中参数c指定的组件。
- 容器本身也是一个组件,因此可以把一个容器添加到另一个容器中实现容器的嵌套
- 每当容器添加新的组件或移除组件时,应当让容器调用*validate()*方法,以保证容器中的组件能正确的显示出来。
窗口
Java提供JFrame类的实例也是一个底层容器,即通常所说的窗口。
JFrame类是Contianer类的间接子类。
当需要一个窗口时,可以使用JFrame或其子类创建一个对象。
窗口也是一个容器,可以向窗口添加组件。
需要注意的是,不允许将窗口添加到另个一容器中。
下面介绍JFrame类常用方法
- JFrame():创建一个无标题的窗口。
- JFrame(String s):创建一个标题为s的窗口。
- public void setBounds(int a,int b,int width,int height):设置窗口的初始位置是,距离屏幕左边a个像素,距离屏幕上方b个像素;窗口的宽是width,窗口的高是height。
- public void setSize(int width,int height):设置窗口的大小。
- public void setLocation(int a,int b):设置窗口的位置。默认位置为(0,0)。
- public void setVisible(boolean b):设置窗口是否可见,默认窗口不可见
- public void setResizable(boolean b):设置窗口是否可调整大小。默认可调整大小。
- public void dispose():撤销当前窗口,并释放当前窗口所使用的资源。
- public void setExtendedState(int state) :设置窗口的拓展状态。其中,state取JFrame类中的类常量 MAXIMIZED_HOEIZ(垂直方向最大化),MAXIMIZED_VERT(水平方向最大化),MAXIMIZED_BOTH(水平,垂直方向都最大化)
- public void setDefaultCloseOperation(int operation):该方法用来设置单机窗体右上角的关闭图标后,程序会给出怎样的处理。其中,参数operation取JFrame类中的int型static常量DO_NOTHING_ON_CLOSE(什么也不做),HIDE_ON_CLOSE(隐藏当前窗口),DISPOSE_ON_CLOSE(隐藏当前窗口并释放窗体占有的其他资源),EXIT_ON_CLOSE(结束窗口所在的应用程序)
下面来演示一下功能:
import javax.swing.JFrame;
public class project01 {
public static void main(String[] args) {
JFrame win1=new JFrame();//创建一个没有标题的窗口
JFrame win2=new JFrame("第二个窗口");//创建一个有标题的窗口
win1.setBounds(100, 100, 200,200);//设置第一个窗口的位置及大小
win2.setLocation(500, 500);//设置第二个窗口的位置
win2.setSize(150, 150);//设置第二个窗口的大小
win1.setVisible(true);//设置第一个窗口可见。
win2.setVisible(true);//注释此行,运行程序,第二个窗口不可见。因为窗口默认不可见
win1.setResizable(false);//设置第一个窗口不可调节大小,但是,第二个可以,因为默认可调节大小
win1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//关闭按钮失效
win2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
可以自己更改参数,调试功能。
下面介绍菜单条,菜单,菜单项。
1.菜单条,菜单,菜单项是出口常用的组件,菜单放在菜单条里,菜单项放在菜单里。
2.JComponent类的子类JMenubar负责创建菜单条,即JMenubar的一个实例就是一个菜单条。JFrame有一个将菜单条放到窗口中的方法,不过只能向窗口添加一个菜单条。setJMenuBar(JMenuBar bar);
3.JComponent类的子类JMenu负责创建菜单,即JMenu的一个实例就是一个菜单。
4.JComponent类的子类JMenuItem负责创建菜单项,即JMenuItem的一个实例就是一个菜单项。
5.JMenu是JMenuItem的子类,因此,菜单也是一个菜单项,当把菜单看作一个菜单项添加到菜单中,这样的菜单成为子菜单。
6.为了使菜单项有一个图标,可以使用图标类Icon声明一个图标,然后用其子类创建一个图标,接着用菜单项调用setIcon(Icon icon)方法将图标设置为icon。
public class project01 {
public static void main(String[] args) {
WindowMenu win=new WindowMenu("带菜单的窗口", 20, 30, 200, 200);
}
}
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import static javax.swing.JFrame.*;
import javax.swing.*;
public class WindowMenu extends JFrame{
//对象的声明
JMenuBar menubar;//菜单条
JMenu menu,submenu;//菜单及子菜单
JMenuItem item1,item2;//菜单项
public WindowMenu() {//创建无参构造方法
}
public WindowMenu(String s,int x,int y,int w,int h) {//创建带参构造方法
init(s);
setLocation(x, y);//设置窗口的位置
setSize(w, h);//设置窗口的大小
setVisible(true);//设置窗口为可见的
setDefaultCloseOperation(DISPOSE_ON_CLOSE);//隐藏当前窗口并释放窗体占有的其他资源
}
void init(String s) {
setTitle(s);//设置窗户的标题
//为对象分配变量
menubar=new JMenuBar();
menu=new JMenu("菜单");
submenu=new JMenu("子菜单");
item1=new JMenuItem("菜单项1",new ImageIcon("a.gif"));
item2=new JMenuItem("菜单项2",new ImageIcon("b.gif"));
menu.add(item1);//将菜单项1添加到菜单中
menu.addSeparator();//添加分割线
menu.add(item2);//将菜单项2添加到菜单中
menu.add(submenu);//将子菜单添加到菜单中
submenu.add(new JMenuItem("子菜单里的菜单项",new ImageIcon("c.gif")));//新建一个菜单项添加到子菜单中
menubar.add(menu);//将菜单添加到菜单条中
setJMenuBar(menubar);//将菜单条放到窗口中
}
}
常用容器,组件和布局
常用组件
- 文本框 使用JTextField类创建文本框,允许用户在文本框输入单行文本。
- 文本区 使用JTextArea类创建文本区,允许用户在文本区输入多行文本。
- 按钮 使用JButton类创建按钮,允许用户单击按钮。
- 标签 使用JLabel类创建标签,标签为用户提供信息提示。
- 复选框 使用JCheckBox类创建复选框,为用户提供多项选择。复选框右边有一个名字,并提供了两种状态,选中与未选中,单击该组件可切换状态。
- 单选按钮 与复选框相似,不同的是,只能在一组单选按钮中选择一个,必须单击同组的其他单选按钮来切换当前状态。
- 下拉列表 使用JComboBox类创建下拉列表,为用户提供单项选择。
- 密码框 可以使用JPasswordField类创建密码框。允许用户在密码行中输入单行密码。默认回显字符是‘*’。可以使用setEchoChar(char c)重新设置回显字符。调用char[] getPassword()方法返回输入的密码。
package swing;
import javax.swing.JFrame;
public class demo {
public static void main(String[] args) {
ComponentInWindow win=new ComponentInWindow();
win.setBounds(100,100,300,300);
win.setTitle("常用组件");
}
}
package swing;
import java.awt.*;
import javax.swing.*;
public class ComponentInWindow extends JFrame{
//声明对象
JTextField text;//声明文本框
JButton button;//声明按钮
JCheckBox checkBox1,checkBox2,checkBox3;//声明复选框
JRadioButton radio1,radio2;//声明单选按钮
ButtonGroup group;//声明单选按钮的组
JComboBox<String>comBox;//声明下拉列表
JTextArea area;//声明文本区
public ComponentInWindow() {//创建无参构造方法
init();
setVisible(true);//设置窗口是可见的
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout());//布局,详解见下面。
JLabel biaoqian=new JLabel("文本框");//创建标签
add(biaoqian);//将标签加入到窗口
text=new JTextField(10);//为声明的对象分配变量
add(text);//将文本框加入到窗口,
button=new JButton("确定");//为声明的对象分配变量
add(button);//将按钮加入到窗口
checkBox1=new JCheckBox("喜欢音乐");//为声明的对象分配变量
checkBox2=new JCheckBox("喜欢旅游");//为声明的对象分配变量
checkBox3=new JCheckBox("喜欢篮球");//为声明的对象分配变量
add(checkBox1);//将复选框加入到窗口
add(checkBox2);//将复选框加入到窗口
add(checkBox3);//将复选框加入到窗口
group=new ButtonGroup();//为声明的对象分配变量
radio1=new JRadioButton("帅哥");//为声明的对象分配变量
radio2=new JRadioButton("美女");//为声明的对象分配变量
group.add(radio1);//将单选按钮加入到组
group.add(radio2);//将单选按钮加入到组
add(radio1);//将单选按钮加入到窗口
add(radio2);//将单选按钮加入到窗口
comBox=new JComboBox<String>();//为声明的对象分配变量
comBox.addItem("音乐天地");//添加下拉列表的选项
comBox.addItem("武术天地");//添加下拉列表的选项
comBox.addItem("象棋天地");//添加下拉列表的选项
add(comBox);//将下拉列表加入到窗口
area=new JTextArea(6,12);//为声明的对象分配变量
add(new JScrollPane(area));//当组件内容大于显示区域时会自动产生滚动轴
}
}
常用容器
JComponent是Contianer的子类,因此,JComponent子类创建的对象也都是容器。中间容器必须被添加到底层容器中才能发挥作用。
- JPanel面板。使用JPanel先创建一个面板,再向面板中添加组件,然后吧面板加到其他容器中。默认布局是FlowLayout布局。
- 滚动窗格。 只能添加一个组件。JScrollPane()
- 拆分窗格。将容器拆分为上下或者左右两部分。拆分线可移动。JSplitPane(int a,Component b,Component c)参数a决定是水平分还是垂直分。JSplitPane(int a,boolean b,Component c,Component d)参数b决定当拆分线移动时组件是否连续变化。
- 分层窗格。
- 选项卡窗格。JTabbedPane属于中间容器。一个组件对应一个选项卡,选项卡层叠式的放入JTabbedPane容器中。add(String s,Component c);将组件c加到选项卡窗格中并指定文本提示s。可以用构造方法创建选项卡窗格。public JTabbedPane(int tabbedPane)
常用布局
-
FlowLayout布局。
FlowLayout()该构造方法可以创建一个居中对齐的布局对象。组件之间的默认水平和垂直间隙是5像素,为最佳大小,如果需要更改最佳大小,需调用public void setPreferredSize(Dimension preferredSize);
FlowLayout布局对象调用setAlignment(int aligin)方法可以重新设置布局的对称方式。其中aligin可以取FlowLayout.LEFT,FlowLayout.CENTER,FlowLayout.RIGHT.
FlowLayout布局对象调用setHgap(int hgap)方法和setVgap(int vgap),可以重新设置水平间隙和垂直间隙。 -
BorderLayout布局。
BorderLayout布局是window型容器的默认布局,容器空间被简单地分为东,西,南,北,中5个区域,中间区域最大。加入组件应指定区域且一个区域只能放一个组件。如果放了多个组件,那么后放入的替换先放入的。 -
CardLayout布局。
可以容纳多个组件,组件被层叠的放在容器中,最先放入的在最上面。特点是同一时刻只能从容器中选出一个来显示。
容器调用add(String s,Component c)将组件c加入容器,并给出了显示该组件的代号s。
布局用CardLayout类提供的show()方法显示容器中代号为s的组件。show(c,s) -
GridLayout布局。
把容器分成若干行和若干列的网格区域。使用GridLayout的构造方法GridLayout(int m,int n)
创建布局对象,指定划分网格的行数m和列数n。
package gridlayout;
public class work104 {
public static void main(String[] args) {
new ShowLayout();
}
}
package gridlayout;
import java.awt.*;
import javax.swing.*;
public class ShowLayout extends JFrame {
//声明对象
PanelGridLayout panelGrid;
PanelNullLayout panelNull;
JTabbedPane tabbedPane;
ShowLayout(){
//为对象分配变量
panelGrid=new PanelGridLayout();
panelNull=new PanelNullLayout();
tabbedPane=new JTabbedPane();
tabbedPane.add("网格布局的面板",panelGrid);
tabbedPane.add("空布局的面板",panelNull);
add(tabbedPane,BorderLayout.CENTER);
add(new JButton("窗体是BorderLayout布局"),BorderLayout.NORTH);
add(new JButton("南"),BorderLayout.SOUTH);
add(new JButton("西"),BorderLayout.WEST);
add(new JButton("东"),BorderLayout.EAST);
setBounds(10, 10,570, 390);//设置窗口的大小及位置
setVisible(true);//设置窗口是可见的
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
validate();
}
}
package gridlayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Label;
import javax.swing.JPanel;
public class PanelGridLayout extends JPanel {
PanelGridLayout(){
GridLayout grid=new GridLayout(12,12);//创建12行12列的GridLayout布局对象
setLayout(grid);//设置布局为GridLayout布局
Label label[][]=new Label[12][12];//创建12*12的label组件数组
for(int i=0;i<12;i++) {
for(int j=0;j<12;j++) {
label[i][j]=new Label();
if((i+j)%2==0) {
label[i][j].setBackground(Color.black);//设置颜色是黑色
}
else {
label[i][j].setBackground(Color.white);//设置颜色是白色
}
add(label[i][j]);//添加组件
}
}
}
}
package gridlayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class PanelNullLayout extends JPanel {
JButton button;//声明一个按钮
JTextField text;//声明一个文本框
public PanelNullLayout() {
setLayout(null);//设置空布局
button=new JButton("确定");//为对象分配变量
text=new JTextField();//为对象分配变量
add(text);//将文本框添加到窗口
add(button);//将按钮添加到窗口
text.setBounds(100, 30, 90,30);//设置文本框的位置及大小
button.setBounds(190,30, 66, 30);//设置按钮的位置及大小
}
}
- BoxLayout布局。
用BoxLayout类可以创建一个布局对象,成为盒式布局。Java.swing包中提供了Box类,该类是Contianer的子类,创建的容器成为盒式容器,默认布局时盒式布局,而且不允许更改盒式容器的布局。
使用盒式布局吧组件排列在一行或者一列。组件再多也不会延申到下一行。使用BoxLayout的构造方法BoxLayout(Container con,int axis)axis的有效值是
BoxLayout.X_AXIS,BoxLayout.Y_AXIS。
如果需要一个盒式布局的容器可以使用Box的类方法createVerticalBox();获得一个具有行型盒式布局的容器,可以使用Box的类方法createHorizontalBox();获得一个具有列型盒式布局的容器。
如果想要控制盒式布局容器的组件之间的距离,需要使用水平支撑组件或垂直支撑组件。Box的静态方法createVerticalStrut(int height)可以得到一个不可见的垂直Strut对象,成为垂直支撑。Box的静态方法createHorizontalStrut(int width)可以得到一个不可见的水平Strut对象,成为水平支撑。
package work_105;
public class work05 {
public static void main(String[] args) {
WindowBoxLayout win=new WindowBoxLayout();
win.setBounds(100, 100, 310, 210);
win.setTitle("嵌套盒式布局容器");
}
}
package work_105;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class WindowBoxLayout extends JFrame {
Box baseBox,boxV1,boxV2;//创建三个盒式容器。
public WindowBoxLayout() {
setLayout(new java.awt.FlowLayout());//设置为FlowLayout布局
init();
setVisible(true);//设置窗口可见
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
boxV1=Box.createVerticalBox();//boxV1是一个具有列型盒式布局的盒式容器
boxV1.add(new JLabel("姓名"));//向boxV1中添加标签
boxV1.add(Box.createVerticalStrut(8));//添加一个高度为8的垂直支撑。
boxV1.add(new JLabel("e_mail"));//向boxV1中添加标签
boxV1.add(Box.createVerticalStrut(8));//添加一个高度为8的垂直支撑。
boxV1.add(new JLabel("职业"));//向boxV1中添加标签
boxV2=Box.createVerticalBox();//boxV2是一个具有列型盒式布局的盒式容器
boxV2.add(new JTextField(10));//向boxV2中添加文本框
boxV2.add(Box.createVerticalStrut(8));//添加一个高度为8的垂直支撑。
boxV2.add(new JTextField(10));//向boxV2中添加文本框
boxV2.add(Box.createVerticalStrut(8));//添加一个高度为8的垂直支撑。
boxV2.add(new JTextField(10));//向boxV2中添加文本框
baseBox=Box.createHorizontalBox();//baseBox是一个具有行型盒式布局的盒式容器。
baseBox.add(boxV1);//将boxV1放到baseBox里
baseBox.add(Box.createHorizontalStrut(10));//添加一个宽度为10的水平支撑。
baseBox.add(boxV2);//将boxV2放到baseBox里
add(baseBox);//将baseBox放到窗口中。
}
}
- null布局。向空布局的容器p中添加一个组件c需要两步。
p.setLayout(null);//设置空布局。
p.add(c);//添加组件c。
c.setBounds(int a,int b,int width,int height);//设置组件c的大小。