十三、Swing绘图技术
JavaSE(十二)
--Swing绘图技术
一、Swing基础
图形用户界面(GUI)的历史:
JFrame:是一个顶层容器类(可以添加其它swing组件的类),默认布局方式是边界布局
①创建 JFrame jf=new JFrame(); ②设置标题 jf.setTitle("message"); ③设置大小 jf.setSize(200, 200);//不设置默认为0 ④设置初始位置 jf.setLocation(200, 200); //不设置则默认为(0,0),即为桌面左上角 ⑤设置关闭方式 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//一般设置为关闭窗口就停止程序 ⑥设置可视性 jf.setVisible(true);//不设置默认为false,即看不见。 ⑦设置图标 jf.setIconImage((new ImageIcon("images\\2.jpg").getImage()));
//更多设置请参阅帮助文档
窗口界面类开发流程:
①继承Jframe
②定义组件
③在构造函数中实例化定义的组件,添加实例化后的组件到容器中,设置窗口信息(标题、大小、位置、可视性、布局方式、关闭方式)
二、布局管理器
组件在容器(比如JFrame)的位置和大小是由布局管理器来决定的,所有的容器都会使用一个布局管理器,通过它来自动进行对组件地布局管理。
Java共提供了五种布局管理器:流式布局管理器(FlowLayout)、边界布局管理器(BorderLayout)、网格布局管理器(GridLayout)、卡片布局管理器(CardLayout)、网格包布局管理器(GridBagLayout)、前三种是最常见的布局管理器。
jf.setLayout(布局方式);//设置布局方式
1.边界布局(BorderLayout):
边界布局将容器简单的划分为东西南北中5个区域、中间区域最大。这是JFrame窗体、JDialog对话框组件默认布局方法。
默认的this.add(组件)只会将组件加载到中部,并且后面加的也会加载到中部,所以add 多个组件只会显示最后加的一个组件。如添加五个按钮(JButton("中部")、JButton("北部")、JButton("东部")、j4=new JButton("南部")、j5=new JButton("西部");):
默认添加:
this.add(j1); this.add(j2); this.add(j3); this.add(j4); this.add(j5);
应用边界布局添加:
this.add(j1,BorderLayout.CENTER); this.add(j2,BorderLayout.NORTH); this.add(j3,BorderLayout.EAST); this.add(j4,BorderLayout.SOUTH); this.add(j5,BorderLayout.WEST);
注意事项:
①不是五个部分都必须添加
②中部组件会自动调节大小(当一部分未添加,其接邻部分会吃过来,并自动调节)
2.流式布局(FlowLayout)
按照组件的添加次序将组件从左到右放置在容器中。当到达容器边界的时候,将组件放置在下一行中。FlowLayout可以左对齐、居中对齐(默认)、右对齐的方式排列组件
流式布局注意事项:
1.不限制他所管理的组件大小,允许他们有最佳大小(如果想不被布局管理器限制组件的改变,则设置jf.setLayout(null);)
2.当容器被缩放时,组件的位置可能发生变化,但组件的大小不变(即拖动窗口边缘改变窗口大小或最大化窗口的时候,组件位置发生相应调整)
3.默认的流式布局,组件是居中对齐,可以通过FlowLayout(int align)函数来指定对其方式,这样FlowLayout在居中排好组件后就会向你规定的对齐方向靠。
例子:
j1=new JButton("中部"); j2=new JButton("北部"); j3=new JButton("东部"); j4=new JButton("南部"); j5=new JButton("西部");
this.setLayout(new FlowLayout(FlowLayout.RIGHT));
this.add(j1);
this.add(j2);
this.add(j3);
this.add(j4);
this.add(j5);
this.setTitle("666");
this.setSize(300, 200);
this.setLocation(200, 200);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
运行结果:
3.网格布局
它将容器分割成多行多列,组件被填充到每个网格中,添加到容器的组件首先放置在左上角的网格中,然后从左到右放置其它的组件,当占满改行的所有网格后,接着在下一行从左到右放置组件
JButton jb[]=new JButton[9]; for(int i=0;i<9;i++){ jb[i]=new JButton(String.valueOf(i+1)); this.add(jb[i]); } this.setLayout(new GridLayout(3,3)); this.setTitle("666"); this.setSize(300, 200); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true);
网格布局注意事项:
1.组件的相对位置不随容器的缩放而变化,但大小会变化
2.所有组件的大小相同
3.可以通过(GridLayout(int rows,int cols,int hgap,int vgap))来指定网格的行数、列数、水平间隙、竖直间隙。
三、swing组件
Swing组件一览图:
常用组件(JPanel面板组件,JButton按钮,JLabel 标签 ,JTextField文本框,JPasswordField密码框,复选框组件JCheckBox,单选框组件JRadioButton,JSpliPane拆分窗格,JTextArea多行文本框组,JTabbedPane选项卡窗格,JMenuBar菜单条组件,JMenu菜单组件,JMenuItem菜单项组件,JToolBar容器类组件,JTabbedPane选项卡窗格)
① JPanel jPanel=new JPanel(); ② JButton jButton=new JButton("登录"); JButton jButton2=new JButton(new ImageIcon("images/head.png")); ③ JLabel jLabel=new JLabel("用户名:"); JLabel jLabel=new JLabel("用户名:",JLabel.CENTER); JLabel jLabel2=new JLabel(new ImageIcon("")); ④ JTextField jTextField=new JTextField(10); ⑤ JPasswordField jPasswordField=new JPasswordField(10); ⑥ jcb1=new JCheckBox("足球"); jcb2=new JCheckBox("篮球"); jcb3=new JCheckBox("网球"); 页面添加jcb1,jcb2,jcb3 ⑦ ButtonGroup bg=new ButtonGroup(); JRadioButton jrb1=new JRadioButton("男"); JRadioButton jrb2=new JRadioButton("女"); bg=new ButtonGroup(); bg.add(jrb1); bg.add(jrb2); 页面添加jrb1,jrb2 ⑧ String []words={"boy","girl","bird"}; jlist=new JList(words); ⑨ String[] jg={"北京","上海","江西","四川"}; jcb1=new JComboBox(jg); ⑩ JScrollPane jsp=new JScrollPane(jlist); jlist.setVisibleRowCount(3); 添加jsp ⑩① this.setJMenuBar(JMenuBar); JMenuBar-菜单条组件 树干 JMenu 菜单组件 树枝 JMenuItem 菜单项组件 树叶 JMenu里面可以嵌套JMenu JTabbedPane jtp=new JTabbedPane (); jtp.add("标题1",界面1); jtp.add("标题2",界面2); jtp.add("标题3",界面3);
1.面板组件(JPanel)
一个界面只可以有一个JFrame窗口组件,但可以有多个JPanel面板组件,而JPanel上也可使用各种布局管理器,这样组合使用可以达到较为复杂的布局效果
JPanel布局默认是FlowLayout。
①案例1,要达到一个这样的布局:
就可以使用JPanel,将按钮1按钮2放在一个面板1里(由于默认是流式布局,我们直接往面板里加入即可),将按钮4,按钮5,按钮6放在一个面板2里。再对面板1,面板2,按钮3进行边界布局即可。
public class Test3 extends JFrame{ JPanel jp1,jp2; JButton jb1,jb2,jb3,jb4,jb5,jb6; public static void main(String[] args) { new Test3(); } public Test3(){ //实例化组件 jp1=new JPanel(); jp2=new JPanel(); jb1=new JButton("关羽"); jb2=new JButton("张飞"); jb3=new JButton("赵云"); jb4=new JButton("马超"); jb5=new JButton("黄忠"); jb6=new JButton("刘备"); //将组件添加到JPanel jp1.add(jb1); jp1.add(jb2); jp2.add(jb3); jp2.add(jb4); jp2.add(jb5); this.add(jp1,BorderLayout.NORTH); this.add(jb6,BorderLayout.CENTER); this.add(jp2,BorderLayout.SOUTH); this.setTitle("666"); this.setSize(300, 200); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } }
②案例2,写一个类似QQ的登录界面
public class Test4 extends JFrame{ JPanel jp1,jp2,jp3; JLabel jlb1,jlb2; JButton jb1,jb2; JTextField jtf1; JPasswordField jtf2; public Test4(){ jp1=new JPanel(); jp2=new JPanel(); jp3=new JPanel(); jlb1=new JLabel("用户名:"); jlb2=new JLabel("密 码:"); jb1=new JButton("登录"); jb2=new JButton("取消"); jtf1=new JTextField(10); jtf2=new JPasswordField(10); this.setLayout(new GridLayout(3,1)); jp1.add(jlb1); jp1.add(jtf1); jp2.add(jlb2); jp2.add(jtf2); jp3.add(jb1); jp3.add(jb2); this.add(jp1); this.add(jp2); this.add(jp3); this.setTitle("666"); this.setSize(300, 200); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new Test4(); } }
③案例3,写一个拥有单选框和复选框的注册界面
public class Test5 extends JFrame{ JPanel jp1,jp2,jp3; JLabel jl1,jl2; JButton jb1,jb2; JCheckBox jcb1,jcb2,jcb3; JRadioButton jrb1,jrb2; ButtonGroup bg; public Test5(){ // TODO 自动生成的构造函数存根 jp1=new JPanel(); jp2=new JPanel(); jp3=new JPanel(); jl1=new JLabel("你喜欢的运动"); jl2=new JLabel("你的性别"); jb1=new JButton("注册"); jb2=new JButton("取消"); jcb1=new JCheckBox("足球"); jcb2=new JCheckBox("篮球"); jcb3=new JCheckBox("网球"); jrb1=new JRadioButton("男"); jrb2=new JRadioButton("女"); bg=new ButtonGroup(); bg.add(jrb1); bg.add(jrb2); this.setLayout(new GridLayout(3,1)); jp1.add(jl1); jp1.add(jcb1); jp1.add(jcb2); jp1.add(jcb3); jp2.add(jl2); jp2.add(jrb1); jp2.add(jrb2); jp3.add(jb1); jp3.add(jb2); this.add(jp1); this.add(jp2); this.add(jp3); this.setTitle("666"); this.setSize(300, 200); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new Test5(); } }
④显示下拉框和列表
public class Test6 extends JFrame{ JPanel jp1,jp2; JLabel jl1,jl2; JComboBox jcb1; JList jlist; JScrollPane jsp; public Test6() { // TODO 自动生成的构造函数存根 jp1=new JPanel(); jp2=new JPanel(); jl1=new JLabel("你的籍贯"); jl2=new JLabel("旅游地点"); String[] jg={"北京","上海","江西","四川"}; jcb1=new JComboBox(jg); String[] dd={"九寨沟","故宫","长城","天安门"}; jlist=new JList(dd); jsp=new JScrollPane(jlist); jlist.setVisibleRowCount(3); this.setLayout(new GridLayout(3,1)); jp1.add(jl1); jp1.add(jcb1); jp2.add(jl2); jp2.add(jsp); // jp2.add(jlist); add(jp1); add(jp2); this.setTitle("666"); this.setSize(300, 300); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new Test6(); } }
⑤案例5,利用拆分窗格制作类似于金山词霸界面
public class Test7 extends JFrame{ JSplitPane jsp; JList jlist; JLabel jl1; public Test7() { // TODO 自动生成的构造函数存根 String []words={"boy","girl","bird"}; jlist=new JList(words); jl1=new JLabel(new ImageIcon("images/1.jpg")); jsp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jlist,jl1); jsp.setOneTouchExpandable(true); //水平拆分窗口 this.add(jsp); this.setTitle("666"); this.setSize(480,350); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new Test7(); } }
⑥写一个QQ聊天界面
public class Test8 extends JFrame{ JTextArea jta=null; JPanel jp1=null; JComboBox jcb=null; JTextField jtf=null; JButton jb=null; JScrollPane jsp; public Test8() { // TODO 自动生成的构造函数存根 jta=new JTextArea(); jsp=new JScrollPane(jta); jp1=new JPanel(); String []chaters={"张三","李四","王五"}; jcb=new JComboBox(chaters); jtf=new JTextField(10); jb=new JButton("发送"); jp1.add(jcb); jp1.add(jtf); jp1.add(jb); this.add(jsp); this.add(jp1,BorderLayout.SOUTH); this.setSize(300, 200); this.setIconImage((new ImageIcon("images\\2.jpg").getImage())); setTitle("QQ聊天"); this.setLocation(200, 200); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new Test8(); } }
四、绘图技术
1.JPanel中有个paint()方法是用于绘画本界面的,我们一般继承JPanel,然后重写其paint方法.通过此方法来写自己所需要的界面
2.在以下情况下,paint函数将会被调用
①窗口大小发生改变
②repaint()函数被调用。
3.绘画详情参阅帮助文档