Code Comments
Programming Forum and web based access to our favorite programming groups.Hello,
I would like to create a JTextArea (without ScrollPane) with a fixed
number of rows which resizes itself so that it is *just* wide enough to
hold the text.
I tried the following:
jTextAreaOnly.setRows(2);
jTextAreaOnly.setLineWrap(true);
jTextAreaOnly.setWrapStyleWord(true);
jTextAreaOnly.setText ("This is my preferred text; more to follow.");
System.out.println (jTextAreaOnly.getPreferredSize());
Output: java.awt.Dimension[width=100,height=32] - regardless of the text
length ?!
No matter what text I set the textarea to, the width is 100.
How can I get the textarea to assume exactly the width needed to display
its text for a given number of rows?
Also, is there means of finding out which text is displayed in which
row? getLineCount(), getLineStartOffset() don't seem to refer to the
visible rows.
The ulterior motive for this is that I want to create a JTable with a
custom multi-row header renderer. I would like to set the number of
header rows but let the column header wrap and assume the minimum width
required.
--
Regards/Gruß,
Tarlika Elisabeth Schmitz
Post Follow-up to this messageOn Wed, 07 Jul 2004 15:09:22 +0100, Tarlika Elisabeth Schmitz wrote: > The ulterior motive for this is that I want to > create a JTable with a custom multi-row header renderer. You might find some useful examples amongst the Tame codes.. <http://www.physci.org/codes/tame/> Unfortunataly the applet I wrote to launch them is not smart enough to deal with Tame's MultiLineHeaderExample.. :-( -- Andrew Thompson http://www.PhySci.org/ Open-source software suite http://www.PhySci.org/codes/ Web & IT Help http://www.1point1C.org/ Science & Technology
Post Follow-up to this messageDear Andrew, Andrew Thompson wrote: > On Wed, 07 Jul 2004 15:09:22 +0100, Tarlika Elisabeth Schmitz wrote: > > > > > You might find some useful examples > amongst the Tame codes.. > <http://www.physci.org/codes/tame/> Thank you for providing all those useful examples on your website. I had a look at MultiLineHeaderRenderer, but as far as I understand the code this is not quite what I am looking for. (Correct me if I am wrong.) I want the header text to wrap automatically - just like it does in a JTextArea with wordwrap set to true. -- Regards/Gruß, Tarlika Elisabeth Schmitz
Post Follow-up to this messageOn Wed, 07 Jul 2004 15:56:40 +0100, Tarlika Elisabeth Schmitz wrote: > > Thank you for providing all those useful examples on your website. (shrugs) I just host the Tame examples, I myself am grateful to Nobuo Tamemasa, the author of the codes.. > I had a look at MultiLineHeaderRenderer, but as far as I understand the > code this is not quite what I am looking for. A pity. >..(Correct me if I am wrong.) I must admit that I have not had much time to look carefully at the code itself, though I have had contact with two people who suggested fixes for some slight quirks in the codes (mostly due to the API not being completely settled in before the codes were effectively complete). I hope to get those changes incorporated in a new release before the end of the year. Hope you find your answer.. -- Andrew Thompson http://www.PhySci.org/ Open-source software suite http://www.PhySci.org/codes/ Web & IT Help http://www.1point1C.org/ Science & Technology
Post Follow-up to this messageAndrew Thompson wrote: > On Wed, 07 Jul 2004 15:56:40 +0100, Tarlika Elisabeth Schmitz wrote: > (shrugs) I just host the Tame examples, > I myself am grateful to Nobuo Tamemasa, > the author of the codes.. I thought they looked just like Nobuo Tamemasa's screenshots! I picked up a few ideas from him before. -- Regards/Gruß, Tarlika Elisabeth Schmitz
Post Follow-up to this message
"Tarlika Elisabeth Schmitz" <invalid@invalid.invalid> wrote in message
news:2l2egkF7nnpcU1@uni-berlin.de...
> Hello,
>
> I would like to create a JTextArea (without ScrollPane) with a fixed
> number of rows which resizes itself so that it is *just* wide enough to
> hold the text.
>
> I tried the following:
>
> jTextAreaOnly.setRows(2);
> jTextAreaOnly.setLineWrap(true);
> jTextAreaOnly.setWrapStyleWord(true);
> jTextAreaOnly.setText ("This is my preferred text; more to follow.");
> System.out.println (jTextAreaOnly.getPreferredSize());
>
> Output: java.awt.Dimension[width=100,height=32] - regardless of the text
> length ?!
>
> No matter what text I set the textarea to, the width is 100.
With something like word warp, the fixed width determines the word wrap, not
the other way around.
So, you need to decide how wide you want the area to be, or how many lines
you want the area to be. You may have some heuristics you'd like to use, but
you'll need to set those up as well. For example, if you have a string: "one
two three four five", this can be represented as:
"one two three four five"
"one two three
four five"
"one two
three
four
five", etc.
Even if you fix the rows, you'll neet to try different aspects to get it
right.
"one two three four
five"
"one two three
four five"
"one two
three four five"
I think you want the second version, but it literally takes trial and error
to figure out what is "correct". As you can imagine, setting a max width and
wrapping to margins with a floating bottom border is much easier.
To figure it out, you should try calculating sizes based on the
FontMetrics/LineMetrics of the words, and writing your own word wrap logic.
Of course wrapping the same text over and over again to get it to fit "just
right" can be expensive, depending on the amount of text.
Regards,
Will Hartung
(willh@msoft.com)
Post Follow-up to this messageHello Will, Will Hartung wrote: > "Tarlika Elisabeth Schmitz" <invalid@invalid.invalid> wrote in message > news:2l2egkF7nnpcU1@uni-berlin.de... > > With something like word warp, the fixed width determines the word wrap, n ot > the other way around. > You're right - you saw the flaw in my idea and this is the right answer even though I don't like it :-( > Even if you fix the rows, you'll neet to try different aspects to get it > right. > "one two three four > five" > "one two three > four five" > "one two > three four five" > > I think you want the second version, but it literally takes trial and erro r > to figure out what is "correct". Yep. It looks trivial though as the human brain can see the "right" configuration in a split second. > To figure it out, you should try calculating sizes based on the > FontMetrics/LineMetrics of the words, and writing your own word wrap logic . > Of course wrapping the same text over and over again to get it to fit "jus t > right" can be expensive, depending on the amount of text. It wouldn't be too expensive as the titles are only between 20 and 40 chars maybe. But of course to come up with an algorithm that goes through all permutations for a set row number (either 1, 2 or 3 maybe) will take a little thought. Thanks again for thinking this through. -- Regards/Gruß, Tarlika Elisabeth Schmitz
Post Follow-up to this message"Tarlika Elisabeth Schmitz" <invalid@invalid.invalid> wrote in message news:2l37snF83sldU1@uni-berlin.de... > Yep. It looks trivial though as the human brain can see the "right" > configuration in a split second. It's a "hard problem". logic. "just > > It wouldn't be too expensive as the titles are only between 20 and 40 > chars maybe. But of course to come up with an algorithm that goes > through all permutations for a set row number (either 1, 2 or 3 maybe) > will take a little thought. It's probably not super hard. Here's what I would try. Break the text into indvidual words. Get the rectangle for a "space". Calculate the rectangle for each word. Add up the widths of the words with a single space between them (using the space rectangle). This gives you the rough "overall" distance. Decide on the number of rows (I think you mentioned 2). You can use the overall width to guess the number of rows. For example, perhaps you want "as small as possible under 100 pixels", so if you get a string 350 pixels long, then you guess "4 lines". Divide the total width by that number, that gives you your "margin bell" to use an old typewriter analogy. Starts adding words and spaces until you hit your margin. When you do, "add a line" and keep going. Now you have a list of lines, and you can find the size of the entire paragraph. The problem happens when you have somthing like: "Name the movie that uses the word 'supercalifragulisticexpialidotious' instead of the the word 'neeto'" You can imagine that your "margin word" is going to be that monster, but ideally that will be rare. But that's a "quick hack" that can do the job "most of the time" I think, and it's pretty cheap to figure out. The other thing you can do is do the same technique, but use several different line counts (2, 3, 4), and then you can simply use the area to find "the smallest rectangle", that way you don't fix the number of lines, just guesstimate it. By getting the smallest rectangle, you should minimize total wasted space on the line ends (which is what you're really after anyway) [the key there is to make sure you always don't end up with a single line, which is, of course "most efficient".] It's brute force, but the potential expensive part is getting the bounding box on the word, and that's only done once, up front. Text processors spend a lot of time on this problem, particularly when you can tweak the words a little bit, bend the font kerning, use hyphenation, etc. This problem comes up when they try to do full justification of text in paragraphs. Knuth spent a lot of time on it in TeX. > Thanks again for thinking this through. Always like puzzling interesting problems a little bit. Regards, Will Hartung (willh@msoft.com)
Post Follow-up to this message
Tarlika Elisabeth Schmitz wrote:
> I would like to create a JTextArea (without ScrollPane) with a fixed
> number of rows which resizes itself so that it is *just* wide enough to
> hold the text.
>
> I tried the following:
>
> jTextAreaOnly.setRows(2);
> jTextAreaOnly.setLineWrap(true);
> jTextAreaOnly.setWrapStyleWord(true);
> jTextAreaOnly.setText ("This is my preferred text; more to follow.");
> System.out.println (jTextAreaOnly.getPreferredSize());
>
> Output: java.awt.Dimension[width=100,height=32] - regardless of the text
> length ?!
>
> No matter what text I set the textarea to, the width is 100.
>
the 100 is a "magic number" set initially in WrappedPlainView if the
lineWrap is true.
> How can I get the textarea to assume exactly the width needed to display
> its text for a given number of rows?
>
As already (I'm a bit late here :-) mentioned: that's not supported.
A clean way to get it would be to provide a custom ViewFactory, but as
far as I can see that would involve subclassing BasicTextUI - everything
in JTextArea is "plain" so there are no hooks to plugin such a factory.
Another possibility is to set the columns as well - it's an
approximation but might work:
1 start with setting the columns to doc.length/rows.
2 check how many chars are left-over in the next row (the first that
should not be showing.
3 increment the columns "reasonably" - you can go to 2 again to check
>
> The ulterior motive for this is that I want to create a JTable with a
> custom multi-row header renderer. I would like to set the number of
> header rows but let the column header wrap and assume the minimum width
> required.
Just curious - what should happen on resizing the columns?
Greetings
Jeanette
Post Follow-up to this messageHallo Jeanette, Kleopatra wrote: > > Tarlika Elisabeth Schmitz wrote: > > the 100 is a "magic number" set initially in WrappedPlainView if the > lineWrap is true. I searched around in xxxUI but never came across this - do you know the Swing API by heart ;-) ? > As already (I'm a bit late here :-) mentioned: that's not supported. I know, I know; but I find this a really reasonable request ;-) For one line table headers I managed to set the column size to Max(fieldDisplayWidth, HeaderWidth). You see, I don't want to hard-code column widths for each bloody table. I have business object fields, they are of certain types, if they are Strings they are of a certain length, and they have localizable titles,mnemonics,tooltips. The titles are used as field labels but might also be used as column headers. So, I don't want to stick newlines in "by hand". I am simply looking for as generic an approach as possible. Granted, when it comes to designing the form, not all can be done automagically. But for a table, it should suffice to write myTable.setNoOfHeaderRows(2); myTable.setNoOfVisibleColumns (5); (for this one I will start another thread, Jeanette) <ot> Many years ago, long before Java existed, I worked on a GUI project with 100+ forms. The crap front-end didn't allow for much automation. I spend ages working out optimum layout arrangements (similar to Karsten's FormLayout), working out column widths etc. Then got someone to "draw" them. Nightmare. They called me Mrs Pixel because I always spotted it when a border was out by a pixel. Now, with all this Java technology, the kind of semi-generated GUI I was envisaging then, is only a stone's throw away. </ot> > A clean way to get it would be to provide a custom ViewFactory, but as > far as I can see that would involve subclassing BasicTextUI - everything > in JTextArea is "plain" so there are no hooks to plugin such a factory. At some point (not during this project) I would like to create my own GUI components, stuff that I keep on re-using and that behaves in a certain way. I realize that, to make a proper job of it, I'll have to provide each component with its UI delegate rather than just fudging some subclasses ... At the moment I have only time for quick fudges :-( I haven't through this through completely (it's just the sort of idea that you wake up with first thing in the morning): I think what has to be done is: a) split String into whitespace separated words b) arrange words in all possible permutations on lines 1-n (n is a given); not all lines have to be occupied c) measure width of lines 1-n for each permutation d) choose the one with the smallest Max(line_1_Width,...,line_n_Width) I don't think performance is a problem as we're only talking about 4-5 words at maximum and a maximum of 3 lines. b - how to loop through all permutations will take a bit of thought. Now, where should this logic go? I have to admit I am fairly new to Java, so my ideas might be a bit rough around the edges. I presume, if I was to create a JMultiRowHeader this would have to be placed in BasicMultiRowHeaderUI. After all, all I want is a getPreferredSize(). > > > Just curious - what should happen on resizing the columns? Good point. But come to think about it: If the user squashes his columns and if a column is too small to display the whole cell - tough. You just get an ellipsis. What should happen to the header? Just emulate the behaviour of a squashed JTextArea. I think the most important thing is that the table looks good when fired up. If the user wants to squeeze the columns, for instance in order not to have to scroll to the ones outside the viewport*, fine. By then he knows what each column is. *See thread JTable "AUTO_RESIZE and horizontal scrolling" which you answered yesterday, Jeanette. http://groups.google.co.uk/groups?d...ava .gui -- Regards/Gruß, Tarlika
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.