我一直在制作一个监控远程系统的程序,并在屏幕的一个角落(用户偏好)显示非侵入式警报,以提醒用户远程系统发生变化。要做到这一点,我正在使用JWindow,以便我可以为更重要的警报产生脉冲效果,吸引用户的注意力。我还有一个警报,可以从屏幕外滚动到屏幕上。
我遇到的问题是,如果我没有将这些警报设置为始终位于顶部,则它们并不总是显示,但是当我将它们设置为始终位于顶部时,滚动选项还会在任务栏上显示上方。有什么方法可以强制它显示所有其他程序(全屏程序不需要应用),但在任务栏下面?
编辑:以下是滚动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&amp; 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();
}
}
});
}
答案 0 :(得分:1)
我不确定这是否是推荐的做法,但以下是您想要的:
while(tillYouWantToDisplay) {
window.setAlwaysOnTop(true);
window.setAlwaysOnTop(false);
delay(delayTime); // You have to write this method using sleep()
// delayTime may be about 500ms
}
window.dispose();
您可能必须将上述代码放在一个帖子中。
我在下面写了快速演示代码,以显示我的意思(只是运行它看看):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JLabel;
import javax.swing.JWindow;
public class TestProgram extends JWindow {
public static void main(String[] args) throws Exception {
TestProgram window = new TestProgram();
window.setVisible(true);
Dimension windowDim = window.getSize();
int steps = 20;
for (int i = 0; i < steps; i++) {
window.setAlwaysOnTop(true);
window.setAlwaysOnTop(false);
Point p = window.getLocation();
window.setLocation(p.x, p.y - windowDim.height / steps);
Thread.sleep(100);
}
for (int i = 0; i < 10; i++) {
window.setAlwaysOnTop(true);
window.setAlwaysOnTop(false);
Thread.sleep(100);
}
for (int i = 0; i < steps; i++) {
window.setAlwaysOnTop(true);
window.setAlwaysOnTop(false);
Point p = window.getLocation();
window.setLocation(p.x, p.y + windowDim.height / steps);
Thread.sleep(100);
}
window.dispose();
}
public TestProgram() {
setSize(200, 100);
Rectangle scrDim = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
setLocation(scrDim.x + scrDim.width - getSize().width, scrDim.y + scrDim.height);
JLabel msg = new JLabel("Your Message");
msg.setHorizontalAlignment(JLabel.CENTER);
msg.setVerticalAlignment(JLabel.CENTER);
getContentPane().add(msg);
getContentPane().setBackground(Color.red);
}
}
答案 1 :(得分:0)
您可以通过找出窗口框架显示的常用区域的边界来避免在任务栏(或您想要避免的其他类似区域)上显示JWindow:
Rectangle maxBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
编辑:问题的作者在此答案的评论部分中提到的动画问题的更多代码,他也想要包含在答案中:
有了这个我认为你可以使框架未修饰(setUndecorated(true)),然后使背景完全透明,然后慢慢增加你在背景中绘制的矩形的高度,最终将在整个窗口中着色。 / p>
setShape(new Ellipse2D.Double(0,0,getWidth(),getHeight()));
to(通常先调用newHeightOfDisplay来缓慢更新Rectangle的位置)
setShape(new Rectangle2D.Double(0, getHeight() - newHeightOfDisplay, getWidth(), newHeightOfDisplay));