Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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
MouseeEvent之前的Java JTree valueChanged事件_Java_Jtree - Fatal编程技术网

MouseeEvent之前的Java JTree valueChanged事件

MouseeEvent之前的Java JTree valueChanged事件,java,jtree,Java,Jtree,情况是这样的,我有一个带有选项卡式窗格的jFrame,在选项卡中有两个jTables和一个jTree。我希望能够根据用户是使用ctrl/shift+单击还是常规单击在表和树之间链接选择。(如果按住ctrl键并在第一个表/树中单击,则会添加到总体选择中;如果使用常规单击,则会清除其他表/树中的选择)。目前我对Java的jTree组件有一个问题。我添加了一个TreeSelectionListener和一个MouseListener,其中一个类实现了这两个接口,称之为MyBigListener; i、

情况是这样的,我有一个带有选项卡式窗格的jFrame,在选项卡中有两个jTables和一个jTree。我希望能够根据用户是使用ctrl/shift+单击还是常规单击在表和树之间链接选择。(如果按住ctrl键并在第一个表/树中单击,则会添加到总体选择中;如果使用常规单击,则会清除其他表/树中的选择)。目前我对Java的jTree组件有一个问题。我添加了一个TreeSelectionListener和一个MouseListener,其中一个类实现了这两个接口,称之为MyBigListener; i、 e

我的计划是,如果用户使用ctrl/shift+click,我可以在树选择侦听器实现的valueChanged(TreeSelectionEvent e)期间进行检查,则设置一个布尔标志。 我希望能够在valueChanged treeSelection事件之前处理鼠标事件,但问题是我在valueChanged treeSelection事件之后接收鼠标事件。这对我来说似乎很奇怪,我在按下鼠标事件触发之前收到选择更改,而选择更改实际上是由按下鼠标启动的。(我已经同步了布尔标志设置,讽刺的是,这有助于突出事件的错误顺序。)

我已经尝试过添加keyListener之类的替代方法,但当焦点位于单独的帧上时,这不起作用,当用户按住ctrl键,然后单击jTree,使其接收焦点并触发任何valueChanged选择事件时,这会使我陷入困境

任何帮助都将不胜感激,谢谢

--编辑--@akf 我在选项卡式窗格中有单独的jTables和jTrees,用作节点图中数据的摘要/控制面板。我在选项卡式窗格中使用这些组件对单独jFrame中显示的图形进行协调选择。每个表都可以单独工作,就像jTree一样。窗格之间的协调很棘手。到目前为止,这在jTable组件中工作得很好,因为我在MouseeEvent中触发了新的选择,在MouseeEvent中,我可以判断shift/ctrl按钮是否已按下,形成我的新选择,并将其传递给父帧,该父帧协调所有窗格之间的选择,并将最终选择发送到图形。但是,父级需要知道是否需要在窗格之间链接选择,或者挤压其他窗格。对于jTables,它又可以了,因为我通过鼠标点击触发选择更改。jTree是一个更大的问题,因为我正在做一些强制选择。如果单击一个分支,它将强制所有叶子进入选择。我需要实现一个TreeSelectionListener来实现这一点,但只需要获得一个valueChanged(TreeSelectionEvent)来实现更改。我添加了一个鼠标侦听器来侦听ctrl+clicks和shift+clicks,但显然事件并不总是以相同的顺序发生。。至少到目前为止,我在mousePressed事件之前收到valueChanged事件,因此检查在修改选择之后是否发生了ctrl+单击

现在,我正在发布一个悬而未决的选择更改,然后让MouseListener抓取它并将其发送到链上,但是如果这些事件不能保证以相同的顺序发生,那么在某个时候它将失败。实施延迟器也会让我感到不舒服

谢谢你迄今为止的帮助

--EDIT2--@ykaganovich


我认为重写fireValueChanged方法更接近正确的方式。根据我对哪些操作应该导致对其他组件的“链接”选择的定义,我需要在valuedChanged方法触发之前收集一些关于发生了什么的上下文。这基本上意味着在任何情况下,我都可以通过谁触发它来定义它的含义。也就是说,如果鼠标事件导致它,并且ctrl按下,那么设置我需要设置(解释)的内容,然后触发。如果由于键盘事件而改变,再次设置需要设置的内容,然后启动。我不认为TreeSelectionModel是可行的,因为我仍然不知道事件发生时的情况。我想这意味着我需要重写jTree的一些部分来实现这一点,但我想我会看看它是如何进行的。谢谢。

您可以在树选择事件之前或之后获得鼠标事件。最好不要依赖这样的命令。原因是树选择事件是响应鼠标事件而导致的。该鼠标事件侦听器是在侦听器之前还是之后调用的?也可能是


这类事情与PL&F的实现密切相关。

不要这样做,而是覆盖
JTree.fireValueChanged

尝试类似的方法(未经测试):

然后在侦听器中检查ChainedSelectionEvent的实例

编辑


实际上,我认为正确的方法是实现您自己的TreeSelectionModel,并覆盖fireValueChanged。假设
setSelectionPath
方法意味着一个新的选择,而
add/removeSelectionPath
意味着链接,您可以清楚地区分这两种方法。我不喜欢直接听键盘或鼠标事件,因为改变选择的方法不止一种(例如,如果有人按住SHIFT键并按下向下箭头,你将不会得到鼠标事件)。

这里的关键是要理解JTree是通过BasicTreeUI交付的。MouseHandler,请参见javax.swing.plaf.basic.basictreui

要回答核心问题“什么激发了fireValueChanged”,答案是“这个鼠标处理程序”。。。这是您转到tree.getMouseListeners()时返回的唯一一个鼠标侦听器

因此,您必须用自己的版本替换此默认鼠标侦听器。。。这有点棘手。我使用Jython,每个人都需要发现它。此代码应该
MyBigListener listener = new MyBigListener();
jTree1.addMouseListener( listener );
jTree1.addTreeSelectionListener( listener );

MyBigListener implements TreeSelectionListener, MouseListener {
  private boolean chained = false;
  public synchronized setChained(boolean ch){
    chained = ch;
  }
  public synchronized boolean isChained(){
    return chained
  }
  public void valueChanged(TreeSelectionEvent e){
    if(isChained()){ blah... }
  }

  public void mousePressed(MouseEvent e){
    setChained(e.isControlDown() || e.isShiftDown());
  }
}
class ChainedSelectionEvent extends TreeSelectionEvent {
  ChainedSelectionEvent(TreeSelectionEvent e) {
    super(e.newSource, e.paths, e.areNew, e.oldLeadSelectionPath, e.newLeadSelectionPath);
  }
}

protected void fireValueChanged(TreeSelectionEvent e) {
  if(chained) { // figure out separately
      super.fireValueChanged(new ChainedSelectionEvent(e));
  } else {
      super.fireValueChanged(e);
  }
}
  from javax.swing.plaf.basic import BasicTreeUI      
  def makeMouseHandlerClass():
    class MouseHandlerClass( BasicTreeUI.MouseHandler ):
      def mousePressed( self, mouseEvent ):
        genLog.info( "mouse handler MOUSE PRESSED!" )
        nTFSelf.mousePressedStatus = True
        BasicTreeUI.MouseHandler.mousePressed( self, mouseEvent )
        nTFSelf.mousePressedStatus = False

    return MouseHandlerClass
  suppliedMouseHandler = nTFSelf.taskTree.mouseListeners[ 0 ]
  nTFSelf.taskTree.removeMouseListener( suppliedMouseHandler  ) 
  nTFSelf.taskTree.addMouseListener( makeMouseHandlerClass()( nTFSelf.taskTree.getUI() ))