2

So what I'm trying to do is to resize the font of every component in a JFrame knowing that the fonts have different sizes at launch.

For example, I would have a JButton with a font size of 15 and a JLabel with a font size of 20 :

button1.setFont(new Font("Arial", Font.PLAIN, 15));
label1.setFont(new Font("Arial", Font.PLAIN, 20));

The result I want here is that if the window is resized to twice its width, the components should follow at the same rate, so the JButton would be 30 and the JLabel would be 40.

I'm using a ComponentListener on the JFrame but I can't find how to do it. Here's what I currently have; if only I knew the window's size BEFORE it was resized it would already be working, but I don't think it's possible.

Here is the overridden componentResized method :

@Override
public void componentResized(ComponentEvent arg0) {
    Component[] components = ((JFrame)arg0.getComponent()).getComponents();
    System.out.println(((Component) arg0.getSource()).getSize().getWidth());//How do I find the window's size before it was resized ?


    //Getting standard window size
    Dimension dimScreen = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension dimBaseWindow = new Dimension(dimScreen.width/2,dimScreen.height/2);
    double baseWidth = dimBaseWindow.getWidth();

    //Getting current window size
    Dimension dimCurrentWindow = ((JFrame)arg0.getComponent()).getSize();
    double currentWidth = dimCurrentWindow.getWidth();
    System.out.println(currentWidth);

    //Rate at which the font will be resized
    double resizeRate = currentWidth/baseWidth;

    resizeComponentsFonts(components, resizeRate, (int)currentWidth, (int)baseWidth);
}

resizeComponentsFonts method :

public void resizeComponentsFonts(Component[] components, double resizeRate, int newWindowWidth, int baseWindowWidth) {
    for(int i=0;i<components.length;i++) {
        if(components[i] instanceof JPanel || components[i] instanceof JLayeredPane || components[i] instanceof JRootPane) {
            resizeComponentsFonts(((Container)components[i]).getComponents(),resizeRate, newWindowWidth, baseWindowWidth);
        }

        else {
            //System.out.println((double)components[i].getFont().getSize()/newWindowWidth*baseWindowWidth);
            components[i].setFont(new Font(components[i].getFont().getFontName(),components[i].getFont().getStyle(),(int) (((double)components[i].getFont().getSize()/newWindowWidth*baseWindowWidth)*resizeRate)));
        }
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
FlawTECH
  • 61
  • 8
  • I would take a slightly different approach. I would start with a "known" size, which would represent a scaled size of "1", then from there you can calculate the scale size off it. Another approach would be to have the "default" size set up using a `Dimension` and initially set to `null`, when `componentResized` is called, you'd check this for `null` and if it's, you'd use the resulting size as your base size. The problem with this, is a component can be sized a number of times when the UI is first established, you can overcome this by using a non-repeating Swing `Timer` set to a low delay – MadProgrammer Apr 28 '17 at 23:42
  • You could also have a look at [this](http://stackoverflow.com/questions/34149453/java-swing-application-too-small-in-hidpi-computers/34152675#34152675) for some ideas about how to scale your UI – MadProgrammer Apr 28 '17 at 23:42
  • And an [example of using a `Timer` and `componentResized`](http://stackoverflow.com/questions/28999349/java-swing-repaint-dont-work-correctly/29000414#29000414) – MadProgrammer Apr 28 '17 at 23:45
  • Also consider `deriveFont()` or a `JComponent.sizeVariant`, for [example](http://stackoverflow.com/a/14599176/230513). – trashgod Apr 28 '17 at 23:56
  • @MadProgrammer thank you both; I'll try using this approach then, and thanks for the tip about the deriveFont method :) – FlawTECH Apr 29 '17 at 00:29

0 Answers0