Swing中支持自动换行的WrapLayout

http://www.cnblogs.com/TLightSky/p/3482454.html

——————————————————————————————————————————————————————————————————————————————

原来的WrapLayout有点小bug,会引起抖动,稍微改了一下,现在比较好用了

package com.miui.theme.tool.gui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;

import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

/**
 * FlowLayout subclass that fully supports wrapping of components.
 */
public class WrapLayout extends FlowLayout {
    private Dimension preferredLayoutSize;

    /**
     * Constructs a new <code>WrapLayout</code> with a left alignment and a
     * default 5-unit horizontal and vertical gap.
     */
    public WrapLayout() {
        super();
    }

    /**
     * Constructs a new <code>FlowLayout</code> with the specified alignment and
     * a default 5-unit horizontal and vertical gap. The value of the alignment
     * argument must be one of <code>WrapLayout</code>, <code>WrapLayout</code>,
     * or <code>WrapLayout</code>.
     *
     * @param align
     *            the alignment value
     */
    public WrapLayout(int align) {
        super(align);
    }

    /**
     * Creates a new flow layout manager with the indicated alignment and the
     * indicated horizontal and vertical gaps.
     * <p>
     * The value of the alignment argument must be one of
     * <code>WrapLayout</code>, <code>WrapLayout</code>, or
     * <code>WrapLayout</code>.
     *
     * @param align
     *            the alignment value
     * @param hgap
     *            the horizontal gap between components
     * @param vgap
     *            the vertical gap between components
     */
    public WrapLayout(int align, int hgap, int vgap) {
        super(align, hgap, vgap);
    }

    /**
     * Returns the preferred dimensions for this layout given the <i>visible</i>
     * components in the specified target container.
     *
     * @param target
     *            the component which needs to be laid out
     * @return the preferred dimensions to lay out the subcomponents of the
     *         specified container
     */
    @Override
    public Dimension preferredLayoutSize(Container target) {
        return layoutSize(target, true);
    }

    /**
     * Returns the minimum dimensions needed to layout the <i>visible</i>
     * components contained in the specified target container.
     *
     * @param target
     *            the component which needs to be laid out
     * @return the minimum dimensions to lay out the subcomponents of the
     *         specified container
     */
    @Override
    public Dimension minimumLayoutSize(Container target) {
        Dimension minimum = layoutSize(target, false);
        minimum.width -= (getHgap() + 1);
        return minimum;
    }

    /**
     * Returns the minimum or preferred dimension needed to layout the target
     * container.
     *
     * @param target
     *            target to get layout size for
     * @param preferred
     *            should preferred size be calculated
     * @return the dimension to layout the target container
     */
    private Dimension layoutSize(Container target, boolean preferred) {
        synchronized (target.getTreeLock()) {
            // Each row must fit with the width allocated to the containter.
            // When the container width = 0, the preferred width of the
            // container
            // has not yet been calculated so lets ask for the maximum.
            int targetWidth = target.getSize().width;

            if (targetWidth == 0)
                return new Dimension();
//            if (targetWidth == 0)
//                targetWidth = Integer.MAX_VALUE;

            int hgap = getHgap();
            int vgap = getVgap();
            Insets insets = target.getInsets();
            int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
            int maxWidth = targetWidth - horizontalInsetsAndGap;

            // Fit components into the allowed width

            Dimension dim = new Dimension(0, 0);
            int rowWidth = 0;
            int rowHeight = 0;

            int nmembers = target.getComponentCount();

            for (int i = 0; i < nmembers; i++) {
                Component m = target.getComponent(i);

                if (m.isVisible()) {
                    Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();

                    // Can‘t add the component to current row. Start a new row.

                    if (rowWidth + d.width > maxWidth) {
                        addRow(dim, rowWidth, rowHeight);
                        rowWidth = 0;
                        rowHeight = 0;
                    }

                    // Add a horizontal gap for all components after the first

                    if (rowWidth != 0) {
                        rowWidth += hgap;
                    }

                    rowWidth += d.width;
                    rowHeight = Math.max(rowHeight, d.height);
                }
            }

            addRow(dim, rowWidth, rowHeight);

            dim.width += horizontalInsetsAndGap;
            dim.height += insets.top + insets.bottom + vgap * 2;

            // When using a scroll pane or the DecoratedLookAndFeel we need to
            // make sure the preferred size is less than the size of the
            // target containter so shrinking the container size works
            // correctly. Removing the horizontal gap is an easy way to do this.

            Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);

            if (scrollPane != null && target.isValid()) {
                dim.width -= (hgap + 1);
            }

            return dim;
        }
    }

    /*
     * A new row has been completed. Use the dimensions of this row to update
     * the preferred size for the container.
     *
     * @param dim update the width and height when appropriate
     *
     * @param rowWidth the width of the row to add
     *
     * @param rowHeight the height of the row to add
     */
    private void addRow(Dimension dim, int rowWidth, int rowHeight) {
        dim.width = Math.max(dim.width, rowWidth);

        if (dim.height > 0) {
            dim.height += getVgap();
        }

        dim.height += rowHeight;
    }
}
时间: 2024-10-31 09:52:44

Swing中支持自动换行的WrapLayout的相关文章

第12章-Swing编程 --- Swing中的特殊容器--JSplitPane

(一)使用JSplitPane JSplitPane用于创建一个分割板,它可以将一个组件(通常是一个容器)分割成两个部分,并提供一个分割条.用户可以拖动该分隔条来调整两个部分的大小.分隔面板的实质是一个特殊容器,该容器只能容纳两个组件,而且分割面板又分为上下分割.左右分割两种情形. 创建分割面板的代码如下: new JSplitPane(方向,左/上组件,右/下组件); JSplitPane分割面板提供了如下几个方法: (1)setDividerLocation(double proportio

Java Swing中的SwingWorker

Swing中的SwingWorker主要是用来执行比较耗时的任务. Java doc文档中中包含了一些简单的例子. An abstract class to perform lengthy GUI-interaction tasks in a background thread. Several background threads can be used to execute such tasks. However, the exact strategy of choosing a threa

大开测试:性能- VuGen中支持哪些步骤类型(连载12)

7.12  VuGen中支持哪些步骤类型 1.问题提出 VuGen中支持哪些步骤类型? 2.问题解答 VuGen中支持下列步骤类型,如表7-3所示. 表7-3                                                  VuGen支持步骤类型列表 步 骤 类 型 描    述 服务 服务步骤是一个函数,它不会在Web应用程序上下文中进行任何更改.更确切地说,服务步骤执行自定义任务(如设置代理服务器).提供授权信息以及发出自定义的标头 URL 在键入URL或者

在ASP.NET中支持断点续传下载大文件(ZT)

IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag         客户端每次提交下载请求时,服务端都要添加这两个响应头,以保证客户端和服务端将此下载识别为可以断点续传的下载: Accept-Ranges:告知下载客户端这是一个可以恢复续传的下载,存放本次下载的开始字节位置.文件的字节大小: ETag:保存文件的唯一标识(我在用的文件名+文件最后修改时间,以便续传请求时对文件进行

第二节 Java Swing中的基本容器:JFrame

第二节 基本容器:JFrame 如果要使用Swing创建一个窗口,则直接使用JFrame即可,此类事Component类的子类,常用方法如下: 小试牛刀 创建一个简单的窗口 import java.awt.*; import java.io.*; import javax.swing.*; public class JavaSwingTest { public static void main(String args[]) throws IOException{ test1(); } //创建一

U-Boot中支持USB

转载: http://blog.csdn.net/qiurihuanghua/article/details/6234832 今天查看了一下在P4080DS板子的U-Boot中支持USB,主要是加入USB Host端驱动和相应设备端驱动来支持存储设备,这样就 可以将Kernel以及文件系统存放在U盘上,来通过U盘来启动. 跟其它接口一样,在U-Boot中,USB的支持也是通过放在相应板子上的几个宏定义来实现,对于P4080DS板,是在include/configs/corenet_ds.h定义:

【云快讯】之二十五《微软将在Windows Server中支持“Docker”容器》

2015-04-09 张晓东 东方云洞察 点击上面的链接文字,可以快速关注"东方云洞察"公众号 Windows Server Containers will be able to run applications specifically built for Windows Server and .Net 微软已经开发了一种容器技术,可以在Windows Server操作系统上运行,是希望能够在微软的windows和.Net体系上复制基于Docker的容器在Linux上的成功. &qu

在CentOS 6.x中支持exfat格式的U盘(移动硬盘)

参考资料:http://linux.cn/article-1503-1.html CentOS系列一直没有默认支持使用exfat格式的大容量U盘(移动硬盘),但可以通过添加fuse-exfat模块来支持,步骤如下: 1.下载fuse-exfat支持软件: exfat支持是通过fuse模块的方式支持的,其项目地址是: https://code.google.com/p/exfat/  ,当前版本是:1.0.1. 目前exfat的支持已经是全功能支持,支持读写. 可以下载源代码包,并自行使用scon

jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?

1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML.在 1.4 中,JSON 就会生成一个 JavaScript 对象,而 script 则会执行这个脚本.随后服务器端返回的数据会根据这个值解析后,传递给回调 函数.可用值: •"xml": 返回