Custom swing JTextComponent [closed]

孤人 提交于 2019-12-13 22:28:01

问题


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.


回答1:


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):

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



来源:https://stackoverflow.com/questions/13077106/custom-swing-jtextcomponent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!