java 图形程序设计(GUI)

xiaoxiao2021-02-28  106

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()
转载请注明原文地址: https://www.6miu.com/read-69988.html

最新回复(0)