JTextArea not selectable, but still showing a “ghost” cursor

后端 未结 1 659
我在风中等你
我在风中等你 2020-11-30 14:15

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 t

相关标签:
1条回答
  • 2020-11-30 15:10

    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.

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

    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...

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

    Using a JLabel

    enter image description here

    Using a JTextArea

    enter image description here

    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);
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题