65.9K
CodeProject 正在变化。 阅读更多。
Home

Java中以相同比例调整框架和控件

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019 年 10 月 8 日

CPOL

1分钟阅读

viewsIcon

7278

downloadIcon

70

本文介绍如何在Java中自动调整框架及其控件的大小,使其保持相同的比例。

引言

我在布局管理器中缺失的一点是,让控件能够自动调整大小,并且调整比例与框架调整大小的比例相同。这意味着如果用户将框架的宽度加倍,那么所有控件的宽度,甚至它们之间的距离,都将变为初始宽度的两倍。我为此创建了一个快速可移植的解决方案。虽然它可能不完美,但我认为它作为一个起点是“足够好的”。无论如何,我只是一个业余爱好者,我认为发布它不会有坏处,因为有人可能会觉得它有用。

背景

我创建了一个 HierarchyBoundsListener 类,执行自动调整大小的过程。然后应该将该类添加到面板以使其生效。

使用代码

关于这个类没什么好说的,代码可以直接复制粘贴到名为“test”的应用程序中。

/* Warning! This listener should be added AFTER the panel with all
   its components have been created and added.
   Note: Several successive resizings may change significantly the sizes of the
   components due to the accumulated rounding errors. */

package test;

import java.awt.Component;
import java.awt.Font;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import javax.swing.JPanel;

/**
 *
 * @author Bilal Gharib
 */
public class ResizeComponentsListener implements HierarchyBoundsListener {
    
    private int InitialPaneWidth;
    private int InitialPaneHeight;   
    private double InitialArea;
    private final boolean ResizeFont;

    public ResizeComponentsListener(
        int InitialPaneWidth, int InitialPaneHeight, boolean ResizeFont) {
        
        this.InitialPaneWidth = InitialPaneWidth;
        this.InitialPaneHeight = InitialPaneHeight;    
        this.InitialArea = InitialPaneWidth * InitialPaneHeight;
        this.ResizeFont = ResizeFont;
    }
            
    @Override
    public void ancestorMoved(HierarchyEvent e) {
        // not used        
    }

    @Override
    public void ancestorResized(HierarchyEvent e) {
                
        JPanel Panel = (JPanel)e.getSource();
        
        double RatioX = (double)Panel.getWidth() / InitialPaneWidth;
        double RatioY = (double)Panel.getHeight() / InitialPaneHeight;
        
        double CurrentArea = Panel.getWidth() * Panel.getHeight();
        double RatioArea = (double)CurrentArea / InitialArea;
        
        double NewX, NewY, NewWidth, NewHeight, NewFontSize;
        Font NewFont;
                
        for(Component c : Panel.getComponents()){            
            NewX = c.getX() * RatioX;
            NewY = c.getY() * RatioY;
            NewWidth = c.getWidth() * RatioX;
            NewHeight = c.getHeight() * RatioY;               
            c.setLocation((int)Math.round(NewX), (int)Math.round(NewY));
            c.setSize((int)Math.round(NewWidth), (int)Math.round(NewHeight));            
            if (ResizeFont){
                NewFontSize = c.getFont().getSize() * RatioArea;
                NewFont = c.getFont().deriveFont((float)Math.round(NewFontSize));
                c.setFont(NewFont);                
            }                                       
        }                
        this.InitialPaneWidth = Panel.getWidth();
        this.InitialPaneHeight = Panel.getHeight();
        this.InitialArea = CurrentArea;   
    }    
}

以下是使用该类的“test”程序的完整代码。它包含一个 JFrame 和一些控件。最后一行将 ResizeComponentsListener 附加到 JFrame。

package test;

import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.BorderFactory;
import javax.swing.SwingConstants;

public class Test {

    public static void main(String[] args) {
               
        JFrame f = new JFrame("Java JFrame!");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(500, 300);
        f.setLocation(250, 150);
        f.getContentPane().setLayout(null);
        
        Font fnt = new Font("Tahoma", Font.BOLD, 18);
                        
        JLabel l1 = new JLabel("L");
        l1.setHorizontalAlignment(SwingConstants.CENTER);
        l1.setHorizontalAlignment(SwingConstants.CENTER);
        l1.setBorder(BorderFactory.createLineBorder(Color.black));
        l1.setBounds(10, 10, 100, 70);
        l1.setFont(fnt);
        
        JButton b1 = new JButton("B1");
        b1.setFont(fnt);
        b1.setBounds(120, 10, 100, 70);
        JButton b2 = new JButton("B2");
        b2.setFont(fnt);
        b2.setBounds(390, 10, 100, 70);
        JButton b3 = new JButton("B3"); 
        b3.setFont(fnt);
        b3.setBounds(390, 90, 100, 70);
                           
        f.add(l1);
        f.add(b1);  
        f.add(b2);
        f.add(b3);
        f.setVisible(true); 
        f.getContentPane().addHierarchyBoundsListener(
            new ResizeComponentsListener(500, 300, true));
        
    }   
}

关注点

请注意,调整字体大小是可选的,它作为布尔值传递给构造函数。正如警告所述,应该在创建所有控件并将其添加到 JFrame 后添加此监听器。另请注意,该监听器不适用于 JFrame 内部面板中的控件。

希望这能有所帮助。欢迎提出任何建议。

© . All rights reserved.