답변을 기반으로 투명 클릭 스 오버레이를 사용했습니다 (클릭 연결을 사용하려면 jna를 사용함) https://stackoverflow.com/a/28772306/1093872. 그러나 실제 보이는 오버레이는 항상 한 걸음 뒤에 있습니다. 구성 요소에서 repaint()
이 호출되면 이전 업데이트에 표시된 업데이트가 표시됩니다.투명 스윙 오버레이를 올바르게 업데이트하는 방법은 무엇입니까?
처음에는 다른 스레드 때문에 메모리 불일치 문제가 의심됩니다. 그러나 SwingWorker
을 사용하여 sure-to-be-correct 접근 방식을 시도했지만 여전히 동일한 문제에 직면했습니다.
AWTUtilities.setWindowOpaque(w, false);
나는 문제가 (버퍼는 다음 페인트 전에 만 그림 후 교환되지 않음) 이중 버퍼링에 뭔가 관련이있을 수도 의심하지만 난 정말 모르겠어요. 또한 구성 요소에서 setDoubleBuffered(false)
및 setDoubleBuffered(true)
을 호출했지만 아무 것도 변경하지 않았습니다.
또한 문제는 jna 파트와 관련이 없다는 것을 깨달았습니다. 제거한 후에는 문제가 완전히 동일하기 때문입니다.
인덱스 인쇄는 도면과 동시에 발생하므로 paintComponent
은 시간에 따라 호출되지만 그 다음 호출시에만 표시되는 것으로 나타납니다.
어떤 원인 일 수 있으며 해결 방법은 무엇입니까? Window w = new JWindow();
-Window w = new Window(null);
변경 많은 시행 착오 내가 일하는 해결책을 발견 한 후
import com.sun.awt.AWTUtilities;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import javax.swing.*;
import java.awt.*;
public class OverlayUpdateTest {
private static MyJComponent myJComponent;
public static void main(String[] args) {
setupOverlayWindow();
new Thread(() -> {
for (int i = 0; i < 100; i++) {
myJComponent.increaseIndex();
myJComponent.repaint();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
private static void setupOverlayWindow() {
Window w = new Window(null);
myJComponent = new MyJComponent();
w.add(myJComponent);
w.pack();
w.setLocationRelativeTo(null);
w.setVisible(true);
w.setAlwaysOnTop(true);
/**
* This sets the background of the window to be transparent.
*/
AWTUtilities.setWindowOpaque(w, false);
setTransparent(w);
}
private static void setTransparent(Component w) {
WinDef.HWND hwnd = getHWnd(w);
int wl = User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
wl = wl | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT;
User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, wl);
}
/**
* Get the window handle from the OS
*/
private static WinDef.HWND getHWnd(Component w) {
WinDef.HWND hwnd = new WinDef.HWND();
hwnd.setPointer(Native.getComponentPointer(w));
return hwnd;
}
private static class MyJComponent extends JComponent {
private int index = 0;
/**
* This will draw a black cross on screen.
*/
protected void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, getHeight()/2 - 10, getWidth(), 20);
g.fillRect(getWidth()/2 - 10, 0, 20, getHeight());
g.setColor(Color.RED);
g.drawString("i: " + index, 10, getFont().getSize() + 10);
System.out.println("i: " + index);
}
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
void increaseIndex() {
index++;
}
}
}