-3

I want to create a JTextArea which looks like JTextArea, acts like JTextArea, responds like JTextArea, speaks like JTextArea, moves like JTextArea, etc, but is not JTextArea.

To make it short, I'd like to create a custom swing component based 100% on JTextArea. Once I do that, I'll be able to change different otherwise hard-coded properties of a JTextArea and make my own customised JTextArea. There are no predefined swing components that are designed the way I need them to be, but JTextArea is the closest, that why I choose it.

I'd like to change the spacing inbetweem the rows of a JTextArea. And no, I don't want to use JtextPane, I've tried, it doesn't work with my program, it calcualtes it position diferently, it look diferently, and applying the JtextArea border just messes thing up further.

I'm not trying to extend the JTextArea, I'm trying to create a custom JTextArea, as in custom swing component, with changed hard-coded properties that are not configurable trought JTextAreas methods.

However, I have no idea how to do it. I've been looking it up on the internet, but there is only an extensive guide about building your own component from stracth...

Figuring that out will take a lot of time and will not really solve my problem.

Only thing I have to do is create a class (or several classes) that will contain everyting that builds JTextArea. Start from JTextComponent level and copy all the lower level classes that are used in creating JTextArea. I'd also like to note that I use Nibus look and feel, I think that there may be some classes that would need to be included for the custom JTextArea to function properly under that LAF.

I've looked into the swing source code, and it's full of everyting. Figuring out what classes or their parts are used in creating a JTextArea would be a time consuming nightmare, given that I have no knowledge about core swing structure and mechanics.

That's why I'm asking somebody who has the knowledge to at least list the classes that I need to replicate the JTextArea, and I'll then figure out how to compose them.

Because, if I start learning now about swing core mechanics, it'll take days and weeks before I figure it all out, but for someone who knows, it would take only a couple of minutes to list all classes that I need to focus my attention onto.

I'm trying to take a shortcut here. I don't want to fully understand swing, I just want this thing to work. Default spacing is one pixel too low, and all I want to do is just make it that pixel higher. I don't want to know how the painter paints component onto screen, I just want to know where is it called from and what does it call itself...

Thanks to anyone who takes the time.

Karlovsky120
  • 6,212
  • 8
  • 41
  • 94
  • Have you tried simply coping the original code over and renaming it? – Coupon22 Oct 25 '12 at 20:57
  • 2
    Why not just make your class extend JTextArea? That's the point of OO – durron597 Oct 25 '12 at 20:58
  • You didn't get what I'm trying to do here. I'm not doing simple component extending, I'm trying to "code" a completly new swing component (which is 100% based on JTextArea, but still). For that I need the original JTextArea classes located in src folder of JDK... I just don't know which ones... – Karlovsky120 Oct 25 '12 at 21:04
  • Start by naming the things which are "not configurable" – Lukas Knuth Oct 25 '12 at 21:07
  • If it's 100% based on JTextArea, it sounds as if you don't get the point of OO. Otherwise if you absolutely want to completely write your own component, then go ahead as it would make for a good academic exercise. Start by extend JTextComponent, which all text components *must* do, and delve into the source code of JTextComponent, JTextArea, PlainDocument, AbstractDocument, etc... That would be a lot of work, but you would learn much, I'm sure. – Hovercraft Full Of Eels Oct 25 '12 at 21:07
  • 1
    Oh, also, I don't see how anyone can "walk" you through this on this site, as what this will involve will mainly be your studying the source code, and that may take weeks to do so that you fully understand it. Voting to close this question as it really isn't answerable on this site. – Hovercraft Full Of Eels Oct 25 '12 at 21:09
  • I just need a list of classes I'd have to look at. There is bunch of JTextComponent and JTextArea classes in src folder, and I wanted to see which classes to study further... Maybe not study, but to start working from there... If you would just finish this list, it would help me a lot, that is what I only asked for: JTextComponent, JTextArea, PlainDocument, AbstractDocument, etc... – Karlovsky120 Oct 25 '12 at 21:19
  • 4
    re `"I'm trying to take a shortcut here. I don't want to fully understand swing, I just want this thing to work."` -- seriously? really?? – Hovercraft Full Of Eels Oct 25 '12 at 21:20
  • 2
    @Karlovsky120 Honestly, you should consider explaining what you want to achieve rather than say that JTextArea can't do it. Many elements can be configured through XxxUI-properties but they are not directly visible in the API. So if you explain what you are trying to achieve we may find a "standard" way to do it that would be simpler. – Guillaume Polet Oct 25 '12 at 21:25
  • If you're serious about re-writing a text component from the ground up, and want us to outline what you need, it would require most of us 1-2 weeks to go through the source ourselves before we could come up with a viable solution. If you want help from someone who knows this code backwards and forwards, then you're looking for help from one of the authors of Swing, and you won't find any here. Seriously the realistic way to do this is to either extend JTextArea or use a JTextArea where you change its properties. Your current question as asked is non-answerable in my opinion. And your desire... – Hovercraft Full Of Eels Oct 25 '12 at 21:32
  • ... to just get it working without fully understanding Swing is somewhat insulting in that you'd be asking major effort from us without showing that you'd be willing to put in the same. That's why I'm voting to close this question. – Hovercraft Full Of Eels Oct 25 '12 at 21:32
  • Look at this this way. You want to add a exhaust pipe to your car. you don't need to study how thw whole car works, you just need to look at the old one, see how it was connected and then conenc the new one the same way... And for comment below that, I did addd the explanation... – Karlovsky120 Oct 25 '12 at 21:32
  • Your metaphor won't work as you're not "driving" a car here and you're not "fixing" a car,... you're *creating* one, fully, wholly, out of basic component libraries, so yes, you'd better be willing to put in the effort to fully understand how a car works from top to bottom. – Hovercraft Full Of Eels Oct 25 '12 at 21:33
  • 1
    _add a exhaust pipe to your car_ chances are that you would die of monoxide next time you drive it ;-) Or in other words: there is absolutely _no_ way of creating a custom component as complex as a textComponent without knowing much more about the innards as you do .. (or I do :-) -1 and voting to close this question – kleopatra Oct 26 '12 at 08:04

