简体   繁体   中英

how to make Jspinner change size to fit the content

I want jspinner to resize to fit the content properly I have a SpinnerListModel with the Fonts of my operating system, but when navigating between the options there are some of them that do not enter correctly in the space of the Jspinner

Is there any way for Jspinner to dynamically resize so that the name of each font enters. Or some way of knowing what the maximum size Jspinner should be so that all fonts can enter.

class Lamina11 extends JPanel{

    public Lamina11(){
        String lista[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        JSpinner control= new JSpinner(new SpinnerListModel(lista));
        control.setPreferredSize(new Dimension(100,20));

        add(control);
    }
}

You can use getFontMetrics and getFont on the JFormattedTextField of the DefaultEditor of the JSpinner .

You can do this manually to find maximum preferred width beforehand, like so:

import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GraphicsEnvironment;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.SpinnerListModel;

public class Main extends JPanel {

    public Main(){
        String lista[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        JSpinner control= new JSpinner(new SpinnerListModel(lista));

        JFormattedTextField ftf = ((DefaultEditor) control.getEditor()).getTextField();
        final FontMetrics fmetrics = ftf.getFontMetrics(ftf.getFont());
        int maxWidth = 0;
        for (final String fontName: lista)
            maxWidth = Math.max(maxWidth, fmetrics.stringWidth(fontName));
        //maxWidth = Math.max(maxWidth, ftf.getPreferredSize().width); //Optional. Make this call if 'lista' could be empty.
        ftf.setPreferredSize(new Dimension(maxWidth, fmetrics.getMaxAscent() + fmetrics.getMaxDescent()));

        add(control);
    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame("JSpinner fit content size");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Main());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

By " dynamically " you mean you will have some room to spare for the JSpinner to increase or decrease its size according to the selected value, wright? Then you can do this in a ChangeListener , like so:

import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GraphicsEnvironment;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerListModel;

public class DynamicMain extends JPanel {

    public DynamicMain() {
        String lista[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        JSpinner control= new JSpinner(new SpinnerListModel(lista));

        //Add ChangeListener to change the size for each change in the selected value:
        control.addChangeListener(e -> {
            final JFormattedTextField ftf = ((JSpinner.DefaultEditor) control.getEditor()).getTextField();
            final FontMetrics fmetrics = ftf.getFontMetrics(ftf.getFont());
            final int maxHeightForASingleLine = fmetrics.getMaxAscent() + fmetrics.getMaxDescent();
            ftf.setPreferredSize(new Dimension(fmetrics.stringWidth((String) control.getValue()), maxHeightForASingleLine));
            revalidate();
            repaint();
        });

        //Note the initial size of the JFormattedTextField will depend on the currently selected value of the model.

        add(control);
    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame("JSpinner fit content size");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new DynamicMain());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM