Avatar billede Slettet bruger
23. februar 2005 - 13:35 Der er 5 kommentarer og
1 løsning

Font størrelse skal følge størrelse på JLabel

Hej,

Jeg vil gerne at font størrelsen brugt i en JLabel følger størrelsen på JLabel'en. Altså når JLabel'en bliver resized, så sættes der en ny font, der passer med den nye størrelse.

Jeg har fundet frem til følgende, som virker:

class AntiAliasJLabel extends JLabel implements ComponentListener {
    private static Graphics2D g2;

    public AntiAliasJLabel() {
        addComponentListener(this);
    }

    public void paint(Graphics g) {
        g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        super.paint(g2);
    }

    synchronized public void componentResized(ComponentEvent e) {
        final SwingWorker worker = new SwingWorker() {
            private Font font;
            private Insets insets = getInsets();
            private int windowWidth = getWidth() - insets.left - insets.right;
            private int windowHeight = getHeight() - insets.top - insets.bottom;
            private int fontSize = windowHeight;
            private FontMetrics metrics;
            private int height, width;
            public Object construct() {
                // executed in background thread
                do {
                    font = new Font("Verdana", Font.BOLD, fontSize--);
                    metrics = getGraphics().getFontMetrics(font);
                    height = metrics.getHeight();
                    width = metrics.stringWidth(getText());
                } while (height > windowHeight || width > windowWidth);
                return null;
            }
            public void finished() {
                // executed in event dispatching thread
                setFont(font);
            }
        };
        worker.start();
    }

    public void componentMoved(ComponentEvent e) {
    }

    public void componentShown(ComponentEvent e) {
    }

    public void componentHidden(ComponentEvent e) {
    }
}

Problemet med ovenstående er, at det tager et stykke tid (nogle sekunder) at udregne fontstørrelsen. Er der nogle, der kan komme op med en bedre metode til dette?
Avatar billede _carsten Nybegynder
23. februar 2005 - 15:29 #1
Du kan jo minimere beregningerne voldsomt ved at bruge denne her

font = new Font("Verdana", Font.BOLD, fontSize-=10);

og stadig opnå samme resultat
Avatar billede Slettet bruger
23. februar 2005 - 15:37 #2
Ja klart, men så vil fonten jo ofte passe dårligere.
Avatar billede _carsten Nybegynder
24. februar 2005 - 11:50 #3
Ja, det er selvfølgelig rigtig

Jeg har lavet lidt om på din AntiAliasJLabel(), prøv lige at teste den - tror vi er ved at være der.


class AntiAliasJLabel extends JLabel implements ComponentListener {
    private static Graphics2D g2;
    private Font font;
    private Insets insets;
    private int windowWidth;
    private int windowHeight;
    private int fontSize;
    private FontMetrics metrics;
    private int height, width;
   
    public AntiAliasJLabel() {
        addComponentListener(this);
        insets = getInsets();
        windowWidth = getWidth() - insets.left - insets.right;
        windowHeight = getHeight() - insets.top - insets.bottom;
        fontSize = windowHeight;
        font = new Font("Verdana", Font.BOLD, 10);
    }

    public void paint(Graphics g) {
        g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        super.paint(g2);
    }

    public void componentResized(ComponentEvent e) {
        windowWidth = getWidth() - insets.left - insets.right;
        windowHeight = getHeight() - insets.top - insets.bottom;
        fontSize = font.getSize();
       
        metrics = getGraphics().getFontMetrics(font);
        width = metrics.stringWidth(getText());

        double faktor = (double)windowWidth / (double)width;
        fontSize  = (int)Math.floor( ((double)fontSize * faktor) );

        if(fontSize > windowHeight){
            fontSize = windowHeight ;
        }

        font = new Font("Verdana", Font.BOLD, fontSize-2);
        setFont(font);   
    }

    public void componentMoved(ComponentEvent e) {
    }

    public void componentShown(ComponentEvent e) {
    }

    public void componentHidden(ComponentEvent e) {
    }
}
Avatar billede Slettet bruger
25. februar 2005 - 11:37 #4
Jeg har i mellemtiden droppet Swing helt, og bruger bare Graphicd2D pakken til at tegne strengen i den rigtige størrelse. Så spørgsmålet er ikke længere relevant for mig.

Hvis du vil have points for din indsats, kan du bare lægge et svar.
Avatar billede _carsten Nybegynder
25. februar 2005 - 11:56 #5
Jeg vil selvfølgelig ikke være ked af at få point, når jeg nu har brugt energi på det, men jeg forstår udmærket godt dit valg.
Avatar billede Slettet bruger
25. februar 2005 - 12:02 #6
Det skal du selvfølgelig også have.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester