好吧,我已經設置了一些代碼來創建一個簡單的小覆蓋窗口,用作我正在處理的程序的警報消息。一切運行良好,但試圖再次運行它,它凍結了整個事情,迫使我通過調試器或任務管理器終止它。由於我對Java的經驗有限,我知道我做錯了什麼,我只是不確定是什麼。Java窗口脈衝推子工作一次然後休息
下面是我用它來設置我的窗口,並將其放置在右下角任務欄上面的代碼:
private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static JWindow alertWindow() {
JWindow newWin = new JWindow();
JPanel panel = new JPanel();
BufferedImage img = null;
try {
img = ImageIO.read(Main.class.getResource("/images/test.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
JLabel imgLbl = new JLabel(new ImageIcon(img));
panel.add(imgLbl);
newWin.setContentPane(panel);
newWin.pack();
Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(newWin.getGraphicsConfiguration());
int taskBar = scnMax.bottom;
int x = screenSize.width - newWin.getWidth();
int y = screenSize.height - taskBar - newWin.getHeight();
newWin.setLocation(x,y);
newWin.setVisible(true);
final PulseWindow pulseWin = new PulseWindow(newWin);
pulseWin.getWindow().addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent click) {
if(SwingUtilities.isRightMouseButton(click)) {
pulseWin.stopPulsing();
pulseWin.destroyPulse();
} else {
System.out.println(pulseWin.isPulsing());
if(pulseWin.isPulsing()) {pulseWin.stopPulsing();}
else {pulseWin.startPulse();}
}
}
@Override
public void mouseEntered(MouseEvent arg0) {}
@Override
public void mouseExited(MouseEvent arg0) {}
@Override
public void mousePressed(MouseEvent arg0) {}
@Override
public void mouseReleased(MouseEvent arg0) {}
});
pulseWin.startPulsing();
return newWin;
}
並在下面的代碼我設置,使之脈繪製用戶注意:
import javax.swing.JWindow;
public class PulseWindow {
private boolean pulse = true;
private boolean doPulse = true;
private Float floor = 0.50f;
private JWindow win;
public PulseWindow(JWindow win) {
this.win = win;
}
public void startPulsing() {
pulse = true;
boolean decreasing = true;
double inc2 = 0.03;
double current = win.getOpacity();
while(pulse) {
if(doPulse) {
if(decreasing) {
current = current - inc2;
if((float) current <= floor) {
current = floor;
win.setOpacity((float) current);
decreasing = false;
} else {
win.setOpacity((float) current);
}
} else {
current = current + inc2;
if((float) current >= 1.0f) {
current = 1.0;
win.setOpacity((float) current);
decreasing = true;
} else {
win.setOpacity((float) current);
}
}
} else {
current = 1.0;
win.setOpacity(1.0f);
decreasing = true;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
win.setOpacity(1.0f);
}
public void destroyPulse() {
pulse = false;
win.dispose();
}
public boolean isPulsing() { return doPulse; }
public void setFloor(float floor) { this.floor = floor; }
public void stopPulsing() { doPulse = false; }
public void startPulse() { doPulse = true; }
public JWindow getWindow() { return win; }
}
反正,就像我提到的,它工作正常第一次使用,但只要你通過關閉窗口,單擊右鍵,然後嘗試後重新運行它(無論是通過調用startPulsing()
方法或通過用新的JWindow完全重新初始化整個類再次調用alertWindow()
),整個程序就凍結了。任何想法,爲什麼這是?
就像我說的,我仍然是Java的一個新手,所以如果你看到其他任何我做錯了/效率低下,那麼隨時指出它,所以我可以正確地做到這一點。
編輯:
我開始認爲這個問題是JWindows,現在。我爲其他代碼設置了不同的顯示警報的方法,雖然這次不凍結,但它不能按預期工作。
public class AlertWindow extends JWindow {
private static Border compound = BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLoweredBevelBorder());
private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public AlertWindow() {
JPanel panel = new JPanel();
panel.setBorder(compound);
panel.setBackground(Color.RED);
JLabel imgLbl = new JLabel("Enter Alert Msg Here!");
imgLbl.setFont(new Font(null,Font.BOLD,16));
panel.add(imgLbl);
setContentPane(panel);
pack();
this.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent click) {
if(SwingUtilities.isLeftMouseButton(click)) {
scrollOff();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
scrollOn();
}
}
@Override
public void mouseEntered(MouseEvent arg0) {}
@Override
public void mouseExited(MouseEvent arg0) {}
@Override
public void mousePressed(MouseEvent arg0) {}
@Override
public void mouseReleased(MouseEvent arg0) {}
});
scrollOn();
}
public void scrollOn() {
Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
int taskBar = scnMax.bottom;
int x = screenSize.width - getWidth();
int yEnd = screenSize.height - taskBar - getHeight();
int yStart = screenSize.height;
setLocation(x,yStart);
setVisible(true);
int current = yStart;
while(current > yEnd) {
current-=2;
System.out.println(current);
setLocation(x,current);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void scrollOff() {
int x = screenSize.width - getWidth();
int yEnd = screenSize.height;
int yStart = this.getBounds().y;
setLocation(x,yStart);
int current = yStart;
while(current < yEnd) {
current+=2;
setLocation(x,current);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
setVisible(false);
}
}
就像脈衝窗口的問題,它的工作原理是第一次,然後打破後續使用。在這種情況下,唯一中斷的是scrollOn()命令。它在不可見的情況下滾動,然後在到達目的地後變爲可見。該位置的控制檯輸出清楚地表明它正在移動,但在停止移動之前無法看到它。
想到一個念頭;這可能不是由於我重寫Java的自動垃圾收集的一些奇怪的方式,可以嗎?我試圖通過創建/初始化一個新的'PulseWindow'類來防止這些問題,但我仍然收到凍結問題。另外,我注意到凍結只發生在第二次調用'startPulsing()'時,即使該類被重新初始化。它在第一次通過時完全正常,但第二次調用導致凍結。 – DGolberg
經過了一番討論後,我相信這可能是由於我使用了Runnables而不是SwingWorker線程。該程序正在使用一個用戶界面,該用戶界面包含一個系統托盤圖標。我會發布完整的代碼,但在這個時候它太大了,無論如何,我有點樂於嘗試。我稍後會發布我的發現,如果我仍然需要任何幫助解決問題。 – DGolberg