如何在Swing L&F中查询当前的抗锯齿设置?

谢尔盖·塔切诺夫(Sergei Tachenov)

TL; DR:设置Graphics实例以使用默认设置呈现字符串的最简单,最正确的方法是什么?或者如何使用默认的抗锯齿设置呈现字符串,使其看起来像JLabel?问题的更详细说明如下...

我正在尝试创建一个自定义JComponent子类。实际上,它是一种TableCellRenderer能够显示富文本格式的文件。扩展JEditorPane太繁琐,太慢(实际上尝试过),并且JLabel无法显示富文本,因此我决定实现自己的,轻量级的和快速的。现在,(显然)它需要在中绘制一些文本paintComponent(),并且我希望此文本在所有其他文本组件(如JLabel)中都看起来像。

但是,当我这样做时,它似乎使用了与应用程序其余部分不同的抗锯齿设置,因此它看起来很丑陋。我意识到我可以强制Graphics转换Graphics2D为使用适当的API,但是问题是,要使用什么确切的设置?也就是说,setRenderingHint()作为第二个参数传递给什么

我可以通过使用各种AA值使它在系统上看起来不错,但是在其他具有不同默认AA设置的系统上,它不会突然变得糟糕吗?

我尝试查看JLabel和LabelUI的源代码,但它们似乎使用了很多黑魔法,例如使用来查询某些神秘属性JComponent.getClientProperty()SwingUtilities2而Swing甚至都不包含这些属性当然,我可以尝试模仿这一点,但这太麻烦了,而且b)不得不使用一些没有太多文档证明的功能,这些功能不能保证拥有稳定的API。

也许有一种方法可以重用一些现有的UI委托?基本上,我只希望我的文本看起来与所显示的完全相同JLabel我什至可以使用JLabel或其子类的实例作为一种“橡皮图章”来绘制文本,但这看起来有些丑陋,而且我不确定性能。我意识到JTable实际上确实可以做到这一点,但是使用aJLabel绘制整个单元格是一回事,使用它绘制部分单元格感觉并不对。例如,某些L&F可能会JLabel以一种看起来很难看的特殊方式装饰它们

理想情况下,我想使用以下代码(虚构代码):

((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    JLabel.getDefaultUI().getRenderingHint());

或者更好(设置所有内容,而不仅仅是AA):

JLabel.getDefaultUI().setupGraphics(g); // this sets up g just like for drawing a JLabel

但是据我看来,似乎没有如此简单的事情。

亚戈·门德斯·维达尔

有时候我们看不到森林的树木...

和JLabel无法显示富文本

如果您需要在表格渲染器中使用富文本格式,那么(也许)就是问题所在!JLabel实际上,确实可以通过HTML [Doc]呈现富文本,甚至您也可以JXLabelSwingX使用它实现更多功能(旋转!换行!)。

考虑到DefaultTableRenderer实际上是一个JLabel可能,您可以扩展它并进行简单的修改:

public class AATableRenderer extends DefaultTableCellRenderer {

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        DefaultTableCellRenderer c = (DefaultTableCellRenderer) super
                .getTableCellRendererComponent(table, value, isSelected,
                        hasFocus, row, column);

        String text = c.getText();

        // Do some style transformations maybe...

        c.setText("<html>" + text + "</html>");

        return c;
    }

}

或者您可以JTableprepareRenderer()方法中修改您

public class AATable extends JTable {

    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component c = super.prepareRenderer(renderer, row, column);

        if (c instanceof JLabel) {
            JLabel l = (JLabel) c;
            String text = l.getText();

            // Do some style transformations maybe...

            l.setText("<html>" + text + "</html>");
        }

        return c;
    }

}