1 Answers1

6

I'd like to change the spacing inbetweem the rows of a JTextArea

My first thought was that overriding javax.swing.JTextArea#getRowHeight would be sufficient. The javadoc clearly states

Defines the meaning of the height of a row. This defaults to the height of the font.

So I was hoping that by overriding this method, you would adjust the definition and you would get more spacing between the rows. Bummer, didn't work. A quick search on the usages of that method in the JDK revealed the same. It is mainly used to calculate some sizes, but certainly not used when painting text inside the component.

By looking at the source code of the javax.swing.text.PlainView#paint method, I saw that the FontMetrics are used, and those you can easily override in the JTextArea. So second approach was to extend the JTextArea (bwah, extending Swing components but it is for a proof-of-concept)

  private static class JTextAreaWithExtendedRowHeight extends JTextArea{
    private JTextAreaWithExtendedRowHeight( int rows, int columns ) {
      super( rows, columns );
    }

    @Override
    public FontMetrics getFontMetrics( Font font ) {
      FontMetrics fontMetrics = super.getFontMetrics( font );
      return new FontMetricsWrapper( font, fontMetrics );
    }
  }

The FontMetricsWrapper class basically delegates everything, except the getHeight method. In that method I added 10 to the result of the delegate

@Override
public int getHeight() {
  //use +10 to make the difference obvious
  return delegate.getHeight() + 10;
}

And this results in more row spacing (and a caret which is way too long, but that can probably be adjusted).

A little screenshot to illustrate this (not as nice as some of the other ones, but it shows that this approach might work):

Difference between regular text area and extended one

Small disclaimer: this feels like an ugly hack and might result in unexpected issues. I do hope somebody comes with a better solution.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Robin
  • 36,233
  • 5
  • 47
  • 99
  • 2
    Give you a 1+ on that! But remember, he is dead set against extending JTextArea. Why? Lord only knows. – Hovercraft Full Of Eels Oct 25 '12 at 22:28
  • 1
    You should post this (or a link to it) on his other question with a bounty: http://stackoverflow.com/questions/13001238/creating-custom-swing-component-out-of-existing – Nick Rippe Oct 26 '12 at 00:32
  • @HovercraftFullOfEels from the earlier questions, I suspect that he's doing something so wrong elsewhere that he grabs at straws ... just saying .. +1 for the nice digging, wouldn't have expected that setting the line spacing is unsupported, even my grandfather's typing machine could do it :-) – kleopatra Oct 26 '12 at 08:07
  • 2
    @kleopatra I was more surprised that overriding the `getRowHeight` method simply adjusts some sizes, but leaves the row height unaffected. Meaning that when you create a text area with 30 rows (passed in the constructor), you actually end up with a text area where the preferred size allows for much more then 30 rows ... – Robin Oct 26 '12 at 08:39
  • good catch, haven't thought of that :-) – kleopatra Oct 26 '12 at 08:41