Swing框架之Component:续文一

Java Swing大神必经之路17:Component 请求此 Component 获取输入焦点,并且此 Component 的顶层祖先成为获得焦点的 Window。此 Component 对于所要许可的请求而言必须是不可显示的、可聚焦的和可见的并且其所有祖先(除了顶层 Window 以外)必须是可见的。此方法会尽力完成该请求;但是在某些情况下可能无法完成。在此 Component 接收 FOCUS_GAINED 事件前,开发人员永远不能假定此 Component 是焦点所有者。如果由于此 Component 的顶层 Window 没有成为获得焦点的窗口而拒.. 阅读详情

Swing框架之Component:续文一

(2007-01-09 21:30:56)
分类:  Swing

         昨晚回去后还是觉得Component对象本身说的太简单,想来想去,觉得内容实在是太多,有必要补充两个续文说明Component的其它概念。今天介绍Swing组件paint方法的处理流程,这个流程能使我们理解许多Swing机制。明天续文讲述Swing事件处理器、双缓冲和布局管理器等原理。

=====================================

         Swing组件的paint方法是内部接口方法,一般用户不要直接调用这个方法,它总是在事件调度线程中调用。一般说来除了系统刷新事件触发这个方法,Component的repaint也触发这个方法的调用。repaint方法常用于当组件状态发生变化时刷新界面使用。repaint方法是Swing中少数几个线程安全的方法,可以在任何线程中调用它。它的原理是往事件队列中post一个PAINT事件。由于事件队列的事件是被事件调度线程同步执行的,所以这个方法总是线程安全的。事件调度线程从PAINT事件中获取事件源组件,从系统申请到图形设备资源后,调用该组件的update方法。update是AWT时代遗留下来的产物,本意是AWT组件画好组件背景后,再调用paint方法画出组件的前景。Swing出现后这个方法就被弃用了,所有逻辑都转到paint方法里。Update只是简单地调用paint方法来完成组件的渲染。老的Java教材上经常可以看到,所谓repaint调度update方法,update接着调用paint方法,自定义组件需要重载paint方法等话语,就是因为这个历史造成的。

         上篇文章中的MyButton的paint方法实现是一个非常老式的做法。现在JComponent的实现已经把paint方法改造成可以嵌套多重机制地方,这些机制包括层次渲染、边框、透明背景、双缓冲以及皮肤等。这些机制分别实现不同目的的组件提供了方便。

         图形用户界面的组件按照其在组件树上的角色可以分为容器组件和叶组件。Swing模型把叶组件当作是特殊、没有子组件的容器组件,只是JComponent继承Container类,所有Swing组件继承JComponent的原因。

         JComponent在paint方法中首先根据组件是否需要使用双缓冲,封装好图形设备对象,然后经过一番处理后调用paintComponent方法画出自身,然后调用paintBorder画出边框,最后调用paintChildren来完成子组件的渲染。

         paintComponent意思是画出组件自身,不包括子组件。因此前一文章中的MyButton可以通过覆盖paintComponent方法来完成MyButton的重画。在JComponent实现中,JDK 6的paintComponent的代码为:

    protected void paintComponent(Graphics g) {
        if (ui != null) {
            Graphics scratchGraphics = (g == null) ? null : g.create();
            try {
                ui.update(scratchGraphics, this);
            }
            finally {
                scratchGraphics.dispose();
            }
        }
    }

         这个方法首先检测组件是否安装了UI Delegate,如果安装了就将渲染过程代理给UI Delegate。这儿是嵌入皮肤的地方。JDK 6中JComponent对应的UI Delegate的update方法缺省的实现是:

public void update(Graphics g, JComponent c) {
 if (c.isOpaque()) {
     g.setColor(c.getBackground());
     g.fillRect(0, 0, c.getWidth(),c.getHeight());
 }
 paint(g, c);

}

         可以看出,背景透明机制在这儿实现。首先UI Delegate对象判断Component是否背景透明的,如果不是透明的,则使用背景色填充整个Component区域,然后调用paint(g, c)来完成组件在这种LookAndFeel种的渲染。了解了这些后,我们几乎就明白了Swing如何实现背景透明和如何切换皮肤。由于后面的文章还会对UI Delegate和皮肤机制详细描述,这儿就到此为止。

         目前还不要求实现皮肤,在这种情况下只需要重载paintComponent方法就行了,如果需要背景透明机制,可以模仿上面代码,MyButton的paintComponent可以这样写:

public void paintComponent(Graphics g) {
 if (isOpaque()) {
     g.setColor(getBackground());
     g.fillRect(0, 0, getWidth(), getHeight());
 }
 if(pressed){//按钮按下去了
                //画出按下的样子
 }else{
                //画出抬起的样子
 }
}

         paintBorder意思是画出组件的边框。Swing所有组件都有边框的概念,就是说可以为任何组件添加各种边框,包括自定义的边框。JDK 6中JComponent的paintBorder的实现是这样的:

protected void paintBorder(Graphics g) {
        Border border = getBorder();
        if (border != null) {
            border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
        }
}

         非常直接,如果自己有border,就将画自己边框的任务代理给了这个border,并传给它图形设备和边界参数。Swing缺省提供了大量的各种各样的边框。同样可以定义自己的边框,实现方法就是继承Border类,Border类中有三个方法要实现,它们的含义如下:

public interface Border
{
    //这儿是画出组件边框的地方。
    void paintBorder(Component c, Graphics g, int x, int y, int width, int height);
  //这儿是定义边框边界的地方,组件可以根据这信息,安排它的内容。
    Insets getBorderInsets(Component c);
//边框的背景是不是透明的?不是透明的要负责画出边框的背景。是透明的使用组件的背景。
    boolean isBorderOpaque();
}

         这儿实现一个简单的红线边框作为演示:

public class RedLineBorder implements Border{
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height){     
        g.setColor(Color.red);//设置为红色
        g.drawRect(x,y, width, height);//画出边框
    }
    public Insets getBorderInsets(Component c){
        return new Insets(1,1,1,1); //四周都是1
    }
    public boolean isBorderOpaque(){
        return false; //背景透明
    }
}

         paintChildren完成容器类组件的子组件的渲染。JDK缺省的实现是调用各个自组件的paint方法。一般来说不需要重载这个方法。如果想改变诸如组件Z-order遮挡顺序,可以覆盖这个方法,从相反顺序调用组件的paint方法。

         到这儿我们对Swing的结构有了更深化的理解,UI Delegate机制也已经初露倪端。还有几个重要Swing Component概念或者机制没有讲,明天的续文再对它们做出说明。

VS2019 C# MySQL 学生信息增删改查(一、增删) VS2019 C# MySQL 学生信息增删改查 由于刚刚学习VS2019,入手的第一个例子是编写一个简单的增删改查。这里,我以学生信息为例,进行详细的过程描述以及代码实现。 一、 新建一个Windows窗体应用程序 1、创建新项目界面,如下图所示。 2、更改项目名称,当然不修改也可以。我这里的是“StudentInfoSystem”;项目存放位置路径根据自己需要进行更改;“将解决方案和项目放在同一目录中”前面的勾选框,选不选都可以;点击“创建”,如下图所示。 二、前期准备工作 1、将Form1属性中 阅读详情

相关推荐

VSCode+Typst零配置写作指南:5分钟搞定论文排版环境(含实时预览技巧)

本文介绍如何利用VSCode和Typst快速搭建零配置的论文排版环境,5分钟内实现高效写作与实时预览。Typst作为轻量级排版工具,结合LaTeX的精度与现代化语法,显著提升学术写作效率,特别适合需要频繁调整格式的研究人员。

weixin_30642561的博客 111

Swing框架之Component

Component在Swing的MVC模型中担任Controller的角色,同时它也是SwingAPI中代表具体组件的对象。Component在Swing中对外负责提供API接口,对内负责协调控制Model和UIDelegate(有时可能还包括Renderer)的操作,可以说是整个Swing结构的中心角色。为了方便你回忆Swing的MVC模型,将Swing模型示意图引了过来:

expleeve 3608

用户视角下的vfsglobal预约困境:从注册到登录的全流程避坑指南

本文详细解析了vfsglobal签证预约系统从注册到登录的全流程操作,帮助用户避开常见技术陷阱。针对IP限制、DNS解析、浏览器缓存等登录障碍提供实用解决方案,并揭示账号管理的隐藏规则与支付环节的延时处理技巧,助力用户高效完成签证预约。

ol78901234的博客 872

repaint方法

java.awt 类 Component void repaint() 重绘此组件。 repaint()方法是一个具有刷新页面效果的方法,若不调用repaint方法图形发生变化后不会立刻显示 repaint调用update()清除当前显示并再调用paint()方法 如果不调用repaint()就不能实现每一次的刷新显示,不能立刻显示就无法马上进行下一步的绘画 ...

BlizCp的博客 4661

qcc51xx如何配置spdif输入

qcc51xx如何配置spdif输入。

Alex_886的博客 1375

SAP各模块表清单及逻辑关系介绍

分享韩国同行总结的各模块的表清单及逻辑关系,这对ABAP顾问和各模块业务顾问应该非常有用的 物料主数据 SD与MM PS模块 PP模块 QM模块 CO模块 FI模块

weixin_40672823的博客 9599

java.awt.component.repaint()

repaint public void repaint()Repaints this component. If this component is a lightweight component, this method causes a call to this component's paint method as soon as possible. Otherwise, th...

msforever的专栏 519

2026最新openclaw(clawbot/moltbot)真正在自己个人电脑上搭建部署,配置飞书远程远程让AI助理操控电脑完成任务,以及结合ollama无限token实现7*24小时工作(附配置)

2026最新openclaw(clawbot/moltbot)真正在自己个人电脑上搭建部署,配置飞书远程远程让AI助理操控电脑完成任务,以及结合 ollama 无限token实现7*24小时工作,以及部署安装需要的 skills 完成复杂的工作任务(附完整可以运行的配置文件)。 很多人已经会配置安装 openclaw 了 ,但是 安装完成之后真正让电脑自动运行起来的很好,完成出色工作的更少,最常见的就是聊聊天,或者执行一些简单的命令,理解要让电脑自动化工作,openclaw、skills、大模型这三样。

代码讲故事 2963

repaint方法使用和说明

repaint 重绘此组件。如果组件是轻量组件,则此方法会尽快调用此组件的 paint 方法。否则此方法会尽快调用此组件的 update 方法。 目录 1方法 2工作原理 1方法编辑 repaint()方法用于重绘组件,该方法有下面四种形式: 1。public void repaint() 2。p

liuxinhua2013的专栏 2万+

Python蓝色跳动的爱心(完整代码)

Python语言实现蓝色跳动的爱心的完整代码。 代码分析 这段代码使用了 库来创建一个动态的爱心图案,并在屏幕上显示带有动态效果的“我爱你”字样。以下是对这段代码的详细分析: 用于创建图形用户界面(GUI)。 用于生成随机数,主要用于控制爱心图案的扩散效果。 中的 , , , 用于数学计算,生成爱心形状和扩散效果。 包含了 等常量,用于控制控件的对齐方式。 2. 全局变量定义 , : 定义画布的大小。 , : 爱心的中心坐标。 : 用于定义爱心形状的缩放

AIGC 1921

OPENSSL使用方法

预备知识KEY 通常指私钥。CSR 是 Certificate Signing Request 的缩写,即证书签名请求,这不是证书,只是包含申请证书的基本信息。生成证书时要把这个提交给权威的证书颁发机构,颁发机构审核通过之后,再根据这些申请信息生成相应的证书。CRT 即 certificate的缩写,即证书。 X.509 是一种证书格式。对X.509证书来说,认证者总是CA或由CA指定的人,一份...

zxm8513优快云博客 1215

java画图总结之三(常用方法paint,repaint,update)

三,常用方法paint,repaint,update 这个问题的由来是因为,我在编写java小程序,画图的时候,发现我重写了paint(graphics g)方法,而执行的时候调用的是repaint()无参方法。老师说,repaint里面间接调用了paint方法。但是是如何间接调用的呢?repaint方法里面是否new了一个graphics对象呢然后传给paint呢? 首先paint方法,并不

tanjun592的博客 2万+

基于Python的Steam游戏评论与销量数据爬取及预测分析

随着数字游戏市场的蓬勃发展,Steam作为全球最大的数字游戏分发平台,积累了海量的游戏数据与玩家行为数据。本文旨在通过Python网络爬虫技术,采集Steam平台的游戏基本信息、玩家评论数据及销量相关信息,为后续的游戏评论情感分析与销量预测模型构建提供数据支持。本文将详细介绍使用requestsselenium等库实现Steam数据爬取的全过程,并提供完整的代码实现与数据处理方法。关键词:Steam;Python爬虫;数据采集;评论分析;销量预测。

2201_76125261的博客 855

Swing框架之Component:续文三

Swing框架之Component:续文三 Swing事件与事件处理器模型          Component在Swing模型中是事件触发源。前一篇文章在描述Swing的事件处理模型时就已经提到了这个事件处理过程。简单来说,Swing组 件在侦听到原生事件并处理后,往往产生新的逻辑事件。逻辑事件是某些组件所特有的、具有特定语义的事件,比如JButton按下时产生 ActionEvent...

topinking的专栏 202

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Swing框架之Component:续文二

2008 - 05 - 06 Swing框架之Component:续文二          Swing的事件处理过程为:事件调度线程(Event Dispatch Thread)从事件队列(EventQueue)中获取底层系统捕获的原生事件,如鼠标、键盘、焦点、PAINT事件等。接着调用该事件源组件的 dispachEvent。该方法过滤出特殊事件后,调用processEvent进行处理...

topinking的专栏 157

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java Swing Component

所有 Swing 组件(如按钮、窗口、面板)的“老祖宗”都是。都能作为对话框的父组件参数!所有 Swing 组件都是。

wu_android的博客 220

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java component类_Swing Component类

boolean action(Event evt, Object what) - Deprecated. As of JDK version 1.1, should register this component as ActionListener on the component which fires action events.void add(PopupMenu popup) - Adds...

weixin_42497762的博客 512

How to Write a Custom Swing Component

How to Write a Custom Swing Component February 22, 2007 Kirill Grouchnikov     Contents Basic Building Blocks The Component Class: UI Delegate Plumbing The Model I...

myNameAbian的专栏 367

java getcomponents()_Java Swing - 如何创建getComponentAt()从JFrame获取Component

import java.awt.BorderLayout;import java.awt.Color;import java.awt.Component;import java.awt.Container;import java.awt.Point;import javax.swing.BorderFactory;import javax.swing.JFrame;import javax.swi...

weixin_33050129的博客 664

Swing component使用方式

<br />在使用Swing中JFrame、JPanel及其他Composite组件时有两种方式。<br /> <br />1, 新建一个类并继承此类组件,然后在新的类中向其中添其他组件。<br />      例如 <br />      Class AKindJFrame extends JFrame {<br />             AKindJFrame(){<br />                 Container contents = getContentPane();<br /> 

Jinuxwu的专栏 1483

Swing简单边框(Border)设置

最近重温了下Swing ,写个Border记录下,Border在Swing界面美化这块比较好用,界面的美化还真离不开Border。 快速开发简单Border 步骤: 1、创建Component设置Border 2、创建simpleJpane 添加Component 3、创建JFrame  添加 simpleJpane 代码如下:package border; packag

it小虾米的专栏 2万+

Swing框架学习

Swing是JFC的一部分 Swing提供窗口,按钮,表格等一系列控件; Swing是纯JAVA写的。 例如:JButton,JCheckBox,JScrollbar等都是JComponent的子类; 可以理解为JComponent是控件的超类; 上代码初学,可能还有理解不到位的地方: import java.awt.*; import java.awt.event.*; import...

大风起兮云飞扬 474
上一篇: Swing框架之Component
下一篇: 资源网站推荐
tof21
博客等级 码龄18年 2793粉丝 287原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tof21

支持原创

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值