swing组件及其用法,swing有哪些常用组件

  swing组件及其用法,swing有哪些常用组件

  在第三章中,我们简要介绍了JFC/Swing工程组件使用的模型-视图-控制器(MVC)模式。在这一章中,我们将开始探索如何使用许多可用组件的关键部分。

  的所有Swing组件都基于JComponent类。尽管Swing库的某些部分并不植根于JComponent类,但所有组件都在继承的某个级别上共享JComponent类作为公共父类。JComponent类定义了常见的行为和属性。在这一章中,我们将学习一些常见的功能,如组件绘制、自定义、工具提示和调整大小。

  随着对JComponent的某些后代的关注,我们将了解JLabel、JButton和JPanel,这三个更广泛使用的Swing组件类。为了在组件中显示图像,我们需要理解图标接口,以及在使用预定义图像时对ImageIcon类和GrayFilter类的支持。此外,我们将了解AbstractButton类,它是JButton类的父类。AbstractButton所有子类共享的数据模型是ButtonModel接口;我们将讨论这个接口及其具体实现DefaultButtonModel。

  4.1 JComponent类

  JComponent类是由所有Swing组件继承的抽象基类。JComponent类有42个派生子类,每个子类都继承了JComponent的功能。图4-1显示了继承层次。

  虽然JComponent类是所有Swing组件的公共基类,但是Swing工程库中的很多类都不是从JComponent类派生出来的。这包括所有的高层窗口对象,比如JFrame、JApplet、JInternalFrame;所有与MVC相关的类;处理与事件相关的接口和类;等等。所有这些类将在后面的章节中讨论。

  虽然所有的Swing组件都扩展了JComponent,但是JComponent类扩展了AWT的容器类,相应的,也扩展了AWT的组件类。这意味着JComponent的许多方面是由AWT的组件和容器类共享的。

  部件碎裂

  JComponent类定义了原始AWT组件集之外的许多AWT组件面。这包括自定义绘图行为和显示设置的不同方式,如颜色、字体和其他客户端设置。

  绘制JComponent对象

  因为Swing的JComponent类是从Container类扩展而来的,所以它将遵循基本的AWT绘制模型:所有的绘制都由paint()方法完成,repaint()方法用于触发更新。但是,很多任务的完成是不一样的。JComponent类优化了呈现的许多方面,以提高性能和可伸缩性。此外,RepaintManager类可用于自定义绘制行为。

  为了提高呈现性能和可伸缩性,JComponent将呈现操作分为三个任务。公共paint (graphics g)方法分为三个独立的受保护的方法调用。按调用顺序依次为paintcomponent (g)、paint order(g)和paintChildren(g),图形参数通过原始paint()调用传递。组件本身首先由paintComponent(g)绘制。如果我们想要定制Swing组件的绘制,我们可以覆盖paintComponent()方法,而不是paint()方法。除非我们想完全替换所有的绘图,否则需要先调用super.paintComponent(),如下图所示,得到默认的paintComponent()行为。

  公共类MyComponent扩展JPanel {

  受保护的空白油漆组件(图形g) {

  super . paint component(g);

  //调用super.paintComponent(g)后自定义

  }

  paintBorder()和paintChildren()方法不可重写。paintBorder()方法在组件周围绘制边框,其概念将在第7章中更完整地描述。如果Swing容器对象中有组件,paintChildren()方法将绘制它们。

  为了优化绘图,JComponent类提供了三个附加的绘图属性:opaque、optimizedDrawingEnabled和doubleBuffered。其职能如下:

  optality:optality:JComponent的不透明属性定义了一个组件是否透明。当透明时,JComponent容器必须在组件后面绘制背景。为了提高性能,我们可以保持JComponent的不透明性,让JComponent绘制其背景,而不是依靠容器来绘制被覆盖的背景。

  优化:与optimizedRawingabled属性直接相邻的子元素是否可以重叠。如果子元素不能重叠,那么重绘时间可以大大减少。默认情况下,除了JDesktopPane、JLayeredPane和JViewport之外,大多数Swing组件都允许优化绘制。

  双缓冲:默认情况下,所有Swing组件都会重复地将其绘制操作缓存到一个由完整容器层次结构共享的缓冲区中;即表单中的所有组件。这极大地提高了渲染性能,因为当允许双缓冲时(通过doubleBuffered属性),只有一个屏幕更新渲染。

  JComponent的public void revalidate()方法也提供了绘图支持。调用此方法时,组件的高级容器会验证自身。这与AWT直接调用高级组件的revalidate()方法不同。

  Swing组件绘图增强的最后一个方面是RepaintManager类。

  RepaintManager类

  RepaintManager类负责确保当前显示的Swing组件上重绘请求的效率,并确保当一个区域无效时,只更新屏幕最小的“脏”区域。

  虽然不能自定义,但RepaintManager是公共的,提供了一个静态安装例程来使用自定义管理器:public static void setcurrentManager(Repaint Manager管理器)。要获取当前管理器,只需调用公共静态void current manager (jcomponent)方法。参数通常为空,除非我们定制了管理器来提供组件级支持。一旦我们有了管理器,我们可以做的一件事就是将屏幕缓冲区作为一个图像。因为缓冲区是实际显示在屏幕上的内容,这可以使我们高效地将屏幕复制到表单内部。

  组件组件=.

  repaint manager manager=repaint manager . current manager(null);

  image html image=manager . getoffscreenbuffer(comp,comp.getWidth(),

  comp . getheight());

  //或者

  image volatile image=manager . getvolatileoffscreenbuffer(comp,comp.getWidth(),

  comp . getheight());

  虽然很少实现,但提供我们自己的RepaintManager子类确实允许我们定制屏幕脏区的绘制机制,或者在绘制完成时的最小跟踪。覆盖以下四种方法之一可以允许我们定制机制:

  公共同步void addDirtyRegion(JComponent component,int x,int y,

  int宽度,int高度)

  公共矩形getDirtyRegion(JComponent组件)

  公共void markCompletelyClean(JComponent组件)

  公共void标记CompletelyDirty(JComponent组件)

  UIDefaults类

  UIDefaults类表示为当前外观安装的查询表,并包含显示设置,如JList中使用的字体、JTree部分中显示的颜色或图标。UIDefaults的使用将在第20章讨论Java可插拔观感架构时详细讨论。这里只简单介绍一下UIDefaults表。

  当我们创建一个组件时,该组件将自动请求UIManager在UIDefaults表中查找该组件使用的当前设置。大多数颜色、字体相关的组件设置以及其他与颜色和字体无关的设置都是可配置的。如果您不喜欢某个特定的设置,我们可以通过更新UIDefaults查询表中的相应项来简单地修改它。

  首先,我们需要知道我们想要修改的UIDefaults设置的名称。我们可以在本书的附录A中找到这些设置的名称,其中包含了J2SE 5.0中预定义外观和感觉的所有已知设置的完整列表。(由于发行版本不同会略有不同。此外,每个组件的描述都包含在包含UIResource的相关属性元素的表中。(要查找本书中的特定组件,请查看目录或索引。)

  一旦我们知道了设置的名称,我们就可以使用UImanager的公共静态void put (object key,object value)方法来存储一个新的设置,其中key是键值字符串。例如,以下代码将新创建的按钮的背景色更改为黑色,前景色更改为红色:

  ui manager . put( button . background ,颜色。黑色);

  ui管理器。放(按钮。前景色,颜色.红色);

  获取资源属性

  如果我们正在创建自己的组件,或者是我们只需要查看当前的设置值,我们可以请求UIManager。尽管公共静态对象获取(对象键)方法是最为通用的,却需要我们将返回值转换为合适的类型。相对应的,我们可以下列更为特定的getXXX()方法,这些方法会为我们执行錾,从而返回合适的类型:

  公共静态布尔getBoolean(对象键)

  公共静态边界getBorder(对象键)

  公共静态颜色getColor(对象键)

  公共静态维度getDimension(对象键)

  公共静态字体getFont(对象键)

  公共静态图标getIcon(对象键)

  公共静态Insets getInsets(对象键)

  公共静态int getInt(对象键)

  公共静态字符串getString(对象键)

  公共静态组件UI getUI(JComponent目标)

  包括由父结构继承的属性,JComponent共有92个属性。正如这个数字所表明的,JComponent类极为适用于可视化开发。

  4.1.3 处理JComponnent事件

  所有的JComponent子类共享许多不同类型的事件。大多数的事件类型来自于父类,例如成分与集装箱。首先我们将会探讨由容器继承而来的PropertyChangeListener。然后我们会了解一下所有的JComponent子类所共享的两种事件处理功能的使用:VetoableChangeListener与祖先听众。最后,我们来了解一下由成分继承的完全监听器集合。

  使用PropertyChangeListener监听组件事件

  JComponent类具有一些直接或间接的组件绑定属性。通过将PropertyChangeListener绑定到组件,我们可以监听特定的JComponent属性变化,并进行相应的响应。

  公共接口PropertyChangeListener扩展EventListener {

  public void属性更改(PropertyChangeEvent PropertyChangeEvent);

  }

  为了演示的目的,列表4-1中的PropertyChangeListener演示当监听命令按钮组件中行动类型属性的变化时我们所需要的行为。属性的变化可以决定执行哪一个如果语句块。

  包swingstudy.ch04导入Java。豆子。propertychangeevent

  导入Java。豆子。propertychangelister导入javax。挥棒。行动;

  导入javax。挥棒。图标;

  导入javax。挥棒。jbutton公共类ActionChangedListener实现PropertyChangeListener { private j button button;公共操作ChangedListener(按钮按钮){

  这个按钮=按钮

  } @覆盖

  public void属性更改(PropertyChangeEvent e){

  //TODO自动生成的方法存根字符串property name=e . getproperty name();

  if(e.getPropertyName().等于(动作。名称)){

  String text=(String)e . get new value();

  button.setText(文本);

  按钮。repaint();

  else if(属性名。等于(已启用){

  布尔启用状态=(布尔)e .获取新值();

  按钮。设置启用(启用状态。布尔值());

  按钮。repaint();

  else if(属性名。等于(动作.SMALL_ICON)) {

  Icon Icon=(Icon)e .获取新值();

  button.setIcon(图标);

  按钮。invalidate();

  按钮。repaint();

  } }

  使用VetoableChangeListener监听组件事件

  VetoableChangeListener是摇摆组件所使用的另一个JavaBean监听器。他使用限制属性,而PropertyChangeListener只使用绑定属性。这两个监听器之间的一个关键区别就在于如果监听器不能处理所请求的变化,则public void vetoableChange(PropertyChangeEvent PropertyChangeEvent)方法会抛出一个PerpotyVetoException异常。

  公共接口VetoableChangeListener扩展EventListener {

  public void vetoableChange(PropertyChangeEvent PropertyChangeEvent)

  引发PropertyVetoException

  }

  使用AncestorListener监听JComponent事件

  我们可以使用AncestorListener可以确定组件何时移动,何时可见,以及何时不可见。如果我们允许用户通过在屏幕上移动组件以及由屏幕中移除组件进行屏幕定制,则AncestorListener就十分有用。

  公共接口AncestorListener扩展EventListener {

  public void ancestorAdded(AncestorEvent AncestorEvent);

  public void ancestorMoved(AncestorEvent AncestorEvent);

  public void ancestorRemoved(AncestorEvent AncestorEvent);

  }

  为了演示,列表4-2将一个AncestorListener与窗口的根面板相关联。当程序首次启动时我们会看到删除,添加以及移动信息。另外,当我们拖动窗体是我们会看移动消息。

  包swingstudy.ch04导入Java。awt。事件队列;导入javax。挥棒。jframe

  导入javax。挥棒。事件。ancestorevent

  导入javax。挥棒。事件。ancestorlistener公共类AncestorSample { /**

  * @param args

  公共静态void main(String[] args) {

  //TODO自动生成的方法存根Runnable runner=new Runnable() {

  公共无效运行(){

  JFrame frame=新JFrame(祖先样本);

  框架。setdefaultcloseoperation(JFrame .EXIT _ ON _ CLOSE);AncestorListener AncestorListener=new AncestorListener(){

  公共void ancestorAdded(AncestorEvent事件){

  系统。出去。println( Added );

  公共void ancestorMoved(AncestorEvent事件){

  系统。出去。println(" Moved ");

  公共void祖先已移除(AncestorEvent事件){

  系统。出去。println(“Removed”);

  };frame.getRootPane().addAncestorListener(ancestorListener);

  frame.setSize(300,200);

  框架。设置可见(真);

  frame.getRootPane().设置可见(假);

  frame.getRootPane().设置可见(真);

  };事件队列。稍后调用(runner);

  } }

  监听JComponent的继承事件

  除了监听JComponent的AncestorEvent或是事件实际的功能,JComponent由其父类容器与成分继承了监听其他事件的能力。

  表4-4列出了十个事件监听器。我们也许我们使用了相当多的JComponent监听器,但是旧版本也可以工作。使用最合适的来解决我们的任务。

  JComponent继承的事件监听器

  carepopositionchanged(InputMethodEvent)

  inputMethodTextChanged(输入方法事件)

swing组件及其用法,swing有哪些常用组件