11.5学习swing

在Java中,setBounds 方法用于设置组件的大小和位置。这个方法通常在Swing或AWT组件中使用,用于布局管理。setBounds 方法属于 Component 类,因此所有继承自 Component 的类都可以使用这个方法。
setBounds 方法有以下几种重载形式:
public void setBounds(int x, int y, int width, int height)
public void setBounds(Rectangle r)
以下是 setBounds 方法参数的说明:
x:组件左上角的x坐标。
y:组件左上角的y坐标。
width:组件的宽度。
height:组件的高度。
r:一个 Rectangle 对象,包含了组件的位置和大小。
以下是一个使用 setBounds 方法的简单示例:
import javax.swing.JFrame;
import javax.swing.JLabel;
public class SetBoundsExample {
    public static void main(String[] args) {
        // 创建 JFrame 实例
        JFrame frame = new JFrame("SetBounds Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        // 创建 JLabel 实例
        JLabel label = new JLabel("Hello, World!");
        // 使用 setBounds 设置标签的位置和大小
        label.setBounds(50, 50, 200, 30);
        // 将标签添加到 JFrame 中
        frame.add(label);
        // 显示窗口
        frame.setVisible(true);
    }
}
在这个例子中,我们创建了一个 JFrame 和一个 JLabel。然后我们使用 setBounds 方法设置标签的位置和大小,并将标签添加到窗口中。
需要注意的是,使用 setBounds 方法进行布局通常不是很灵活,因为它固定了组件的绝对位置和大小。在响应式布局或国际化应用中,通常推荐使用布局管理器(如 BorderLayout, FlowLayout, GridBagLayout 等),这些布局管理器可以更好地处理不同屏幕大小和分辨率。

自定布局器

在Java中,要创建自定义布局管理器,你需要实现LayoutManager接口或扩展LayoutManager2接口。LayoutManager2接口是LayoutManager接口的扩展,提供了更多功能,如组件的首选大小、最小大小和最大大小。
以下是一个简单的自定义布局管理器的示例,它实现了LayoutManager2接口:
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager2;
public class CustomLayoutManager implements LayoutManager2 {
    @Override
    public void addLayoutComponent(String name, Component comp) {
        // 通常在这个方法中可以添加组件到特定的布局结构中
    }
    @Override
    public void removeLayoutComponent(Component comp) {
        // 通常在这个方法中可以移除组件
    }
    @Override
    public Dimension preferredLayoutSize(Container parent) {
        // 计算布局的首选大小
        return new Dimension(0, 0); // 这里应该根据布局的需要计算
    }
    @Override
    public Dimension minimumLayoutSize(Container parent) {
        // 计算布局的最小大小
        return new Dimension(0, 0); // 这里应该根据布局的需要计算
    }
    @Override
    public Dimension maximumLayoutSize(Container target) {
        // 计算布局的最大大小
        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }
    @Override
    public void layoutContainer(Container parent) {
        // 布局容器中的组件
        int count = parent.getComponentCount();
        for (int i = 0; i < count; i++) {
            Component c = parent.getComponent(i);
            // 这里可以设置组件的位置和大小
            c.setBounds(10 * i, 10 * i, 50, 50); // 示例位置和大小
        }
    }
    @Override
    public float getLayoutAlignmentX(Container target) {
        // 返回布局的水平对齐方式
        return Component.CENTER_ALIGNMENT;
    }
    @Override
    public float getLayoutAlignmentY(Container target) {
        // 返回布局的垂直对齐方式
        return Component.CENTER_ALIGNMENT;
    }
    @Override
    public void invalidateLayout(Container target) {
        // 当布局需要被重新计算时调用
    }
}
在这个例子中,CustomLayoutManager实现了LayoutManager2接口的所有方法。这些方法中,layoutContainer是最重要的,它负责设置组件的位置和大小。
以下是如何使用这个自定义布局管理器的示例:
import javax.swing.JButton;
import javax.swing.JFrame;
public class CustomLayoutManagerExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Custom Layout Manager Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 创建自定义布局管理器实例
        CustomLayoutManager layoutManager = new CustomLayoutManager();
        // 将自定义布局管理器设置给JFrame
        frame.setLayout(layoutManager);
        // 添加一些组件到JFrame
        frame.add(new JButton("Button 1"));
        frame.add(new JButton("Button 2"));
        frame.add(new JButton("Button 3"));
        // 显示窗口
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}
在这个例子中,我们创建了一个JFrame,将自定义布局管理器设置为它的布局管理器,并添加了三个按钮。当窗口显示时,CustomLayoutManager将负责布局这些按钮。在这个简单的实现中,每个按钮都会被放置在相对于前一个按钮的位置,并具有固定的宽度和高度。在实际应用中,你应该根据需要实现更复杂的布局逻辑。

