CodeGuy
CodeGuy

Reputation: 28907

JLabel width doesn't seem right

I have a very long JLabel of width 80000. It sits in a panel that is of width 80000. However, the label ends with a "..." towards the middle of the panel, meaning it gets cut off. I've set the maximum size, the minimum size, the size, and the preferred size of the JLabel to have a width of 80000. The panel it is in sits inside of a JScrollPane.

Any ideas why the JLabel does not seem to have the width that it actually thinks it has?

Upvotes: 0

Views: 425

Answers (3)

mKorbel
mKorbel

Reputation: 109813

for example Font and String

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class JLabelIntoJScrollPane {

    private JFrame frame = new JFrame();

    public JLabelIntoJScrollPane() {
        AlphaChars aChars = new AlphaChars();
        String str = aChars.getNext(80000);
        JTextArea textarea = new JTextArea(str);
        textarea.setLineWrap(true);
        JScrollPane jScrollPane = new JScrollPane(textarea);

        JLabel label = new JLabel(str);
        label.setPreferredSize(new Dimension(550000, 60)); 
        // replace new Dimension(int, int) with proper way
        // I'd be use TextLayout or one of three methods
        // how to get size from Font and String

        frame.pack();

        final JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(label);

        JScrollPane jScrollPane1 = new JScrollPane(panel);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(jScrollPane, BorderLayout.CENTER);
        frame.add(jScrollPane1, BorderLayout.SOUTH);

        frame.setSize(400, 300);
        frame.setVisible(true);

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                System.out.println(panel.getPreferredSize());
            }
        });
    }

    private class AlphaChars {

        public static final int MIN_LENGTH = 80000;
        private java.util.Random rand = new java.util.Random();
        private char[] AlphaChars = {
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
            'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
            'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '*', '/', '<', '>', '&',
            '#', '@', '{', '}', '?', ':', '_', '"', '!', ')', '('};

        public String getNext() {
            StringBuilder strbuf = new StringBuilder();
            for (int i = 0; i < MIN_LENGTH; i++) {
                strbuf.append(getAlphaChars()[getRand().nextInt(getAlphaChars().length)]);
            }
            return strbuf.toString();
        }

        public String getNext(int reqLenght) {
            StringBuilder strbuf = new StringBuilder();
            for (int i = 0; i < reqLenght; i++) {
                strbuf.append(getAlphaChars()[getRand().nextInt(getAlphaChars().length)]);
            }
            return strbuf.toString();
        }

        public java.util.Random getRand() {
            return rand;
        }

        public void setRand(java.util.Random aRand) {
            rand = aRand;
        }

        public char[] getAlphaChars() {
            return AlphaChars;
        }

        public void setAlphaChars(char[] aAlphaChars) {
            AlphaChars = aAlphaChars;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JLabelIntoJScrollPane();
            }
        });
    }
}

Upvotes: 2

Subs
Subs

Reputation: 529

Here's a way:

You can repaint the JLabel with your own custom graphics or text:

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(foregroundImage, x, y, this);
    g.drawString("YOUR BIG STRING");
    jlabel.setBounds(0,0,100,100); //set it to your JLabel bounds...
    jlabel.paint(g);
}

Upvotes: 1

Sbodd
Sbodd

Reputation: 11454

Per Andrew Thompson's comment - post a code sample that demonstrates your problem for better answers.

If you're having problems getting your label to show the string contents...

1) use FontMetrics to figure out what size your string actually needs to be.

Graphics g; //initialize this with your component's Graphics, as passed in to paintComponent
Rectangle2D bounds = g.getFontMetrics().getStringBounds(reallyLongString, g)

2) Remember that the label will have some variable cushion for its margins. This should be equal to its insets, although there may be other items that increase the label's required size beyond the size of the string itself.

Insets i = getInsets();

3) After 1 and 2, you should be able to figure out the size your label needs to be:

minWidth = bounds.getWidth() + i.left + i.right;

4) If that's not sufficient, then there's some other factor I've missed. You could always experimentally test to figure out the threshold - incrementally increase the size of the label until it stops giving you the ellipses.

Upvotes: 1

Related Questions