我一直在制作一个程序来监控远程系统并在屏幕的一个角落(用户偏好)显示非侵入性警报,以提醒用户远程系统的变化。为此,我使用了 JWindow,以便为更重要的警报产生脉冲效果,以引起用户的注意。我还有一个从屏幕外滚动到屏幕上的警报。
我遇到的问题是,如果我不将这些警报设置为always on top,它们并不总是显示,但是当我将它们设置为 always on top 时,滚动选项也会显示在任务栏上方。有什么方法可以强制它显示在所有其他程序上(全屏程序不需要应用),但在任务栏下方?
编辑: 这是我滚动 JWindow 开/关屏幕的代码:
Edit2:更新代码以显示我对 NESPowerGlove 的回答:
public void scrollOn() {
//Get the normal screen area minus taskbar
Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
int taskBar = scnMax.bottom; //Bottom of the normal window area
int x = screenSize.width - getWidth(); //Horizontal start point of the window
int yEnd = screenSize.height - taskBar - getHeight(); //where the window will stop
int yStart = screenSize.height; //Vertical start point of the window
setLocation(x,yStart); //set window to start location
int current = yStart; //windows current location
newHeight = yStart - current; //Set the newHeight field to the clipping start height
while(current > yEnd) { //loop while window is still enroute to final destination
current-=2; //increments to move the window, in pixels
newHeight = yStart - current; //Update the newHeight field to clip the window appropriately based on position
setLocation(x,current); //move the window to the next position
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//This is basically the reverse of the scrollOn() method
public void scrollOff() {
Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
int taskBar = scnMax.bottom;
int x = screenSize.width - getWidth();
int yEnd = screenSize.height - taskBar;
int yStart = this.getBounds().y;
setLocation(x,yStart);
int current = yStart;
newHeight = this.getBounds().height;
while(current < yEnd) {
current+=2;
newHeight = yEnd - current;
setLocation(x,current);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Tells the system the next alert can be triggered
//This prevents screen clutter from multiple alerts by setting up a queue
Main.alertControl.setAlertActive(false);
}
下面是我实际构建窗口的方式(当前)。这个方法只是一个占位符,直到我得到图像来构建最终的 L&F 窗口。
public AlertScroller(String msg) {
addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(ComponentEvent e) {
//Sets the area to be shown while the rest is clipped,
//updating whenever the component moves
setShape(new Rectangle2D.Double(0, 0, getWidth(), newHeight));
if(!isVisible())
setVisible(true);
}
});
setAlwaysOnTop(true);
JPanel panel = new JPanel();
panel.setBorder(compound);
panel.setBackground(Color.yellow);
JLabel imgLbl = new JLabel(msg);
imgLbl.setFont(new Font(null,Font.BOLD,16));
panel.add(imgLbl);
setContentPane(panel);
pack();
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent click) {
if(SwingUtilities.isLeftMouseButton(click)) {
autoClear = false;
scrollOff();
}
}
});
}