Question

I am currently working on an overlay and testing every function out first.

The overlay should be completely translucent and only the elements, i.e. Components or String, should be displayed. Also, I would like to add a feature that makes dragging Panels possible.

My problem now is: I have drawn the rectangle onto the transparent background. Any time I drag it to another position, the rendering fails and the old projection does not get cleared. Also, the whole frame flashes when I start to drag. I think I might need to repaint it in a separate thread while the mouse button is held down, right?

I have tried many things until now, but none of them seemed to work to resolve the rendering error.

Here is my code. Thanks for the help in advance.

Frame.java

public class Frame extends JFrame implements ActionListener {

public Frame() {
    super();

    setLayout(null);
    setResizable(false);
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    setSize(600, 600);
    Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
    setLocation(screensize.width / 2 - getWidth() / 2, screensize.height / 2 - getHeight() / 2);
    setUndecorated(true);
    setBackground(new Color(0, 0, 0, 0));
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

    Container c = getContentPane();
    c.setBackground(new Color(255, 0, 0, 0));
    DragPanel dp = new DragPanel();
    dp.setSize(100, 100);
    dp.setLocation(10, 10);
    JButton bt = new JButton("TEST");
    bt.setSize(100, 30);
    bt.setLocation(getWidth() - 20 - bt.getWidth(), getHeight() - 20 - bt.getHeight());
    bt.addActionListener(this);
    c.add(dp);
    c.add(bt);
    repaint();
}

@Override
public void actionPerformed(ActionEvent arg0) {
    this.repaint();
}

}

DragPanel.java

public class DragPanel extends JPanel implements MouseListener, MouseMotionListener {

private int screenX = 0;
private int screenY = 0;
private int compX = 0;
private int compY = 0;

public DragPanel() {
    setOpaque(false);
    addMouseListener(this);
    addMouseMotionListener(this);
}

@Override
public void mouseClicked(MouseEvent arg0) {

}

@Override
public void mouseEntered(MouseEvent arg0) {

}

@Override
public void mouseExited(MouseEvent arg0) {

}

@Override
public void mousePressed(MouseEvent e) {
    screenX = e.getXOnScreen();
    screenY = e.getYOnScreen();
    compX = getX();
    compY = getY();
    Starter.f.repaint();
}

@Override
public void mouseReleased(MouseEvent arg0) {

}

@Override
public void mouseDragged(MouseEvent e) {
    int dX = e.getXOnScreen() - screenX;
    int dY = e.getYOnScreen() - screenY;
    setLocation(compX + dX, compY + dY);
    Starter.f.repaint();
}

@Override
public void mouseMoved(MouseEvent arg0) {

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.red);
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.gray);
    g.fillRect(3, 3, getWidth() - 6, getHeight() - 6);
}

}
Was it helpful?

Solution

Probably containers do not like moving UI parts so you have to "render" it yourself. You have to overwrite the paint method and clear the background and do what the container does, you issue a paint request to every component. For me this worked without problems.

public void paint(Graphics g) {
    g.clearRect(0, 0, getWidth(), getHeight());
    for(Component c: getContentPane().getComponents()) {
        c.repaint();
    }
}

OTHER TIPS

What do you expect the JFrame to paint, when you're setting a transparent background color? Of course it doesnt "reset". From your description I still fail to see for what you would need any transparency at all.

If your goal is to make the entire JFrame transparent with respect to the desktop, your approach is meaningless. You need to explicitly make the frame transparent, which is easily found using google: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top