欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java 图形程序设计(GUI)

程序员文章站 2022-04-11 17:49:00
...
GUI(Graphical User Interface) 图形用户界面    
在java刚出现的时候,包含了一个用于基本GUI程序设计的类库。Sun将他称为抽象窗口工具箱(Abstract Window ToolKit,awt)。基本awt库采用将处理用户界面元素的任务委派给每个目标平台(Window,Solaris,Macintosh等)的本地GUI工具箱的方式,由本地GUI工具箱负责用户界面元素的创建和动作。例如,如果使用最初的AWT在Java窗口中放置一个文本框,就会有一个低层的对等体文本框,用来真正的处理文本输入。从理论上来说,结果程序可以运行在任何平台上,但是观感(look and feel)的效果却依赖于目标平台,因此,Sun公司的口号是:一次编写,随处使用 对于简单的应用程序来说,基于对等体方法的效果还是不错的,但是要想编写依赖于本地用户界面元素的高质量、可移植可图形库就会暴露出一些缺陷。例如:菜单,滚动条和文本域这些用户界面元素,在不同的平台上,操作行为存在一些微妙的区别,因此,有些图形环境(如X11/Motif)并没有像Windows或者Macintosh这样丰富的用户界面组件集合。这也就将基于对等体的可移植库限制在了“最小公分母”的范围内。其结果使AWT构建的GUI应用程序看起来没有Windows或者Macintosh那么漂亮,也没有提供哪些平台用户所认知的功能。更糟糕的是,在不同平台上的AWT用户界面库中存在不同的bug。研发人员必须在每一个平台上测试应用程序。 后来,Netscape创建了一种称为IFC(Internet Foundation Class)的GUI库,它采用了与AWT完全不同的工作方式,他将按钮,菜单这样的用户界面元素绘制在空白窗口上,而对等*需要创建和绘制窗口。因此,Netscape的IFC组件在程序运行的所有平台上的外观和动作都一样。Sun与Netscape合作创建了一个名为Swing的用户界面库 Swing没有完全代替AWT,而是基于AWT的架构之上。Swing仅仅提供了能力更强大的用户界面组件。尤其在采用Swing编写的程序中,还需要使用基本的AWT处理时间。从现在开始,Swing是指被绘制的用户界面类,AWT是指向事件处理这样的窗口工具箱的底层机制 创建框架 —- 在java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame)在AWT库中,有一个称为Frame的类,用于描述顶层窗口,这个类的Swing版本名为JFrame,他扩展于Frame类,JFrame是极少数几个不绘制在画布上的Swing组建之一。因此,他的修士部件)如按钮,标题栏,图标等)由用户的窗口系统绘制,而不是由Swing绘制。 绝大多数Swing组件类都以J开头,例如JButton,JFrame等。在Java中,有Button和Frame这样的类,但是他们属于AWT组件。如果偶然的忘记了书写J,程序仍然可以进行编译和运行,但是将Swing和AWT组件混合在一起使用将会导致视觉和行为的不一致 以下将介绍有关Swing的JFrame常用方法。
java.awt
Class EventQueue

java.lang.Object
java.awt.EventQueue

public class EventQueue
extends Object
EventQueue是一个独立于平台的类,用于从底层对等类和可信应用程序类排队事件。
它封装了从队列中提取事件,并通过调用调度它们异步事件指派机制dispatchEvent(AWTEvent)这种方法EventQueue与该事件被分派作为参数。 这种机器的特殊行为是依赖于实现的。 唯一的要求是实际排队到这个队列的事件(注意,发布到EventQueue事件可以合并)被调度:
package NEW_DATE_SEQUENCE_PACKAGE;
import java.awt.*;
import javax.swing.*;
/**
 *
 * @author cmx
 */
public class J_9_1_6_swing 
{
    public static void main(String [] args)
    {
        EventQueue.invokeLater(()->
        {
            SimpleFrame3 a=new SimpleFrame3();
            a.setVisible(true);
            a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        });
    }
}
class SimpleFrame3 extends JFrame
{
    private static final int DEFAULT_WIDTH=300;
    private static final int DEFAULT_HIGHT=200;
    public SimpleFrame3()
    {
        setSize(DEFAULT_WIDTH,DEFAULT_HIGHT);
    }
}
运行结果:一个空白的窗口 框架定位 —- JFrame类本身只包含若干个改变框架外观的方法。当然,通过继承,从JFrame的超类中继承了很多用于处理框架大小和位置的方法。其中最重要的有下面几个: setLocation和setBounds方法用于设置框架的位置
setLocation

public void setLocation(int x,
                        int y)
将组件移到新位置。通过此组件父级坐标空间中的 x 和 y 参数来指定新位置的左上角。
参数:
x - 父级坐标空间中新位置左上角的 x 坐标
y - 父级坐标空间中新位置左上角的 y 坐标
从以下版本开始:
JDK1.1
=============
setBounds

public void setBounds(int x,
                      int y,
                      int width,
                      int height)
移动组件并调整其大小。由 x 和 y 指定左上角的新位置,由 width 和 height 指定新的大小。
参数:
x - 组件的新 x 坐标
y - 组件的新 y 坐标
width - 组件的新 width
height - 组件的新 height
从以下版本开始:
JDK1.1
setIconImage用于告诉窗口系统在标题栏、任务切换窗口等位置显示那个图标
setIconImage

public void setIconImage(Image image)
设置要作为此窗口图标显示的图像。
将单个图像指定为窗口的图标时,可以使用此方法代替 setIconImages()。

以下语句:

     setIconImage(image);

等价于:
     ArrayList imageList = new ArrayList();
     imageList.add(image);
     setIconImages(imageList);

注:根据上下文的不同(例如,窗口装饰、窗口列表、任务栏等),本机窗口系统可以使用不同尺寸的不同图像表示一个窗口。也可以对所有上下文使用一个图像,或者根本不用图像。

覆盖:
类 Frame 中的 setIconImage
参数:
image - 要显示的图标图像。
setTitle 用于改变标题栏的文字
setTitle

public void setTitle(String title)
将此窗体的标题设置为指定的字符串。
参数:
title - 要显示在窗体边框中的标题。 null 值视为空字符串 ""
setResizable 利用一个boolean值确定框架的大小是否允许用户改变
setResizable

public void setResizable(boolean resizable)
设置此窗体是否可由用户调整大小。
参数:
resizable - 如果此窗体是可调整大小的,则为 true;否则为 false
JFrame继承框架:
javax.swing 
类 JFrame

java.lang.Object
  继承者 java.awt.Component
      继承者 java.awt.Container
          继承者 java.awt.Window
              继承者 java.awt.Frame
                  继承者 javax.swing.JFrame
JPanel继承框架
javax.swing 
类 JPanel

java.lang.Object
  继承者 java.awt.Component
      继承者 java.awt.Container
          继承者 javax.swing.JComponent
              继承者 javax.swing.JPanel
对于Component类和window类(是Frame的超类)要仔细研究,从中找到缩放和改变框架的方法。例如:在Component类中的setLocation方法是重定位组建的一个方法。 如果调用setLocation(x,y) 则将窗口放置在左上角水平x像素,垂直y像素的位置。坐标(0,0)位于屏幕的左上角。同样的,Component中的setBounds方法可以实现一步重定位组件,
setBounds(x,y,width,height)
可以让窗口系统控制窗口的位置,如果在显示串口之前调用
setLocationByPlatform (true);
窗口系统会选用窗口的位置(而不是大小),通常是距离最后一个显示窗口最小偏移量的位置。 对于框架来说,setLocation和setBounds中的坐标均相对于整个屏幕。 在容器中包含的组件所指的坐标均相对于容器。 **框架属性** 组件类的很多方法是以获取/设置方法对形式出现的,例如:Frame类的下列方法:
public String getTitle();
public void setTitle(String title);
这样的一个获取/设置方法对就被称为一种属性。属性中包含属性名和类型。将get或者set之后的第一个字母改为小写字母就可以得到相应的属性名。例如:Frame类有一个名为title且类型为String的属性。 从概念上讲,title是框架的一个属性,当设置这个属性的时候,我们不关心如何实现这个属性。 针对get/set约定由一个例外:对于类型为boolean的属性,获取方法由is开头。例如:下面两个方法定义了locationByPlatform属性:
public boolean isLocationByPlatform();
public void setLocationByPlatform();
=======================
isLocationByPlatform

public boolean isLocationByPlatform()
如果此窗口下次可见时,出现在本机窗口操作系统的默认位置,则返回 true。如果窗口显示在屏幕上,则此方法始终返回 false。
返回:
此窗口是否将出现在默认位置

==========================
setLocationByPlatform

public void setLocationByPlatform(boolean locationByPlatform)
设置窗口下次可见时应该出现的位置:本机窗口系统的默认位置,还是当前位置(由 getLocation 返回)。此行为模拟显示的本机窗口,而不是以编程方式设置其位置。如果未显式设置窗口的位置,那么大多数窗口操作系统将重叠显示窗口。一旦窗口显示在屏幕上,其实际位置就被确定
确定合适的框架大小 ——— 要记住:如果没有明确的指定框架的大小,所有框架的默认值为0*0像素,为了让示例程序尽可能的简单,这里将框架的大小重置为大多数情况下都可以接受的显式尺寸。然而,对于专业应用程序来说,应该检查屏幕的分辨率,并根据其分辨率编写代码重置框架的大小,如在微型电脑的屏幕上,正常显示的窗口在高分辨率屏幕上可能变为一张邮票的大小。 为了得到屏幕的大小,需要按照下列步骤操作。调用Toolkit类的静态方法getDefaultToolkit得到一个Toolkit对象(Toolkit类包含许多与本地窗口系统打交道的方法)。然后,调用getScreenSize方法,这个方法以Dimension对象的形式返回屏幕的大小,Dimension对象同时用公有实例变量width和height保存着屏幕的宽度和高度。下面是相关的代码:
package NEW_DATE_SEQUENCE_PACKAGE;
import java.awt.*;
import javax.swing.*;
/**
 *
 * @author cmx
 */
public class J_9_1_6_swing 
{
    public static void main(String [] args)
    {
        EventQueue.invokeLater(()->
        {
            SimpleFrame3 a=new SimpleFrame3();
            a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            Toolkit kit= Toolkit.getDefaultToolkit();
            Dimension screenSize=kit.getScreenSize();
            int screenWidth=screenSize.width;
            int screenHeight=screenSize.height;
            /**
             * 下面,将框架大小设置为上面取值得50%,然后,告知窗口系统定位框架
             */

            a.setSize(screenWidth/2,screenHeight/2);
            a.setLocationByPlatform((true));
            a.setVisible(true);
        });
    }
}
class SimpleFrame3 extends JFrame
{
    private static final int DEFAULT_WIDTH=300;
    private static final int DEFAULT_HIGHT=200;
    public SimpleFrame3()
    {
        setSize(DEFAULT_WIDTH,DEFAULT_HIGHT);
    }
}
另外,还提供了一个图标,由于图像的描述与系统有关,所以需要再次使用工具箱加载图像。然后,将这个图像设置为框架的图标:
public abstract class Image


      extends 
      Object

抽象类 Image 是表示图形图像的所有类的超类。必须以特定于平台的方式获取图像。
对于不同的操作系统,所看到的图标显示位置可能不同。例如:在Windows中,图标显示在窗口的左上角,按下ALT+TAB,可以在活动任务的里表中看到相应程序的图标。 下面是为了处理框架给予的一些提示: 如果框架中只包含标准的组件,如按钮和文本框,那么通过调用pack方法设置框架大小。
pack

public void pack()
调整此窗口的大小,以适合其子组件的首选大小和布局。如果该窗口和/或其所有者还不可显示,则在计算首选大小之前都将变得可显示。在计算首选大小之后,将会验证该窗口。
框架将被设置为刚好能放下所有组件的大小。在通常情况下,将程序的主框架尺寸设置为最大,可以通过调用下面方法将框设置的最大。
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
//setExtendedState

public void setExtendedState(int state)
设置此窗体的状态。该状态表示为逐位掩码。


MAXIMIZED_BOTH
public static final int MAXIMIZED_BOTH
此状态位掩码指示将窗体完全最大化(水平和垂直方向)。它只是 MAXIMIZED_VERT | MAXIMIZED_HORIZ 的一种便捷别名。
牢记用户定位应用程序的框架位置、重置框架大小,并且在应用程序再次启动时恢复这些内容是一个不错的想法。
GraphicsDevice类还允许以全屏模式执行应用。

//
isFullScreenSupported

public boolean isFullScreenSupported()
如果此 GraphicsDevice 支持全屏独占模式,则返回 true。如果安装了 SecurityManager,则将使用 AWTPermission("fullScreenExclusive") 调用它的 checkPermission 方法。只有授权时 isFullScreenSupported 才会返回 true
ImageIcon

public ImageIcon(String filename)
根据指定的文件创建一个 ImageIcon。使用 MediaTracker 预载图像以监视图像的加载状态。指定 String 可以是一个文件名或是一条文件路径。在指定一条路径时,可使用 Internet 标准正斜杠 ("/") 作为分隔符。(该字符串被转换成一个 URL,而正斜杠适用于所有系统。)例如,指定:
    new ImageIcon("images/myImage.gif") 
================
    getImage

public Image getImage()
返回此图标的 Image。
================
setIconImage

public void setIconImage(Image image)
设置要作为此窗口图标显示的图像。
将单个图像指定为窗口的图标时,可以使用此方法代替 setIconImages()。

以下语句:

     setIconImage(image);

等价于:
     ArrayList imageList = new ArrayList();
     imageList.add(image);
     setIconImages(imageList);

注:根据上下文的不同(例如,窗口装饰、窗口列表、任务栏等),本机窗口系统可以使用不同尺寸的不同图像表示一个窗口。也可以对所有上下文使用一个图像,或者根本不用图像。

覆盖:
类 Frame 中的 setIconImage
参数:
image - 要显示的图标图像。

 

一、问题

ImageIcon icon = new ImageIcon(“a.gif”);

执行结果是icon无法显示

 

二、解决

 

类中有如下调用:

ImageIcon icon = new ImageIcon(“a.gif”);

 

很自然地认为当前类文件和图片在同一路径下即可。

其实所谓的相对路径起点是工程的根目录,即project

这行代码执行时在project目录下查找名为a.gif的文件,结果当然是找不到。

要得到工程的相对路径可通过System.getProperty(“user.dir”)得到。

对图片和对文件的查找应该是一致的,如new File()

假如你的工程根目录为:project1

你的图片文件放在:project1/src/images/a.gif

 

所以正确的调用是:

ImageIcon icon = new ImageIcon(“src//images//a.gif”);

这行代码执行时在project/test目录下查找到了文件

 

总结起来就是一句话:所谓相对路径就是相对于工程根目录的位置^_^

 

三、其他

查看了一下ImageIcon的构造函数。

Public ImageIcon(String filename)//参数可以是绝对路径也可以是相对路径

Public ImageIcon(URL url)

 

第一种构造不在赘述。

第二种通过URL来得到图片

URL url = getClass().getResource(“a.gif”); //当前编译后class文件所在目录查找

ImageIcon icon = new ImageIcon(url);

 

ImageIcon支持GIFJPGPNG等格式。

java.awt.Component
    boolean isVisible()
    void setVisible(boolean b)
    获取或者设置visible属性,组件最初是可见的,但是JFrame这样的顶层组件例外
    void setSize(int width, int height)
    使用给定的宽度和高度,重新设置组建的大小;
    void setLocation(int x ,int y)
    将组件移到一个新的位置上,如果这个组件不是顶层组件,x和y坐标(或者p.x和p.y)是容器坐标;否则是屏幕坐标
    void setBounds(int x,int y, int width, int height)
    移动并重新设置组件的大小
    Dimension getSize()
    void setSize(Dimension d)
    获取或者设置当前组件的size属性
java.awt.Window
    void toFront()
    将这个窗口显示的到其他窗口的前面
    void toBack()
    将这个窗口移到桌面窗口栈的后面,并相应的重新排列所有的可见窗口。
    boolean isLocationByPlatform()
    void setLocationByPlatform(boolean b);
    获取或者设置locationByPlatform属性。这个属性在窗口显示之前被设置,由平台选择一个合适的位置;
java.awt.Frame
    boolean isResizable()
    void setResizable(boolean b)
    获取或者设置resizable属性,这个属性设置后,用户可以重新设置框架的大小
    String getTitle()
    void setTitle(String s)
    获取或者设置title属性,这个属性确定框架标题栏中的文字
    Image getIconImage()
    void setIconImage(Image image)
    获取或者设置iconImage属性,这个属性确定框架的图标,窗口系统可能会将图表作为框架装饰或者其他部位的一部分显式。
    boolean isUndecorated()
    void setUndecorated(boolean b)
    获取或者设置undecorated属性,这个属性设置后,框架显式中将没有标题栏或关闭按钮这样的装饰。在框架显式之前,必须调用这个方法
    int getExtendedState()
    void setExtendedState(int state)
    获取或者设置窗口状态
java.awt.Toolkit
    static Toolkit getDefaultToolkit()
    返回默认的工具箱
    Dimension getScreenSize()
    返回用户屏幕的尺寸
java.swing.ImageIcon
    ImageIcon(String filename)
        构造一个图标,其图像存储在一个文件中
    Image getImage()
    获得该图标的图像。

在组件中显示信息

接下来将讨论如何在框架内显示信息。例如,我们不再像以前那样,采用文本方式在控制台窗口中显示信息。而是在框架中显示这个信息。
可以将消息字符串直接绘制在框架中,但这并不一定是一种很好的编程习惯。在Java中,框架被设计为放置组件的容器,可以将菜单栏和其他的用户界面元素放置在其中。在通常情况下,应该在另一组件上绘制信息,并将这个组件添加到框架中。
JFrame的结构相当复杂。在图中给出了JFrame的结构。可以看到,在JFrame中有四层面板,其中的根面板,层级面板,和玻璃面板我们不太关心,他们是用来组织菜单栏和内容窗格以及实现观感的。swing程序员最关心的是内容窗格(content pane)在设计框架的时候,要使用以下代码将所有的组件添加到内容窗格中:

                    getContentPane
javax.swing 
类 JFrame

java.lang.Object
  继承者 java.awt.Component
      继承者 java.awt.Container
          继承者 java.awt.Window
              继承者 java.awt.Frame
                  继承者 javax.swing.JFrame
getContentPane

public Container getContentPane()
返回此窗体的 contentPane 对象
指定者:
接口 RootPaneContainer 中的 getContentPane
返回:
contentPane 属性
                        Container
public class Container
 extends 
      Component
一般的 Abstract Window Toolkit(AWT) 容器对象是一个可包含其他 AWT 组件的组件。

添加到容器中的组件放在一个列表中。列表的顺序将定义组件在容器内的正向堆栈顺序。如果将组件添加到容器中时未指定索引,则该索引将被添加到列表尾部(此后它位于堆栈顺序的底部)。
java.awtContainer

java.lang.Object
  继承者 java.awt.Component
      继承者 java.awt.Container
=================
                        getPreferredSize

public Dimension getPreferredSize()
返回此容器的首选大小。如果尚未通过 Component.setPreferredSize(Dimension) 显式设置首选大小,并且此 Container 有一个 non-null LayoutManager,则使用 LayoutManager.preferredLayoutSize(Container) 来计算首选大小。
注:一些实现可能缓存从 LayoutManager 返回的值。每次调用此方法时,这些缓存实现不需要在 LayoutManager 上调用 preferredLayoutSize,而是只在 Container 变得无效之后查询 LayoutManager。

覆盖:
类 Component 中的 getPreferredSize
//代码
Container contentPane=frame.getContentPane();
Component c=...;
contentPane.add(c);

在java SE 中,JFrame类中的add方法抛出了一个异常信息“Do not use JFrame.add. Use JFrame.getContentPane().add instead.如今,JFrame.add方法不再显示这些提示信息,只是简单的调用内容窗格的add
因此,可以直接调用
frame.add(c);
在这里,打算将一个绘制消息的组件添加到框架中。绘制一个组件,需要定义一个扩展JComponent类,并覆盖其中的paintComponent方法
paintComponent方法有一个Graphics类型的参数,这个参数保存着用于绘制图像和文本的设置,例如,设置字体或者当前的颜色。在Java中,所有的绘制都必须使用Graphics对象,其中包含了绘制图案,图像和文本的方法。
Graphics参数与Windows中的设备环境或者X11程序设计中的图形环境基本相似.
有些程序员更喜欢扩展JPanel,而不是JComponent。JPanel是一个可以包含其他组建的容器(container),但同样可以在器上面绘制。有一点不同之处是,面板不透明,意味着需要在面板的边界绘制所有的像素。最容易实现的方法是:在每个面板子类的paintComponent方法中调用super.paintComponent来用背景色绘制面板

class Not extends JPane;
{
    public void paintComponent(Graphics g)
    {
        super.paintComonent(g);
        ...
    }
class component3 extends JPanel
{
   private int Width1=75;
   private int Height1=100;
   public void paintComponent(Graphics g)
   {
     //  super.paintComponent(g);
       g.drawString("wel0001212..........", Width1, Height1);
   }
}
//对比
class component3 extends JPanel
{
   private int Width1=75;
   private int Height1=100;
   public void paintComponent(Graphics g)
   {
       super.paintComponent(g);
       g.drawString("wel0001212..........", Width1, Height1);
   }
}
//显示是一样的
javax.swing.JFrame
    Container getContentPane()
    返回这个JFrame的内容窗格对象
    Component add(Component c)
    讲一个给定的组件添加到该框架的内容窗格中
    (在框架类中add,不需要隐式对象)
    //如
    class NotHello extends JFrame
    {
        public NotHello()
        {
            add(new NotComponent);
            pack();
        }
    }
总结:定义一个框架
class XFrame extends JFrame
{
    public XFrame()
    {
        ...
    }
}
//中间可以为setSize();add(组件);

//总结:定义一个组件
class NotHello extends JComponent
{

    public void  paintComponent(Graphics g)
    {
        ...    //Graphics 操作
    }
    public Dimension getPreferredSize()  //组件必须有一个首选大小,或者是默认大小
    {
        return new Dimension(width, height);
    }
}
//或者
class Not extends JPane
{
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        ...
    }
}
//总结:添加JFrame(Component在JFrame类中添加,不在这里添加,层次分明)
public static void main(String[] args)
{
    EventQueue.invokeLater(()->
    {
        JFrame f=new NotHello();  //引入一个框架就是创建一个框架类
        f.setTitle();
        f.setDefaultCloseOperation(Frame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

java.awt.Component
    void repaint()
    尽可能快的重新绘制组件
    Dimension getPreferredSize()
    要覆盖这个方法,返回这个组建的首选大小 //组件都应该有一个首选大小
javax.swing.JComponent
    void paintComponent(Graphics g)
    覆盖这个方法来描述如何绘制自己的组件
java.awt.Window
    void pack()
    调整窗口的大小,当有多个组件,只想使用它们的首选大小,可以调用pack()
相关标签: java 图形