⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiltlayout.java

📁 一本有关Java图形界面设计的一本书,英文的,附带有源码,
💻 JAVA
字号:
import java.awt.*;
import java.awt.LayoutManager;


/**
 * TiltLayout packs RLabels tightly together, tilting
 * them if necessary to fill available space. 
 */
public class TiltLayout implements LayoutManager {
    public void addLayoutComponent(String name, Component comp) {
    }

    public void removeLayoutComponent(Component comp) {
    }

    public Dimension minimumLayoutSize(Container parent) {
        return new Dimension(0, 0);
    }

    public Dimension preferredLayoutSize(Container parent) {
        return new Dimension(500, 500);
    }

    public void layoutContainer(Container parent) {
        // compute the necessary tilt angle 
        double angle = getTiltAngle(parent);       

        // your code here
    }
    
    private double getTiltAngle(Container parent) {
        double parentWidth = parent.getWidth();
        
        int n = parent.getComponentCount();
        double totalHeight = 0;
        double totalWidth = 0;
        double lastWidth = 0;
        double firstHeight = 0;
        for (int i = 0; i < n; ++i) {
            RLabel label = (RLabel) parent.getComponent(i);
            
            double oldAngle = label.getAngle();
            label.setAngle(0);
            Dimension size = label.getPreferredSize();
            label.setAngle(oldAngle);
            
            if (i == 0) {
                firstHeight = size.height;
            }
            totalHeight += size.height;
            totalWidth += size.width;
            if (i == n-1) {
                lastWidth = size.width;
            }
        }

        // special case: parent is wide enough
        if (parentWidth >= totalWidth) {
            // lay out horizontally
            return 0;
        }
        
        // special case: parent is too narrow
        if (parentWidth <= totalHeight) {
            // lay out vertically
            return Math.PI/2;
        }
        
        // parentWidth = (totalHeight-firstHeight)/sin(angle)
        //                 + firstHeight*sin(angle)
        //                 + lastWidth*cos(angle)
        //
        // Solve for angle using Newton's method.  Find root of
        //   f(angle) = parentWidth 
        //                 - (totalHeight-firstHeight)/sin(angle)
        //                 - firstHeight*sin(angle)
        //                 - lastWidth*cos(angle) 
        //
        //   f'(angle) = (totalHeight-firstHeight)*cos(angle)/sin^2(angle)
        //               - firstHeight*cos(angle)
        //               + lastWidth*sin(angle)
        //
        //   start with a good guess:
        double angle = Math.asin(totalHeight / parentWidth);
        
        // limit the number of iterations 
        for (int i=0; i<5; ++i) {
            System.err.println("guessing angle " + angle);
            double sinAngle = Math.sin(angle);
            double cosAngle = Math.cos(angle);
            
            // compute f(angle)
            double f = parentWidth
                         - (totalHeight-firstHeight)/sinAngle
                         - firstHeight*sinAngle
                         - lastWidth*cosAngle;
            if (Math.abs(f) < 0.5) {
                // we're within a pixel of parentWidth; good enough
                return angle;
            }
            
            // Newton's method: improve angle by adding -f(angle)/f'(angle)
            double df =  (totalHeight-firstHeight)*cosAngle/(sinAngle*sinAngle)
                         - firstHeight*cosAngle
                         + lastWidth*sinAngle;
            angle += -f / df;
        }
        return angle;
    }
    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -