Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 暂时禁用JSplitPane分配器侦听器_Java_Listener_Jsplitpane - Fatal编程技术网

Java 暂时禁用JSplitPane分配器侦听器

Java 暂时禁用JSplitPane分配器侦听器,java,listener,jsplitpane,Java,Listener,Jsplitpane,我有一个简单的JSplitPane,它有一个关于调整大小的侦听器和一个关于分隔器移动的侦听器。我需要在resize listener中设置分隔符位置,而不让分隔符listener打印出“foo”,但是使用布尔侦听器的这段代码似乎无法解决问题 addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) {

我有一个简单的JSplitPane,它有一个关于调整大小的侦听器和一个关于分隔器移动的侦听器。我需要在resize listener中设置分隔符位置,而不让分隔符listener打印出“foo”,但是使用
布尔侦听器的这段代码似乎无法解决问题

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);
    }
}