views:

39

answers:

3

I have a JLabel that needs to display some html-formatted text. However, I want to restrict this to being 4 lines long (and if so, provide a button to see everything).

So far, I've tried setting the maximum size manually or via a layout manager. However, both of these solutions can cause part of a line to be displayed.

edit: To add a little more details, I need to force 4 lines even when respecting line wrapping correctly, resizing components, and changing font sizes. I've considered handling resize/fontsize changes by replacing the label with a new one that fits correctly.

JLabel seems to handle incomplete tags well, so I could probably do something like a binary search on the input string finding which character would cause it to go over the 4 line limit (using FontMetric to determine how many pixels 4 lines would be), and then replacing an existing label with the new one. The big downside to this approach is that I need to run the computation every time the user resizes the panel or changes fonts (and it feels like a dirty dirty hack).

A: 

I would try running through the String of text and removing all text after the third "\n"

    String shortenText(String oldtext){
        String newText = "";
        for(int i=0;i<3;i++){
            newText += oldtext.substring(0,oldtext.indexOf("\n"));//adds one line to String
            oldtext = oldtext.substring(indexOf("\n")+1);//shorten old string to prepare for next iteration
        }


    return newText;
}

You may also want to try the same algorithm, except strip of <p> and <br> tags as well...

If you know the values of the possible tags just switch the text from "\n" to "<br>" or any tag you need

Grue
HTML doesn't use "\n" for new lines, it use the <br> tag.
camickr
I just realized that after posting and fixed it, thanks though
Grue
This is okay if the only case to be concerned about is breaks, paragraphs, list items, etc. However, JLabel also handles line wrapping nicely. So if a given line of the input is too many characters across, the label will wrap them to the next line. (The line wrapping is important for my uses since the user can resize the panel creating the label to arbitrary sizes and it should still limit to 4 lines.)
Mike
Since css doesnt work on Swing components, the only other option i can think of is using the pre tag... im still not sure how effective that would be though.
Grue
+1  A: 

Add the JLabel to a JScrollPane as set the scrollpane with a reasonable preferred size. Scrollbars will appear a necessary.

I don't know of any absolute solution to the questions since I doubt you can define what a "line" is. One line of text may be font 12 and another 24. I don't know of any way to calculate the height of each given line.

Even if you did use a ComponentListener to handle the componentResized() event I'm not sure you can come up with a reasonable algorithm to to calculate the exact width/height of of a 4 line display.

camickr
A: 

Hey, I found a way that works. The framework I'm working with allows me to create a listener for font size changes. In this listener, I determine what the new max size of the label is (getFontMetrics(font).getHeight() * 4) and then re-set the maximum height on the label to this and then relayout everything. This even handles the word wrap case well. I'm guessing that someone could do nasty things with silly HTML input, but this covers the 99% case pretty well.

Mike
To clarify, I'd be really surprised if any of my users would enter anything other than simple bold/italics/underline. Maybe a list or a break to separate lines, but font tags and the like are something I'm not concerned about until I have someone present a real use case for one.
Mike