title: Swing transparent background not being repainted
body: <p>I have a problem using transparent backgrounds in Swing.
  There are a lot of artefacts produced as swing is not repainting changed regions.</p>
  
  <p><img src="https://i.stack.imgur.com/35wEg.png" alt="buggy"></p>
  
  <p>As far as I can tell there are 2 out-of-the-box ways to use transparent backgrounds:</p>
  
  <ol>
  <li>an opaque component with transparent color set as background (left txt field)</li>
  </ol>
  
  <p><strong>Problem</strong>: the transparent part of the background is never refreshed -> Artefacts.</p>
  
  <ol start="2">
  <li>an non-opaque component with transparent color set as background (right txt field)</li>
  </ol>
  
  <p><strong>Problem</strong>: background is not being drawn at all.</p>
  
  <p>What I do <strong>not</strong> want to do:</p>
  
  <ul>
  <li>to use timers to auto repaint the frame (super awful)</li>
  <li>to override paintComponent method (which actually works, but is really really awful)</li>
  </ul>
  
  <p>I am running on Win7 x64</p>
  
  <p>Aaaand here is my SSCCEEE:</p>
  
  <p><strong>Update 1: init with invokeLater (still won't work)</strong></p>
  
  <pre><code>public class OpacityBug {
  
      public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  new OpacityBug();
              }
          });
      }
  
      static final Color transparentBlue = new Color(0f, 1f, 0f, 0.5f); 
  
      JFrame frame;
      JPanel content;
  
      JTextField txt1;
      JTextField txt2;
  
      public OpacityBug() {
          initFrame();
          initContent();
      }
  
      void initFrame() {
          frame = new JFrame();
          frame.setSize(300, 80);
          frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          frame.setVisible(true);
      }
  
      void initContent() {
          content = new JPanel();
          content.setDoubleBuffered(true);
          content.setBackground(Color.red);
          frame.getContentPane().add(content);
  
          txt1 = new JTextField() {
              @Override
              public void setBorder(Border border) {
                  super.setBorder(null); //nope border
              }
          };
          txt1.setText("Hi! I am Buggy!");
          txt1.setOpaque(true);
          txt1.setBackground(transparentBlue);
          content.add(txt1);
  
          txt2 = new JTextField() {
              @Override
              public void setBorder(Border border) {
                  super.setBorder(null); //nope border
              }
          };
          txt2.setText("And I have no BG!");
          txt2.setOpaque(false);
          txt2.setBackground(transparentBlue);
          content.add(txt2);
  
          content.revalidate();
          content.repaint();
      }
  }
  </code></pre>
  
  <p><strong>Update 2</strong></p>
  
  <p>As some of you noticed, it seems Swing that swing is unable to paint transparent backgrounds.
  But it is not (yet) clear to me why, I searched for the piece of code responsible for drawing the background of the component and have found the following code in ComponentUI.java :</p>
  
  <pre><code>public void update(Graphics g, JComponent c) {
  if (c.isOpaque()) {
      g.setColor(c.getBackground());
      g.fillRect(0, 0, c.getWidth(),c.getHeight());
  }
  paint(g, c);
  }
  </code></pre>
  
  <p>As you can see, it assumes that if a component is not opaque the background doesn't need to be repainted. I say that this is a very vague assumption.</p>
  
  <p>I would propose following implementation:</p>
  
  <pre><code>public void update(Graphics g, JComponent c) {
  if(c.isOpaque() || (!c.isOpaque() &amp;&amp; c.isBackgroundSet())) {
      g.setColor(c.getBackground());
      g.fillRect(0, 0, c.getWidth(), c.getHeight());
  }
  paint(g, c);
  }
  </code></pre>
  
  <p>I simply check if the background was set at all when the component is not opaque.
  This simple addition would allow us to use transparent backgrounds in swing.
  At least I do not know any reasons why it should not be done that way.</p>