0

I want to create a hud-like ui by using draggable JComponents on a transparent background. Minimal example of what I have so far:

import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class TransparentFrame
    extends JFrame {

  public TransparentFrame() {
    setLayout(null);

    setUndecorated(true);
    setBackground(new Color(1, 1, 1, 0.0f));
    setLocationRelativeTo(null);

    setSize(600, 500);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    JLabel label = new JLabel("ABC");
    label.setBounds(100, 100, 60, 30);
    label.setOpaque(true);
    label.setBackground(Color.RED);
    label.setForeground(Color.WHITE);

    DraggableComponentListener listener = new DraggableComponentListener(label);
    label.addMouseListener(listener);
    label.addMouseMotionListener(listener);

    add(label);
    setVisible(true);
  }


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

class DraggableComponentListener
    extends MouseAdapter {

  private Component component;

  private volatile int screenX = 0;
  private volatile int screenY = 0;

  private volatile int componentX = 0;
  private volatile int componentY = 0;

  public DraggableComponentListener(Component component) {
    this.component = component;
  }

  @Override
  public void mousePressed(MouseEvent e) {
    screenX = e.getXOnScreen();
    screenY = e.getYOnScreen();

    componentX = component.getX();
    componentY = component.getY();
  }

  @Override
  public void mouseDragged(MouseEvent e) {
    int deltaX = e.getXOnScreen() - screenX;
    int deltaY = e.getYOnScreen() - screenY;
    component.setLocation(componentX + deltaX, componentY + deltaY);
  }

}

When the label is dragged, it leaves traces behind: it is painted at all positions it has been at. I tried adding the label to a JPanel, the panel to the frame and overriding the panel's paintComponent method as described here: https://tips4java.wordpress.com/2009/05/31/backgrounds-with-transparency/, the result was the same.

Any suggestions?

1 Answers1

0

Unfortunately, it is working properly on my machine (doesn't leave any traces). Try adding a frame.repaint() after the location changed of the component. Use the repaint variation that takes the paint area for performance.

Dakshinamurthy Karra
  • 5,353
  • 1
  • 17
  • 28
  • I just checked, the code I posted works on windows but not on kde ubuntu that I'm using. I've tried frame. repaint(), validate() etc, still the same behavior – Giannis Papadopoulos Aug 21 '15 at 20:27