如何顺利地根据容器大小自动调整多个JLabel的字体大小? [英] How to auto-adjust font size of multiple JLabel based on container size in a smooth way?

查看:187
本文介绍了如何顺利地根据容器大小自动调整多个JLabel的字体大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要根据用于调整容器大小的比例因子调整多个JLabel的字体大小。为此,我将每个JLabel的字体设置为null,以便它们取得容器的字体。它有效,但也会产生奇怪的结果。

具体来说,文本似乎在容器后面滞后,有时会被截断。我想避免这种行为。任何想法如何?



模拟行为的示例代码:

  import java.awt.BorderLayout中; 
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.AffineTransform;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
导入javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
$ b $ public class TextResize implements Runnable {

public static void main(String [] args){
TextResize example = new TextResize();
SwingUtilities.invokeLater(示例);


public void run(){
JFrame frame = new JFrame(JLabel Text Resize);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(800,400));

Container container = frame.getContentPane();
container.setLayout(new BorderLayout());

final JPanel labelContainer = new JPanel(new GridBagLayout());
labelContainer.setBorder(BorderFactory.createLineBorder(Color.black));

//初始字体
final字体textFont = new Font(Lucida Console,Font.PLAIN,10).deriveFont(AffineTransform.getScaleInstance(1,1));
labelContainer.setFont(textFont);

GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0,10,0,10);
c.weightx = 1;
for(int i = 0; i <5; i ++){
JLabel f = new JLabel(Text here with looooooooong words);
f.setBorder(BorderFactory.createLineBorder(Color.green));
f.setFont(null); //从父元素获取字体
c.gridy = i;
labelContainer.add(f,c);
}

JSlider slider = new JSlider(0,50000,10000);
slider.addChangeListener(new ChangeListener(){
double containerWidth = labelContainer.getPreferredSize()。getWidth(); $ b $ double containerHeight = labelContainer.getPreferredSize()。getHeight();

@Override
public void stateChanged(ChangeEvent ev){
JSlider source =(JSlider)ev.getSource();
double scale =(double)(source.getValue )/ 10000d);

//缩放容器
labelContainer.setSize((int)(containerWidth * scale),(int)(containerHeight * scale));
$
字体newFont = textFont.deriveFont(AffineTransform.getScaleInstance(scale,scale));
labelContainer.setFont(b $ b // //调整字体:为什么会'滞后'?为什么截断有时? (newFont);

// print(font.getSize()不更改?)
System.out.pri ntln(scale ++ newFont.getTransform()+ newFont.getSize2D());
}
});

container.add(slider,BorderLayout.NORTH);
JPanel test = new JPanel();
test.setLayout(null);
labelContainer.setBounds(5,5,labelContainer.getPreferredSize()。width,labelContainer.getPreferredSize()。height);
test.add(labelContainer);
container.add(test,BorderLayout.CENTER);

frame.pack();
frame.setVisible(true);






$ b $ b < a href =http://i.stack.imgur.com/tZLOO.png =nofollow> http://i.stack.imgur.com/tZLOO.png



谢谢,

-s

解决方案

  @Override 
protected void paintComponent(Graphics g){
final Graphics2D g2d =(Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING,java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
super.paintComponent(g2d);
}

谢谢。


I need to resize the font of multiple JLabel based on the scaling factor used to resize the container. To do this, I am setting the font of each JLabel to null so that they take the font of the container. It works, but it also produces strange results.

To be specific, the text seems to "lag" behind the container and sometimes it gets even truncated. I would like to avoid this behavior. Any idea how?

Example code simulating the behavior:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.AffineTransform;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TextResize implements Runnable {

    public static void main(String[] args) {
        TextResize example = new TextResize();
        SwingUtilities.invokeLater(example);
    }

    public void run() {
        JFrame frame = new JFrame("JLabel Text Resize");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(800, 400));

        Container container = frame.getContentPane();
        container.setLayout(new BorderLayout());

        final JPanel labelContainer = new JPanel(new GridBagLayout());
        labelContainer.setBorder(BorderFactory.createLineBorder(Color.black));

        //initial font
        final Font textFont = new Font("Lucida Console", Font.PLAIN, 10).deriveFont(AffineTransform.getScaleInstance(1, 1));
        labelContainer.setFont(textFont);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(0, 10, 0, 10);
        c.weightx = 1;
        for (int i = 0; i < 5; i++) {
            JLabel f = new JLabel("Text here with possibly looooooooong words");
            f.setBorder(BorderFactory.createLineBorder(Color.green));
            f.setFont(null);//take the font from parent
            c.gridy = i;
            labelContainer.add(f, c);
        }

        JSlider slider = new JSlider(0,50000,10000);
        slider.addChangeListener(new ChangeListener() {     
            double containerWidth = labelContainer.getPreferredSize().getWidth();
            double containerHeight = labelContainer.getPreferredSize().getHeight();

            @Override
            public void stateChanged(ChangeEvent ev) {
                JSlider source = (JSlider) ev.getSource();
                double scale = (double) (source.getValue() / 10000d);

                //scaling the container
                labelContainer.setSize((int) (containerWidth * scale), (int) (containerHeight * scale));

                //adjusting the font: why does it 'lag' ? why the truncation at times?
                Font newFont = textFont.deriveFont(AffineTransform.getScaleInstance(scale, scale));
                labelContainer.setFont(newFont);

                //print (font.getSize() does not change?)
                System.out.println(scale + " " + newFont.getTransform() + newFont.getSize2D());
            }
        });

        container.add(slider, BorderLayout.NORTH);
        JPanel test = new JPanel();
        test.setLayout(null);
        labelContainer.setBounds(5, 5, labelContainer.getPreferredSize().width, labelContainer.getPreferredSize().height);
        test.add(labelContainer);
        container.add(test, BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);
    }

}

Picture: http://i.stack.imgur.com/tZLOO.png

Thanks,

-s

解决方案

I sort of solved the problem adding:

@Override
protected void paintComponent(Graphics g) {
    final Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    g2d.setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    super.paintComponent(g2d);
}

Thanks anyway.

这篇关于如何顺利地根据容器大小自动调整多个JLabel的字体大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