从现有的创建自定义swing组件 [英] Creating custom swing component out of existing

查看:122
本文介绍了从现有的创建自定义swing组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有这个JTexrtArea几乎完全符合我的需求。唯一不对的是线间距。我无法设置它。 (为什么不用JTextPane?因为间距可以在JTextArea中更改,JTextArea比JTextPane更轻,我的程序中有很多这样的。)

So, I have this JTexrtArea which is almost perfect for my needs. The only thing wrong with it is the line spacing. I can't set it. (Why not JTextPane? Because spacing CAN be changed in JTextArea and JTextArea is way lighter thatn JTextPane, and I have a bunch of those in my program).

我问过之前这个问题,这就是我得到的答案来自用户StanislavL:

I have asked this question before, and this is the answer that I got from user StanislavL:

要覆盖JTextArea的行间距,请查看PlainView(用于渲染PLainDocument)。

To override JTextArea's line spacing take a look at the PlainView (used to render PLainDocument).

public void paint中有以下几行(Graphics g,Shape a)方法

There are following lines in the public void paint(Graphics g, Shape a) method

    drawLine(line, g, x, y);
    y += fontHeight;

因此,您可以调整渲染修正y偏移。

So you can adapt the rendering fixing y offset.

在BasicTextAreaUI方法中创建视图。将其替换为您自己的PlainView实现

In the BasicTextAreaUI method to create view. Replace it with your own implementation of the PlainView

public View create(Element elem) {
Document doc = elem.getDocument();
Object i18nFlag = doc.getProperty("i18n"/*AbstractDocument.I18NProperty*/);
if ((i18nFlag != null) && i18nFlag.equals(Boolean.TRUE)) {
    // build a view that support bidi
    return createI18N(elem);
} else {
    JTextComponent c = getComponent();
    if (c instanceof JTextArea) {
    JTextArea area = (JTextArea) c;
    View v;
    if (area.getLineWrap()) {
        v = new WrappedPlainView(elem, area.getWrapStyleWord());
    } else {
        v = new PlainView(elem);
    }
    return v;
    }
}
return null;
}






我掌握了一般的想法他告诉我要做什么,但我不知道该怎么做。
另外,我不想覆盖默认的JTextArea属性,我想有一个选择 - 使用默认的或使用自定义的。


I grasp the general idea of what he's telling me to do, but I don't know how to do it. Also, I wouldn't like to override the default JTextArea "property", I'd like to have a choice - to use the default one or to use a custom one.

只有JTextArea代码的更改才能来自

Only change in JTextArea code would be from

y + = fontHeight

y + =(fontHeight +(或 - )additionalSpacing)

我如何实现这一目标?
我使用/复制哪些课程?
我在哪里放?
如何使它们可用?
如何使整个工作正常工作?

How do I achieve this? Which classes do I use/copy? Where do I put them? How do I make them usable? How do I get the whole thing working?

如果您认为这太具体而无用,也许有人可以写一般的教程如何在现有的基础上100%创建自定义swing组件。然后有人可以轻松地改变一些值,以便更好地根据需要进行调整。

推荐答案

我只想复制-paste 我的回答来自你的其他问题

I am simply going to copy-paste my answer from your other question.


我想改变JTextArea行的间距

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

我的第一个想法就是重写 javax.swing.JTextArea#getRowHeight 就足够了。 javadoc明确说明

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.

所以我希望通过覆盖这个方法,你可以调整定义,你会在行之间获得更多间距。糟糕,没有工作。在JDK中快速搜索该方法的用法显示了相同的内容。它主要用于计算某些大小,但在组件内部绘制文本时肯定不会使用。

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.

通过查看 javax的源代码.swing.text.PlainView #paint 方法,我看到使用 FontMetrics ,以及那些你可以在<$ c $中轻松覆盖的方法C>的JTextArea 。所以第二种方法是扩展 JTextArea (bwah,扩展Swing组件,但它用于概念验证)

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 );
    }
  }

FontMetricsWrapper class基本上委托除了 getHeight 方法之外的所有内容。在该方法中,我将10添加到委托的结果中

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.

我个人更喜欢StanislavL提出的解决方案,但这会为您提供另一种选择

I personally prefer the solution StanislavL is proposing, but this gives you an alternative

这篇关于从现有的创建自定义swing组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