透明JFrame,带有可拖动组件

时间:2015-08-21 18:26:13

标签: java swing transparency draggable

我想通过在透明背景上使用可拖动的JComponents来创建类似hud的ui。我到目前为止的最小例子:

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);
  }

}

当拖动标签时,它会留下痕迹:它在它所处的所有位置都被绘制。我尝试将标签添加到JPanel,面板到框架并覆盖面板的paintComponent方法,如下所述:https://tips4java.wordpress.com/2009/05/31/backgrounds-with-transparency/,结果是相同的。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

不幸的是,它在我的机器上正常工作(不会留下任何痕迹)。尝试在组件更改位置后添加frame.repaint()。使用带有绘画区域的repaint变体来表现。