- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 JSplitPane
的子类,它的目的是允许分隔线从右边缘或下边缘(而不是左边缘或上边缘)固定位置。
为此,我使用 ComponentChangeListener
来捕获组件大小的调整,并重新计算相对于宽度或高度的分隔线位置。
一切都完美无缺。但现在我添加一个 PropertyChangeListener
来捕获用户对分割位置的调整,并将左/顶部相对值存储为距右/下边框的偏移量,以便稍后在调整大小时使用。
但是我这里有一种级联问题:
ComponentChangeEvent
PropertyChangeEvent
所以分隔线最终会到处弹跳。
我尝试手动放入一个“禁止”标志(只是一个简单的 boolean 值
),它有时可以阻止事件,但通常不会,所以这就是不是绕过它的方法。
有什么线索吗?
我的 propertyChange
方法如下所示:
public void propertyChange(PropertyChangeEvent e) {
if (inhibit) return;
if (e.getPropertyName().equals("dividerLocation")) {
int pos = (Integer)e.getNewValue();
if (right == -1) {
left = pos;
} else {
Dimension d = getSize();
if (orient == JSplitPane.VERTICAL_SPLIT) {
right = d.height - pos;
} else {
right = d.width - pos;
}
}
}
}
componentResized
是:
public void componentResized(ComponentEvent e) {
if (!inhibit) {
updateDividerLocation();
}
}
void updateDividerLocation() {
inhibit = true;
if (right == -1) { // Left / top is fixed
setDividerLocation(left);
} else {
Dimension d = getSize();
if (orient == JSplitPane.VERTICAL_SPLIT) {
setDividerLocation(d.height - right);
} else {
setDividerLocation(d.width - right);
}
}
inhibit = false;
}
如您所见,我在那里有 inhibit
标志,正如我所说,它不能正常工作。
那么阻止 setDividerLocation
函数触发 PropertyChangeEvent
的正确方法是什么?我是否必须在调整组件大小并随后再次添加时完全删除 PropertyChangeListener
?这会有帮助吗?
注意:当显示更新可能有点滞后时,这一点最为明显。这是一个可以演示该问题的 SSCCE(尽管恐怕不是那么“小”)。问题的结果在这个 SSCCE 中并不总是很明显,因为窗口中没有太多内容(我发现将右边缘向左急剧拖动是搞乱它的好方法,并且速度较慢,图形更加密集,LaF有帮助),但这在整个程序中非常明显。然而,效果可以从以下事实中看出:调整窗口大小会导致“CE”输出(ComponentEvent)并立即产生“PCE”输出(PropertyChangeEvent)。我需要抑制的是 CE 之后的 PCE。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
public class TestClass {
class AbsoluteSplitPane extends JSplitPane implements ComponentListener, PropertyChangeListener {
int left = -1; // and top
int right = -1; // and bottom
int orient;
public AbsoluteSplitPane(int orientation, Component a, Component b) {
super(orientation, a, b);
orient = orientation;
addComponentListener(this);
addPropertyChangeListener(this);
}
void updateDividerLocation() {
if (right == -1) { // Left / top is fixed
setDividerLocation(left);
} else {
Dimension d = getSize();
if (orient == JSplitPane.VERTICAL_SPLIT) {
setDividerLocation(d.height - right);
} else {
setDividerLocation(d.width - right);
}
}
}
public void setLeftSize(int s) {
left = s;
right = -1;
updateDividerLocation();
}
public void setRightSize(int s) {
left = -1;
right = s;
updateDividerLocation();
}
public void setTopSize(int s) {
left = s;
right = -1;
updateDividerLocation();
}
public void setBottomSize(int s) {
left = -1;
right = s;
updateDividerLocation();
}
public void componentHidden(ComponentEvent e) {
}
public void componentShown(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
}
public void componentResized(ComponentEvent e) {
updateDividerLocation();
System.err.println(String.format(" CE: Left: %d Right: %d", left, right));
}
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals("dividerLocation")) {
int pos = (Integer)e.getNewValue();
if (right == -1) {
left = pos;
} else {
Dimension d = getSize();
if (orient == JSplitPane.VERTICAL_SPLIT) {
right = d.height - pos;
} else {
right = d.width - pos;
}
}
System.err.println(String.format("PCE: Left: %d Right: %d", left, right));
}
}
}
public TestClass() {
JFrame frame = new JFrame("Test Window");
JPanel left = new JPanel();
JPanel mid = new JPanel();
JPanel right = new JPanel();
AbsoluteSplitPane split1 = new AbsoluteSplitPane(JSplitPane.HORIZONTAL_SPLIT, mid, right);
AbsoluteSplitPane split2 = new AbsoluteSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, split1);
split1.setRightSize(200);
split2.setLeftSize(200);
frame.add(split2);
frame.setSize(400, 400);
frame.setVisible(true);
}
public static void main(String[] args) {
new TestClass();
}
}
<小时/>
更新:我已经成功通过 UI 将 MouseListener 附加到分隔符来解决该问题 (((BasicSplitPaneUI)getUI()).getDivider.addMouseListener(... )
) 并将位置数据保存在 mouseReleased()
事件中。它有效,但知道是否有办法抑制 PropertyChangeEvents 仍然是件好事...
最佳答案
but it'd still be good to know if there is a way of suppressing PropertyChangeEvents...
public void componentResized(ComponentEvent e) {
removePropertyChangeListener( this );
updateDividerLocation();
addPropertyChangeListener( this );
System.err.println(String.format(" CE: Left: %d Right: %d", left, right));
}
编辑:
也许您可以查看 EDT 上导致生成 PropertyChangeEvent 的事件?
public void propertyChange(PropertyChangeEvent e)
{
if (e.getPropertyName().equals("dividerLocation"))
{
AWTEvent event = EventQueue.getCurrentEvent();
if (event != null
&& (event.getID() != MouseEvent.MOUSE_RELEASED))
return;
int pos = (Integer)e.getNewValue();
if (right == -1) {
left = pos;
} else {
Dimension d = getSize();
if (orient == JSplitPane.VERTICAL_SPLIT) {
right = d.height - pos;
} else {
right = d.width - pos;
}
}
System.err.println(String.format("PCE: Left: %d Right: %d", left, right));
}
}
关于java - 当分隔符移动到 ComponentListener 内时,JSplitPane 会阻止 PropertyChangeEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58666224/
请看下面的代码。 package normal; import java.awt.*; import java.awt.event.*; import javax.swing.*; import ja
有什么方法可以以编程方式触发 ComponentListener 吗?例如,请查看下面的代码快照。 private class DisplayAllRevenue extends Compon
我有一个不寻常的问题,每当 mouseListener/Adapter 检测到事件时,componentListener/Adapter 就会被禁用。在下面的代码中,componentMoved()
我有一个 JPanel,它不应减小到小于最小尺寸,但它没有这样做。我知道我应该使用我已经实现但仍然没有用的 ComponentListener。 有人可以以编程方式解释出了什么问题吗? 这是代码的相关
ComponentListener 出现问题。我用它来检查某个组件的大小是否已调整,如果是,则更新一些内容。 代码看起来像这样,尽管这可能对您没有多大用处: @Override public void
我想在显示 WorldPanel 时获取 (Graphics g)。感谢 stackoverflow,我看到了应该在哪里使用 getGraphics 方法 (ComponentListener.com
为什么这段代码从不打印“Hello2”? public class Test4 { public static void main(String[] args) { JFram
我有一个 Main JPanel,其布局设置为 CardLayout。 Main JPanel 有 4 个卡片:Card1JPanel、Card2JPanel、Card3JPanel、Card4JPa
void NewJDialogcallone(JFrame frame) { location = frame.getLocationOnScreen(); int x = locat
我认为答案是在完成所有初始组件大小调整之后,但请看一下这个 SSCCE: import javax.swing.*; import java.awt.*; import java.awt.event.
我有一个 JSplitPane 的子类,它的目的是允许分隔线从右边缘或下边缘(而不是左边缘或上边缘)固定位置。 为此,我使用 ComponentChangeListener 来捕获组件大小的调整,并重
如果发生 componentShown/componentHidden 事件,我想得到通知。我使用 ComponentListener,但效果不如我需要。我在官方 Swing 教程中找到了这些信息:
我在 JFrame 中添加了一个 ComponentListener ,并在其 componentResized() 方法中保留了一些代码,这使得应用程序执行无限窗口。这是因为我在 component
我用 Google 搜索了一下,找不到答案: 我有一个 JFrame 作为 GUI 并设置了一个 componentListener this.addComponentListener(new CL(
我是一名优秀的程序员,十分优秀!