- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试基于 JWindow
制作自定义 UI,以便选择要共享的屏幕区域。我已经扩展了 JWindow
并添加了代码以使其可调整大小并使用 AWTUtilities.setWindowShape()
“切掉”窗口的中心。
运行代码时,当窗口在负 x 和 y 方向(即向上和向左)调整大小时,我遇到了闪烁。似乎正在发生的事情是在更新组件之前调整窗口大小并绘制。下面是代码的简化版本。运行时,顶部面板可用于向上和向左调整窗口大小。窗口的背景设置为绿色,以明确我不想显示的像素在哪里。
编辑:改进了代码以使用 ComponentListener
正确塑造窗口,并在底部添加了一个虚拟组件以进一步说明闪烁(也更新了屏幕截图)。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import com.sun.awt.AWTUtilities;
public class FlickerWindow extends JWindow implements MouseListener, MouseMotionListener{
JPanel controlPanel;
JPanel outlinePanel;
int mouseX, mouseY;
Rectangle windowRect;
Rectangle cutoutRect;
Area windowArea;
public static void main(String[] args) {
FlickerWindow fw = new FlickerWindow();
}
public FlickerWindow() {
super();
setLayout(new BorderLayout());
setBounds(500, 500, 200, 200);
setBackground(Color.GREEN);
controlPanel = new JPanel();
controlPanel.setBackground(Color.GRAY);
controlPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
controlPanel.addMouseListener(this);
controlPanel.addMouseMotionListener(this);
outlinePanel = new JPanel();
outlinePanel.setBackground(Color.BLUE);
outlinePanel.setBorder(new CompoundBorder(new EmptyBorder(2,2,2,2), new LineBorder(Color.RED, 1)));
add(outlinePanel, BorderLayout.CENTER);
add(controlPanel, BorderLayout.NORTH);
add(new JButton("Dummy button"), BorderLayout.SOUTH);
setVisible(true);
setShape();
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setShape();
}});
}
public void paint(Graphics g) {
// un-comment or breakpoint here to see window updates more clearly
//try {Thread.sleep(10);} catch (Exception e) {}
super.paint(g);
}
public void setShape() {
Rectangle bounds = getBounds();
Rectangle outlineBounds = outlinePanel.getBounds();
Area newShape = new Area (new Rectangle(0, 0, bounds.width, bounds.height));
newShape.subtract(new Area(new Rectangle(3, outlineBounds.y + 3, outlineBounds.width - 6, outlineBounds.height - 6)));
setSize(bounds.width, bounds.height);
AWTUtilities.setWindowShape(this, newShape);
}
public void mouseDragged(MouseEvent e) {
int dx = e.getXOnScreen() - mouseX;
int dy = e.getYOnScreen() - mouseY;
Rectangle newBounds = getBounds();
newBounds.translate(dx, dy);
newBounds.width -= dx;
newBounds.height -= dy;
mouseX = e.getXOnScreen();
mouseY = e.getYOnScreen();
setBounds(newBounds);
}
public void mousePressed(MouseEvent e) {
mouseX = e.getXOnScreen();
mouseY = e.getYOnScreen();
}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
重写的 paint()
方法可以用作断点,或者 Thread.sleep()
可以在此处取消注释以提供更清晰的更新 View 发生。
我的问题似乎源于 setBounds()
方法导致窗口在布局之前被绘制到屏幕上。
调整大小之前的窗口,应该是这样的:
在被覆盖的 paint()
方法的断点处看到更大的窗口(向上和向左):
在被覆盖的 paint()
方法的断点处看到的更小(向下和向右)的窗口):
当然,这些屏幕截图是在激烈的鼠标拖动过程中拍摄的,但即使是更温和的鼠标拖动,闪烁也会变得非常烦人。
调整为更大屏幕截图的绿色区域显示了在任何绘画/布局完成之前绘制的新背景,它似乎发生在底层 ComponentPeer
或 native 窗口管理器中。 'resize to small' 屏幕截图上的蓝色区域显示 JPanel
的背景被推到 View 中,但现在已经过时了。这发生在 Linux(Ubuntu) 和 Windows XP 下。
有没有人找到一种方法来使 Window
或 JWindow
在对屏幕进行任何更改之前调整其大小,从而避免这种闪烁效果?也许有一个 java.awt....
系统属性可以设置来避免这种情况,但我找不到。
编辑 #2: 注释掉对 AWTUtilities.setWindowShape()
的调用(并可选择取消注释 Thread.sleep(10)
行在 paint()
) 中,然后用力拖动顶部面板,以便清楚地看到闪烁的性质。
编辑 #3: 是否有人能够在 Windows 7 或 Mac OSX 上的 Sun Java 下测试此行为?
最佳答案
我承认这不是一个特别有用的答案,但了解 Swing 究竟是什么可能会有所帮助。
你看,Swing 做所有自己的工作,实际上没有从操作系统中获得一点空间。所有的绘图、小部件等都是 Java 代码。与其说它运行缓慢,不如说它在没有 2D 显卡加速和操作系统渲染技巧的情况下运行。
还记得 DirectDraw 吗?现在一切都有了,而且 window 操作非常顺利。但是,如果您曾经因为某种原因(例如,没有安装驱动程序的 XP 安装)购买了一台没有它的计算机,您会注意到正是这种类型的减速。
使用 Swing,因为它管理自己的所有空间,操作系统无法使用任何这些渲染技巧来帮助您。
有人可能会提供一些优化来解决您计算机上的问题,但我担心它并不能真正解决基本问题 - Swing 很慢而且无法变得更快。
您应该研究原生工具包。 AWT 还可以,但缺少很多小部件/等。它是原生的,内置的,所以如果你需要的话,它应该足够快。我偏爱 SWT,这是 Eclipse、Vuze(以及其他)使用的。它结合了 AWT 的原生特性与 Swing 的易用性和特性,当然可以在任何地方运行。
编辑:在阅读了您的更多评论后,您非常清楚您完全了解窗口化是如何发生的——我不想表现得居高临下。不仅如此,您对调整大小更感兴趣,我的评论与此没有太大关系。我仍然推荐 SWT,因为它是 native 代码且速度更快,但与上面的答案不同。
关于java - 如何在不闪烁的情况下调整 Swing JWindow 的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4324221/
是否可以在创建后将父窗口设置为JWindow?例如: public class SomeJWindow extends JWindow { public SomeJWindow (JFrame p
我如何才能只退出我从 Main 创建的新 MainGame?Main 有一个原始的游戏层。 MainGame 是一个对话窗口(例如模态窗口)。 Main.java:(主要代码) public clas
我创建了一个 java 程序,它不使用 JFrame,而是使用 JWindow。这正是我所需要的,一个没有窗口边框/标题栏的应用程序。 问题是它在运行时没有显示在屏幕底部的任务栏中。 谁能知道如何解决
我在使用 JWindow 时遇到问题。 这是我的包含 JWindow 的类: public class NextLevelCounter { JWindow window = new JWin
当我尝试将我的 JWindow 与 SeaGlass 一起使用时,它根本没有出现 Look and Feel ,即使我将其设置为可见。 import java.awt.EventQueue; impo
我创建了一个 java 程序,它不使用 JFrame,而是使用 JWindow。这正是我所需要的,一个没有窗口边框/标题栏的应用程序。 问题是它在运行时没有显示在屏幕底部的任务栏中。 谁能知道如何解决
我编写了一个 JWindow,用作我的桌面应用程序的启动屏幕。我遇到的问题是,窗口变得可见后,在显示预期图像之前它会暂时空白。空白窗口有时会保持 0.5 秒到 2 秒之间。我希望在窗口可见之前完全呈现
我使用了 Java 和 Swing。 我有两个窗口 MainWindow 和 PointWindow。 MainWindow 是一个 JFrame 窗口。 PointWindow 扩展 JWindow
我在我的小程序中创建了一个 JWindow 来显示更新过程,并将所有者设置为小程序父级。我的问题是 JWindow 在我浏览器的所有选项卡中都可见,而不仅仅是包含我的小程序的选项卡。是否可以添加一个监
我正在开发一个 toast 处理程序来管理通过“toast”动画(向上滑动,站立一会儿然后向下滑动)带给用户的通知。 Toast 类扩展了 JWindow(只是为了测试,我可以使用具有更稳定版本的 J
我想要做的是在我的程序加载某些内容时出现一个小的初始屏幕。这是我的: SplashScreen.showSplashScreen(); // Do stuff that takes time. Spl
我想创建一个 JWindow,它不仅具有不透明度,而且还想更改 Swing 内不透明度的默认颜色。 例如,如果我写: AWTUtilities.setWindowOpacity(this, 0.5f)
我想实现像截图工具一样的屏幕截图功能。我已经可以选择一个矩形并制作屏幕截图,但我这个矩形是完全不透明的。 我想知道 Swing 或 AWT 中是否有一个函数可以像这样使用: window.setOpa
我有一个 jwindow(设置为始终在顶部),您可以单击它以获取弹出菜单。如果用户右键单击该窗口,它会显示弹出菜单,但如果用户单击任何其他窗口(例如 firefox),弹出菜单不会消失。 我试图通过在
我正在编写这个程序来在 JWindow 中显示 JProgressbar。但是在同一台机器上运行这个程序而不做任何更改每次都会显示不同的结果。大多数时候它显示空的 JWindow,里面没有任何东西。其
我正在制作一个包含 JWindow 的 java 应用程序。我希望能够跟踪鼠标,而无需用户在转到另一个窗口后单击该窗口。 最佳答案 您的问题对于为什么要在鼠标离开 JWindow 后继续处理鼠标有点含
我正在制作一个自动完成项目(就像 Google 一样)。我的框架中有一个 jtextfield,每当我在该字段中键入内容时,文本字段下方都会出现一个 JWindow,并且该窗口来自另一个类。 现在的问
是否有一些方法可以知道类是否扩展JWindow?例如: class DialogWindow extends JWindow { } 如何检查 DialogWindow 类是否扩展 JWindow 类
我想在 JWindow 中显示一条消息一段时间,所以我尝试使用 while() 和 sleep() 函数,但它不起作用。这是应该调用 JWindow (MessageWindow) 的函数。有没有其他
我正在尝试对透明的JWindow进行双缓冲,但似乎所使用的技术不起作用(不同的周期值相互重叠)。 public final class Overlay extends JWindow { pu
我是一名优秀的程序员,十分优秀!