Java 暂时禁用JSplitPane分配器侦听器
我有一个简单的JSplitPane,它有一个关于调整大小的侦听器和一个关于分隔器移动的侦听器。我需要在resize listener中设置分隔符位置,而不让分隔符listener打印出“foo”,但是使用Java 暂时禁用JSplitPane分配器侦听器,java,listener,jsplitpane,Java,Listener,Jsplitpane,我有一个简单的JSplitPane,它有一个关于调整大小的侦听器和一个关于分隔器移动的侦听器。我需要在resize listener中设置分隔符位置,而不让分隔符listener打印出“foo”,但是使用布尔侦听器的这段代码似乎无法解决问题 addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) {
布尔侦听器的这段代码似乎无法解决问题
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
listener = false;
setDividerLocation(lastDividerLocation);
listener = true;
}
});
addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if (listener) {
System.out.println("foo");
}
}
});
有什么想法吗?谢谢
编辑:
SSCCE
根据我的经验,这是我发现的制造这种东西的仅有的两种方法之一。您可以设置共享布尔值,或者删除并添加回侦听器
我会更倾向于删除侦听器,这样更安全,而且在我看来,这并不是一个真正昂贵的操作(现在我承认,如果在调整大小的过程中发送了这么多次事件,这可能并不理想)
但是,您的解决方案也可以工作,因为这两个事件都发生在事件分派线程上,所以您不应该遇到并发问题。但是,请确保不要在上下文之外更改此布尔值
在您的案例中,另一个有趣的问题是为什么需要将最后一个位置设置回原来的位置?你到底想要实现什么?难道不能用一个合适的值来实现吗?你说它不能解决问题是什么意思?你尝试过删除并重新添加propertyChangeListener吗?@StephaneM当我调整JSplitPane的大小时,它仍然打印出“foo”@SaviourSelf我真的不想这样做,它会很慢,不是吗?我很好奇你是否遇到了同步问题。你能发一张SSCCE吗?不过我不认为这会很慢。我已经尝试了你的两个建议,但都没能奏效。我需要分隔器的比例位置在调整帧大小时保持完全相同。例如,当我将位置设置为0.7时,我希望它保持为0.7,无论帧大小如何调整。@Glissinda-尝试使用setResizeWeight(0.5),调整大小时,它应该保持两侧之间的百分比相等。@Gnoupi-即使我没有更改分隔符的位置,只是使用setResizeWeight(0.5)调整大小,它不断改变它的价值。另外,我认为这是行不通的,因为当除法器为0.7时,系数也应该为0.7,对吗?@Glissinda-不要混淆setDividerLocation和setResizeWeight。调整大小权重确定调整大小时从哪一侧占用或添加空间。默认值为0,因此左侧/顶部不会发生任何变化。0.5将使两侧的大小相等,无论分隔器的位置如何。系数应保持不变(只要不使用极值,如过度减小窗格大小,在这种情况下,系数将丢失并重置为中心位置(但您的解决方案具有相同的效果)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class Split extends JSplitPane {
private boolean listener = true;
private double lastDividerLocation = 0.5;
public Split() {
this.setOrientation(VERTICAL_SPLIT);
this.add(new JPanel(), JSplitPane.TOP);
this.add(new JPanel(), JSplitPane.BOTTOM);
this.setDividerLocation(300);
final PropertyChangeListener dividerListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if (listener) {
if (getOrientation() == VERTICAL_SPLIT) {
lastDividerLocation = (double) getDividerLocation() / (double) getHeight();
} else if (getOrientation() == HORIZONTAL_SPLIT) {
lastDividerLocation = (double) getDividerLocation() / (double) getWidth();
}
System.out.println("divider: " + lastDividerLocation);
}
}
};
addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, dividerListener);
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
listener = false;
setDividerLocation(lastDividerLocation);
listener = true;
}
});
this.setOneTouchExpandable(true);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setSize(800, 600);
frame.add(new Split(), BorderLayout.CENTER);
frame.setVisible(true);
}
}