JTextArea不可选,但仍显示“重影”。光标 [英] JTextArea not selectable, but still showing a "ghost" cursor

查看:225
本文介绍了JTextArea不可选,但仍显示“重影”。光标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将JTextArea放在JPanel中。这张JPanel背景上有一张图片,而JTextArea是半透明的(透明的红色)来显示背景。我不希望用户能够编辑或选择文本,我希望它只是作为一个JLabel(但有多行,易于自动换行并调整到屏幕调整大小)。

I put a JTextArea in a JPanel. This JPanel has a picture on the background, and the JTextArea is translucent (translucid red) to show the background through. I don't want the user to be able to edit or select the text, I want it to act just as a JLabel (but with multiple lines and easy to word wrap and adjust to screen resize).

我尝试了所有这些选项:

I tried all these options:

text.setEditable(false);
text.setFocusable(false);
text.setEnabled(false);
text.setHighlighter(null);

但是当用户将鼠标拖到JTextArea上时,仍会发生一些颜色变化。有谁知道发生了什么?

but still some change of color happens as the user drags the mouse over the JTextArea. Anyone knows what is going on?

推荐答案

您不能简单地将组件的背景颜色设置为透明并期望摇摆来处理它。你需要将组件标记为透明( setOpaque(false)),只有这样,Swing的重绘管理器才会知道它必须更新它下面的组件。

You can't simply set the background color of a component to "transparent" and expect Swing to deal with it. You need to flag the component as transparent (setOpaque(false)), only then will Swing's repaint manager know that it has to update the components under it.

这会引导您解决如何绘制背景的问题(因为Swing只有完全不透明或完全透明的概念)。

This then leads you to the problem of how to paint the background (as Swing only has the concept of fully opaque or fully transparent).

要做到这一点,你需要提供自己的绘图例程(覆盖 paintComponent ,填充背景,更新组件)......这基本上就是 Rob Camick的解决方案正在做,它只提供了一个很好的包装组件你...

To do this, you need to supply your own paint routines (override paintComponent, fill the background, update the component)...this is essentially what Rob Camick's solution is doing, it just provides a nice wrapper component for you...

以下是使用HTML和<$ c包装的文本使用 JLabel 的示例$ c> JTextArea ,两者都更新为支持半透明......

Below is an example of using a JLabel using text wrapped in HTML and a JTextArea, both updated to support "translucency"...

使用 JLabel

使用 JTextArea

现在,它会使用Rob的包装类可以轻松实现,但这可以让您了解出现问题以及修复它需要做些什么。

Now, it would be a lot easier to achieve using Rob's wrapper class, but this provides you with the idea of what is going wrong and what you would need to do to fix it.

public class MultiLineLabel {

    public static void main(String[] args) {
        new MultiLineLabel();
    }

    public MultiLineLabel() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BackgroundPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TransclucentLabel extends JLabel {

        public TransclucentLabel(String text) {
            super(text);
            setVerticalAlignment(TOP);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            Insets insets = getInsets();
            int x = insets.left;
            int y = insets.top;
            int width = getWidth() - (insets.left + insets.right);
            int height = getHeight() - (insets.top + insets.bottom);
            g2d.setColor(new Color(255, 0, 0, 128));
            g2d.fillRect(x, y, width, height);
            super.paintComponent(g);
        }
    }

    public class TransclucentTextArea extends JTextArea {

        public TransclucentTextArea(String text) {
            super(text);
            setOpaque(false);
            setLineWrap(true);
            setWrapStyleWord(true);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            Insets insets = getInsets();
            int x = insets.left;
            int y = insets.top;
            int width = getWidth() - (insets.left + insets.right);
            int height = getHeight() - (insets.top + insets.bottom);
            g2d.setColor(new Color(255, 0, 0, 128));
            g2d.fillRect(x, y, width, height);
            super.paintComponent(g);
        }
    }

    public class BackgroundPane extends JPanel {

        private BufferedImage background;

        public BackgroundPane() {
            setLayout(new BorderLayout());
//            addLabel();
            addTextArea();
            setBorder(new EmptyBorder(24, 24, 24, 24));

            try {
                background = ImageIO.read(new File("/path/to/your/image"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        protected void addTextArea() {
            StringBuilder sb = new StringBuilder(128);
            sb.append("I put a JTextArea in a JPanel. This JPanel has a picture on the background, and the JTextArea is translucent (translucid red) to show the background through. I don't want the user to be able to edit or select the text, I want it to act just as a JLabel (but with multiple lines and easy to word wrap and adjust to screen resize).\n\n");
            sb.append("I tried all these options:\n\n");
            sb.append("text.setEditable(false);\n");
            sb.append("text.setFocusable(false);\n");
            sb.append("text.setEnabled(false);\n");
            sb.append("text.setHighlighter(null);\n\n");
            sb.append("but still some change of color happens as the user drags the mouse over the JTextArea. Anyone knows what is going on?\n");
            add(new TransclucentTextArea(sb.toString()));
        }

        protected void addLabel() {
            StringBuilder sb = new StringBuilder(128);
            sb.append("<html>");
            sb.append("<p>I put a JTextArea in a JPanel. This JPanel has a picture on the background, and the JTextArea is translucent (translucid red) to show the background through. I don't want the user to be able to edit or select the text, I want it to act just as a JLabel (but with multiple lines and easy to word wrap and adjust to screen resize).</p><br>");
            sb.append("<p>I tried all these options:</p><br>");
            sb.append("<p>text.setEditable(false);<br>");
            sb.append("text.setFocusable(false);<br>");
            sb.append("text.setEnabled(false);<br>");
            sb.append("text.setHighlighter(null);</p><br>");
            sb.append("<p>but still some change of color happens as the user drags the mouse over the JTextArea. Anyone knows what is going on?</p>");
            add(new TransclucentLabel(sb.toString()));

        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                int x = (getWidth() - background.getWidth()) / 2;
                int y = (getHeight() - background.getHeight()) / 2;
                g.drawImage(background, x, y, this);
            }
        }
    }
}

这篇关于JTextArea不可选,但仍显示“重影”。光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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