但是也许您不能使用HTML东西……在这种情况下,如果必须坚持使用自定义组件,则可能必须按照外观来进行操作,因为每种外观都是以自己的方式进行管理的。例如,请注意,有时会在系统中设置此属性,并且大多数Swing L&F都会尊重它们(Windows 7在“我的电脑”>“属性”>“高级系统配置”>“性能”>“平滑字体(在列表中选中)”中进行配置。

我不认为您可以重用LabelUI(基本的),因为当您只想要平滑时,也许所有的魔术都会干扰您想要绘制的方式...不确定,这不是没有可能,但我不能说。

这是原始问题的答案

简短答案

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

长答案

您的组件使用不同设置的原因是因为Swing使用绘画的委托体系结构:L&F保留每种类型的组件的委托原型,实例化一个组件时,将创建并注入委托,然后进行绘画(和行为)。当您仅实现该paintComponent(Graphics)方法时,您将跳过所有该体系结构并直接进行绘制,并且缺少那些可能在委托中完成的设置*。[文档]

完成自定义组件的最适当的方法(“适当”并不总是最好的解决方案!!)的方法是构建UI委托,注册它并执行适当的过程。[文件]

无论如何,这是一项冗长而繁琐的工作,因此请实践一下:如果您的应用程序仅使用一种外观,如果您不打算重用此组件,并且您的时间限制不允许您花费大量时间来开发应用程序,单个组件...如果只需要对组件进行抗锯齿设置,请使用以下代码段:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;

public class AAComponent extends JComponent {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // Maybe you want to skip this, up to your needs...

        Graphics2D g2 = null;
        try {
            g2 = (Graphics2D) g.create();

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // Your painting procedures
        } finally {
            if (g2 != null) {
                g2.dispose();
            }
        }
    }

}

也许g2看起来的实例化有点怪异,但它是最佳的,它是一种不传播您的更改的方法,Graphics并且计算成本不到最小。另外,如果要将抗锯齿传播到超类绘画(在这种情况下JComponent不执行任何操作),只需在设置渲染提示后调用super实现即可。

*这有点不准确,因为配置不一定依赖L&F,而是与委托结合使用,但是我认为这是说明发生情况的好方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在R中为rgl设置抗锯齿属性?

来自分类Dev

如何在Java Swing中重叠面板?

来自分类Dev

如何在Java Swing中删除行?

来自分类Dev

如何在Java Swing中抓住鼠标?

来自分类Dev

如何在Swing中打印HashMap?

来自分类Dev

如何在Swing中创建随机矩阵?

来自分类Dev

如何在Swing中创建此组件?

来自分类Dev

如何在 Java Swing 中对齐组件?

来自分类Dev

如何在Wine中启用字体抗锯齿功能?

来自分类Dev

如何在JavaFX字体中强制使用抗锯齿?

来自分类Dev

如何在Moderngl EGL后端中启用抗锯齿?

来自分类Dev

如何在Android Java中关闭Imageview的抗锯齿

来自分类Dev

如何在Wine中启用字体抗锯齿功能?

来自分类Dev

如何在Notepad ++ 6.7.9.2中禁用抗锯齿

来自分类Dev

如何在Notepad ++中打开/关闭字体抗锯齿功能?

来自分类Dev

如何在Firefox中打开抗锯齿功能?

来自分类Dev

如何在Java中编写抗锯齿程序

来自分类Dev

如何在Swing中设置工具提示的背景?

来自分类Dev

如何在Java Swing中设置按钮的背景图像

来自分类Dev

如何在Java中为Swing组件设置字体粗细

来自分类Dev

如何删除PDF图像中的抗锯齿?

来自分类Dev

如何在Java Swing中调整面板中的图像?

来自分类Dev

如何在Java swing中为按钮网格实现actionlistener?

来自分类Dev

如何在Swing中制作此GUI布局

来自分类常见问题

如何在Java GUI swing中制作更多按钮

来自分类Dev

Java Swing:如何在JPanel中删除JButton的默认间距

来自分类Dev

如何在Java Swing应用程序中显示地图?

来自分类Dev

如何在Java Swing中同步两个视图

来自分类Dev

如何在JFileChooser Swing组件中列出最近使用的文件

Related 相关文章

热门标签

归档