Java JWindow-始终在顶部,但在系统栏下方?
我一直在制作一个监控远程系统的程序,并在屏幕的一个角落(用户首选项)显示非侵入性警报,以提醒用户远程系统中的更改。为了做到这一点,我使用了一个JWindow,这样我可以为更重要的警报产生脉冲效果,以吸引用户的注意。我还有一个警报,可以从屏幕外滚动到屏幕上 我遇到的问题是,如果我没有将这些警报设置为始终在顶部,它们不会始终显示,但如果我将它们设置为始终在顶部,滚动选项也会在任务栏上方显示。是否有任何方法可以强制它显示在所有其他程序上(不需要应用全屏程序),但显示在任务栏下方 编辑:以下是我在屏幕上/屏幕下滚动JWindow的代码: Edit2:更新代码以显示我加入了NESPowerGlove的答案:Java JWindow-始终在顶部,但在系统栏下方?,java,swing,taskbar,always-on-top,jwindow,Java,Swing,Taskbar,Always On Top,Jwindow,我一直在制作一个监控远程系统的程序,并在屏幕的一个角落(用户首选项)显示非侵入性警报,以提醒用户远程系统中的更改。为了做到这一点,我使用了一个JWindow,这样我可以为更重要的警报产生脉冲效果,以吸引用户的注意。我还有一个警报,可以从屏幕外滚动到屏幕上 我遇到的问题是,如果我没有将这些警报设置为始终在顶部,它们不会始终显示,但如果我将它们设置为始终在顶部,滚动选项也会在任务栏上方显示。是否有任何方法可以强制它显示在所有其他程序上(不需要应用全屏程序),但显示在任务栏下方 编辑:以下是我在屏幕上
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);
}
通过计算窗口框架显示在其中的常用区域的边界,可以避免在任务栏(或其他类似区域)上显示JWindow:
Rectangle maxBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
编辑:问题作者在本答案的评论部分提到的动画问题的更多代码,他希望也包括在答案中:
有了这个,我认为你可以使框架不装饰(setUndercorated(true)),然后使背景完全透明,然后慢慢增加你在背景中绘制的矩形的高度,最终在整个窗口中着色 。在您的情况下,更改:
setShape(new Ellipse2D.Double(0,0,getWidth(),getHeight()));
to(并经常调用,通过首先更新newHeightOfDisplay来缓慢更新矩形的位置)
我不确定这是否是一种推荐做法,但以下内容符合您的要求:
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();
您可能需要将上述代码放在一个线程中
我已经在下面编写了快速演示代码来说明我的意思(只需运行它即可查看):
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.GraphicsEnvironment;
导入java.awt.Point;
导入java.awt.Rectangle;
导入javax.swing.JLabel;
导入javax.swing.JWindow;
公共类测试程序扩展JWindow{
公共静态void main(字符串[]args)引发异常{
TestProgram window=新的TestProgram();
window.setVisible(true);
维度windowDim=window.getSize();
int步数=20;
对于(int i=0;i
Hmm,那么基本上,你是说当窗口位于任务栏下方时屏蔽它,然后让它从任务栏下方显示出来?按照我现在的方式,它只是从屏幕外开始滚动。我还没有真正弄清楚屏蔽窗口的某些部分。我是说不要使JWindow的边界超出getMaximumWindowBounds()返回的边界。您可以通过几种方式使应用程序看起来像是从任务栏下方向上滚动。一种方法是,假设您正在使用一个已经没有边框或标题栏的未装饰窗口,使其始终位于任务栏上方,但慢慢增加背景开始不透明的高度,同样的高度计算可以用于填充GUI第一个面板显示的高度,以便GUI跟踪最新的不透明高度。另一种方法(在下一篇评论中继续)另一种方法是简单地让你的JWindow以1的高度开始,然后慢慢地增加它的高度和y位置(比如,用SwingTimer每x毫秒增加1个像素,同样的计时器机制也可以用于第一个建议);我只是不知道如何在窗户上做部分不透明的部分。该窗口将使用BoarderLayout
或自定义定位,使用多个图像构建自定义“外观和感觉”;静态角和动态可伸缩的边以及顶部/底部/中心,以便调整其大小以适应警报消息的大小。我认为您可以使框架不装饰(SetUn装饰(true)),然后慢慢地增加你在背景中绘制的矩形的高度,它最终会在整个窗口中着色。我实际上已经考虑过这一点,但它有点违背了让窗口滚动到屏幕上的目的。滚动的主要目的是通过移动来吸引用户的眼球。嗯,编辑确实有效,尽管有点闪烁(在上/下之间)。投票赞成做OP中要求的事情,但我更喜欢NESPowerGlove的方法,因为它比我最初要求的方法有更专业的感觉;而且没有闪烁。不过,我可能会在其他地方使用你的方法。谢谢你的意见!哦,旁注:一定要添加一个commo
setShape(new Rectangle2D.Double(0, getHeight() - newHeightOfDisplay, getWidth(), newHeightOfDisplay));
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);
}
}