容器不负责布局,布局是通过布局器

layoutContainer方法是LayoutManager接口和LayoutManager2接口中的一个核心方法。当容器需要重新布局其组件时,这个方法会被调用。在自定义布局管理器中,你需要在这个方法中实现具体的布局逻辑,即确定容器中每个组件的位置和大小。
下面是layoutContainer方法的一个更详细的实现示例,这个实现将会根据容器的大小和组件的数量来平均分配空间给每个组件:
@Override
public void layoutContainer(Container parent) {
    // 获取容器的内边距大小,通常布局需要考虑内边距
    Insets insets = parent.getInsets();
    // 获取容器内容的宽度,减去内边距
    int maxWidth = parent.getWidth() - (insets.left + insets.right);
    // 获取容器内容的高度,减去内边距
    int maxHeight = parent.getHeight() - (insets.top + insets.bottom);
    // 获取容器内组件的数量
    int componentCount = parent.getComponentCount();
    // 如果没有组件,则不需要布局
    if (componentCount == 0) {
        return;
    }
    // 计算每个组件可以分配的宽度和高度
    int widthPerComponent = maxWidth / componentCount;
    int heightPerComponent = maxHeight / componentCount;
    // 布局容器中的每个组件
    for (int i = 0; i < componentCount; i++) {
        Component component = parent.getComponent(i);
        // 计算组件的X和Y坐标
        int x = insets.left + i * widthPerComponent;
        int y = insets.top + i * heightPerComponent;
        // 设置组件的位置和大小
        component.setBounds(x, y, widthPerComponent, heightPerComponent);
    }
}
在这个实现中,我们首先获取容器的内边距大小,然后计算除去内边距后容器内容的宽度和高度。接着,我们根据容器内组件的数量来计算每个组件可以分配的宽度和高度。最后,我们遍历容器中的每个组件,并为它们设置位置和大小。
请注意,这个实现假设所有组件都应该具有相同的大小,并且容器足够大,可以容纳所有组件。在现实世界的应用中,你可能需要根据组件的首选大小、最小大小或最大大小来调整这个逻辑,并且处理组件之间的间隔和排列方式。
此外,如果组件的首选大小、最小大小或最大大小与计算出的尺寸不匹配,可能需要进一步调整组件的大小或位置,以确保布局看起来既美观又符合预期。

由于我无法直接运行Java代码,我将提供一个完整的Java程序示例,这个程序将创建一个使用自定义布局管理器的窗口,并演示layoutContainer方法的工作原理。你可以在自己的Java开发环境中运行以下代码:
import javax.swing.*;
import java.awt.*;
public class CustomLayoutManagerDemo {
    // 自定义布局管理器
    public static class CustomLayoutManager implements LayoutManager2 {
        @Override
        public void addLayoutComponent(String name, Component comp) {
            // 可以在这里添加组件到布局管理器中
        }
        @Override
        public void removeLayoutComponent(Component comp) {
            // 可以在这里移除组件
        }
        @Override
        public Dimension preferredLayoutSize(Container parent) {
            // 返回首选大小
            return new Dimension(300, 200);
        }
        @Override
        public Dimension minimumLayoutSize(Container parent) {
            // 返回最小大小
            return new Dimension(100, 100);
        }
        @Override
        public Dimension maximumLayoutSize(Container target) {
            // 返回最大大小
            return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
        }
        @Override
        public void layoutContainer(Container parent) {
            // 实现布局逻辑
            Insets insets = parent.getInsets();
            int maxWidth = parent.getWidth() - (insets.left + insets.right);
            int maxHeight = parent.getHeight() - (insets.top + insets.bottom);
            int componentCount = parent.getComponentCount();
            if (componentCount == 0) {
                return;
            }
            int widthPerComponent = maxWidth / componentCount;
            int heightPerComponent = maxHeight / componentCount;
            for (int i = 0; i < componentCount; i++) {
                Component component = parent.getComponent(i);
                int x = insets.left + i * widthPerComponent;
                int y = insets.top + i * heightPerComponent;
                component.setBounds(x, y, widthPerComponent, heightPerComponent);
            }
        }
        @Override
        public float getLayoutAlignmentX(Container target) {
            return Component.CENTER_ALIGNMENT;
        }
        @Override
        public float getLayoutAlignmentY(Container target) {
            return Component.CENTER_ALIGNMENT;
        }
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame("Custom Layout Manager Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置自定义布局管理器
        frame.setLayout(new CustomLayoutManager());
        // 添加组件到窗口
        frame.add(new JButton("Button 1"));
        frame.add(new JButton("Button 2"));
        frame.add(new JButton("Button 3"));
        // 显示窗口
        frame.setSize(400, 300);
        frame.setVisible(true);
    }
}
在这个示例中,我们创建了一个CustomLayoutManager类,该类实现了LayoutManager2接口。layoutContainer方法将容器内的组件平均分配到可用空间中。我们还在main方法中创建了一个JFrame窗口,添加了三个按钮,并设置了自定义布局管理器。
当你运行这个程序时,你将看到一个窗口,其中包含三个按钮,它们被自定义布局管理器平均分配到窗口的可用空间中。你可以调整窗口的大小来观察布局管理器如何重新排列按钮。

最重要三个方法

void addLayoutComponent(Component comp, Object constraints); // 从容器中移除组件时调用 void removeLayoutComponent(Component comp); // 布局容器中的组件 void layoutContainer(Container parent);,这三个是未实现的方法

在Java AWT中,当你使用 add 方法将一个组件添加到容器,并且该容器使用了 LayoutManager2(或 LayoutManager)的实现时,以下是一般的调用顺序:
add(Component comp, Object constraints): 当你调用容器的 add 方法时,如果提供了约束对象,则会调用布局管理器的 addLayoutComponent(Component comp, Object constraints) 方法。如果未提供约束对象,则可能调用 addLayoutComponent(String name, Component comp) 方法(这是 LayoutManager 接口中的方法)。
invalidate(): 添加组件后,容器的布局可能不再有效,因此通常会调用容器的 invalidate() 方法来标记其需要重新布局。
validate(): 在某些情况下,invalidate() 方法之后会立即调用 validate() 方法,或者稍后在事件分派线程中调用。validate() 方法负责重新计算布局并绘制组件。
layoutContainer(Container parent): 在 validate() 过程中,布局管理器的 layoutContainer(Container parent) 方法将被调用,以便实际执行布局操作。
preferredLayoutSize(Container parent), minimumLayoutSize(Container parent), maximumLayoutSize(Container parent): 在布局过程中,这些方法可能会被调用,以确定容器的首选大小、最小大小和最大大小。
以下是一个简化的调用顺序示例:
Container container = new Container();
LayoutManager2 layoutManager = new MyLayoutManager();
container.setLayout(layoutManager);
// 添加组件到容器
container.add(component, constraints);
// 调用顺序大致如下:
layoutManager.addLayoutComponent(component, constraints); // 添加组件和约束
container.invalidate(); // 标记容器需要重新布局
container.validate(); // 重新计算布局
layoutManager.layoutContainer(container); // 执行布局
请注意,实际的调用顺序可能会根据具体的容器实现和上下文有所不同。在某些情况下,validate() 方法可能不会立即调用,而是在下一个事件处理周期中调用,例如在容器被重新绘制时。此外,invalidate() 和 validate() 方法是容器的方法,而不是布局管理器的方法。

是的,JPanel 在Java Swing库中既是容器也是控件。
作为一个控件(Component),JPanel 是 java.awt.Container 类的一个扩展,这意味着它可以被添加到其他容器中,并且可以包含其他组件,如按钮、文本框等。JPanel 自身也是一个组件,可以被添加到其他容器中,比如 JFrame、JDialog 或另一个 JPanel。
作为一个容器(Container),JPanel 可以包含其他组件,并且可以应用布局管理器来安排它包含的组件。默认情况下,JPanel 使用 FlowLayout 布局管理器,但你可以通过调用 setLayout 方法来更改其布局管理器。
以下是一个简单的例子,展示了 JPanel 如何作为容器使用:
import javax.swing.*;
import java.awt.*;
public class JPanelExample {
    public static void main(String[] args) {
        // 创建 JFrame 实例
        JFrame frame = new JFrame("JPanel Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        // 创建 JPanel 实例
        JPanel panel = new JPanel();
        // 将 JPanel 作为容器使用,并添加按钮组件
        panel.add(new JButton("Button 1"));
        panel.add(new JButton("Button 2"));
        panel.add(new JButton("Button 3"));
        // 将 JPanel 添加到 JFrame 容器中
        frame.add(panel);
        // 显示窗口
        frame.setVisible(true);
    }
}
在这个例子中,JPanel 被用作一个容器来容纳三个 JButton 组件,然后 JPanel 自身被添加到 JFrame 中。这样,JPanel 既是容器也是控件的双重角色就体现出来了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/465129.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

W6100-EVB-Pico2评估板介绍

目录 1 简介 2 硬件资源 2.1 硬件规格 2.2 引脚定义 2.3 工作条件 3 参考资料 3.1 RP2350 数据表 3.2 W6100 数据表 3.3 原理图 原理图 & 物料清单 & Gerber 文件 3.3 尺寸图&#xff08;尺寸&#xff1a;mm&#xff09; 3.4 参考例程 认证 CE FCC 4 硬…

VUE2升级成VUE3的优化与区别

大家好&#xff0c;我是小编阿贤。欢迎各位大神关注《全栈技术圈》&#xff0c;让技术更加简单易懂。 1. vue2和vue3实例区别 1.1 创建一个vue2实例 在vue2里面的Vue是一个构造函数&#xff0c;通过该构造函数创建一个Vue实例&#xff0c;data选项可以是对象&#xff0c;也可以…

ProLightsfx新的出发–从CSDN到WordPress

原文链接&#xff1a;ProLightsfx新的出发--从CSDN到WordPress_ProLightsfx的技术分享 &#xff08;https://www.prolightsfxjh.com/article/article-new-start/&#xff09; 大概有差不多2年时间没有在csdn发布文章了。可能主要是最近几年工作有些疲惫、精神有些懈怠&#xff…

「Mac畅玩鸿蒙与硬件19」鸿蒙UI组件篇9 - 自定义动画实现

自定义动画让开发者可以设计更加个性化和复杂的动画效果&#xff0c;适合表现独特的界面元素。鸿蒙提供了丰富的工具&#xff0c;支持通过自定义路径和时间控制来创建复杂的动画运动。本篇将带你学习如何通过自定义动画实现更多样化的效果。 关键词 自定义动画动画路径贝塞尔曲…

GPIO子系统中Controller驱动源码分析

往期内容 本专栏往期内容&#xff1a; Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析&#xff1a;imx_pinctrl_soc_info结构体Pinctrl子系统中c…

【Linux系统编程】第四十二弹---多线程编程全攻略:涵盖线程创建、异常处理、用途、进程对比及线程控制

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、线程创建 2、线程异常 3、线程用途 4、进程 VS 线程 5、线程控制 5.1、创建和等待线程 1、线程创建 线程能看到进程的大…

Qt入门基础分享

文章目录 学习 Qt 语言之前的基本知识1. 编程基础语法:面向对象编程(OOP):基本数据结构:了解数组、链表、栈、队列、树(如二叉树、平衡树)、图(如邻接矩阵、邻接表)等。算法:熟悉常见的排序算法(如快速排序、归并排序、冒泡排序)和查找算法(如线性查找、二分查找)…

超萌!HTMLCSS:超萌卡通熊猫头

效果演示 创建了一个卡通风格的熊猫头 HTML <div class"box"><div class"head"><div class"head-copy"></div><div class"ears-left"></div><div class"ears-right"></di…

使用 AMD GPU 的 ChatGLM-6B 双语语言模型

Using the ChatGLM-6B bilingual language model with AMD GPUs — ROCm Blogs 2024 年 4 月 4 日&#xff0c;作者&#xff1a; Phillip Dang. ChatGLM-6B 是一个开源的中英双语语言模型&#xff0c;拥有 62 亿参数。它基于通用语言模型 (GLM) 架构&#xff0c;针对中文对话进…

计算并联电阻的阻值

计算并联电阻的阻值 C语言代码C代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 对于阻值为r1和r2的电阻&#xff0c;其并联电阻阻值公式计算如下&#xff1a; R1/(1/r11/r2) 输入 两个电阻阻抗大小&#xff0c;浮…

创建线程时传递参数给线程

在C中&#xff0c;可以使用 std::thread 来创建和管理线程&#xff0c;同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…

AAA 数据库事务隔离级别及死锁

目录 一、事务的四大特性&#xff08;ACID&#xff09; 1. 原子性(atomicity)&#xff1a; 2. 一致性(consistency)&#xff1a; 3. 隔离性(isolation)&#xff1a; 4. 持久性(durability)&#xff1a; 二、死锁的产生及解决方法 三、事务的四种隔离级别 0 .封锁协议 …

数字后端零基础入门系列 | Innovus零基础LAB学习Day9

Module 16 Wire Editing 这个章节的学习目标是学习如何在innovus中手工画线&#xff0c;切断一根线&#xff0c;换孔&#xff0c;更改一条net shape的layer和width等等。这个技能是每个数字IC后端工程师必须具备的。因为项目后期都需要这些技能来修复DRC和做一些手工custom走线…

前后端交互通用排序策略

目录 排序场景 排序实现思路 1. 静态代码排序实现 2.数据库驱动排序实现 3. 基于Java反射的动态排序实现 通用排序工具 SortListUtil 结语 排序场景 在面向前端数据展示的应用场景中&#xff0c;我们旨在实现一个更加灵活的排序机制&#xff0c;该机制能够支持对从后端传递…

前端入门一之CSS知识详解

前言 CSS是前端三件套之一&#xff0c;在MarkDown中也完美兼容这些语法&#xff1b;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 Emmet语法&#xff1a;CSS基本语法&#xff1a;css语法结构只有3种&#xff1a…

leetcode | 88. 合并两个有序数组

题目描述 88. 合并两个有序数组 分析 题目不允许更改nums1的长度&#xff0c;要求原地更改。 题目其实不难&#xff0c;如果记住可以从后往前合并的解法&#xff0c;但是正向遍历的问题是什么呢&#xff1f; ——元素覆盖。那为什么负向遍历就不会有这个问题呢&#xff1f;…

跳蚤市场之商品发布功能

一 商品类别和小类的联动 以下是一个示例代码&#xff0c;展示了如何实现商品类别中大类和小类的联动。 商品大类选择框、小类选择框 的设计 html部分 <form id"category-form"><label for"major-category">大类&#xff1a;</label&g…

OpenAI 发布了新的事实性基准——SimpleQA

SimpleQA 简介 名为 SimpleQA 的事实性基准&#xff0c;用于衡量语言模型回答简短的事实性问题的能力。 人工智能领域的一个悬而未决的问题是如何训练模型&#xff0c;使其产生符合事实的回答。 目前的语言模型有时会产生错误的输出或没有证据证明的答案&#xff0c;这个问题…

Android camera2

一、序言 为了对阶段性的知识积累、方便以后调查问题&#xff0c;特做此文档&#xff01; 将以camera app 使用camera2 api进行分析。 (1)、打开相机 openCamera (2)、创建会话 createCaptureSession (3)、开始预览 setRepeatingRequest (4)、停止预览 stopRepeating (5)、关闭…

Javascript属性遮蔽问题

先了解一下Object.defineProperty()方法 Object.defineProperty() 静态方法会直接在一个对象上定义一个新属性&#xff0c;或修改其现有属性&#xff0c;并返回此对象。 //obj&#xff1a;要定义的对象 //prop&#xff1a;一个字符串或 Symbol&#xff0c;指定了要定义或修改…