JXTreeTable - 某些外观和感觉的奇怪的单元格渲染问题

时间:2016-02-06 04:55:00

标签: java swing intellij-idea look-and-feel swingx

所以这就是我的问题。我为intellij开发了一个插件,其中包含一个工具窗口,其中一部分包含一个带有JXTreeTable的选项卡式窗格

enter image description here

看起来很棒并按预期工作,直到我开始点击行。我将通过屏幕截图解释这个问题。

  1. 选择行

    enter image description here

    1. 将鼠标指针移动到下一行
  2. enter image description here

    1. 选择下一行
    2. enter image description here

      1. 对接下来的几行重复上述步骤,我以此结束!
      2. enter image description here

        urghh .. 呕吐

        1. 现在,如果我再次将鼠标指针向上移动,颜色会像魔术一样回归!
        2. enter image description here

          继续沿着行向上移动鼠标.. enter image description here

          1. 此外,如果我的鼠标指针离开列,任何时候......视图再次恢复正常(当然所选行除外)
          2. enter image description here

            我的外观是IntelliJ Dark Look and Feel - com.intellij.ide.ui.laf.IntelliJLaf,我使用System.out.println(UIManager.getLookAndFeel())

            找到了

            如果我以编程方式将其外观改为其他内容,则此问题将消失。但我有能力改变默认外观,所以我必须解决这个问题(或错误?)。

            我已经使用hack为我的JXTreeTable视图组件应用了不同的外观和感觉,并且它工作得很好..我在新窗口上打开另一个项目(这会创建一个新实例)我的工具窗口的新项目)和这次黑客攻击对我来说,为新项目实例正确设置外观,但重新设置我的第一个项目实例的外观默认

            哦,我正在使用DefaultTreeCellRenderer作为我的treetable。

            编辑:我为treetable实现了一个自定义单元格渲染器,未选中时将其设置为透明(如MadProgrammer建议的那样),但问题仍然存在。

            public class CustomCellRenderer extends JLabel
                    implements TreeCellRenderer {
            
                @Override
                public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            
                    if (selected){
                        setBackground(Color.BLUE);
                        setForeground(Color.WHITE);
                    }else{
                        setForeground(Color.BLACK);
                        setBackground(Color.WHITE);
                        setOpaque(false);
                    }
                    setText(value != null ? value.toString() : "<null>");
            
            
                    return this;
                }
            
            
            }
            

            现在结果略有变化。洛尔

            与上面的4.比较

            enter image description here

            编辑02:

            所以我决定使用treeTable.setFocusable(false)完全禁用我的treetable的单元格选择。好吧猜怎么着?现在当我点击一行时没有任何反应。没有细胞选择或颜色变化。但是,一旦我将鼠标指针移动到如上所示的下一行(步骤2),就会再次发生相同的故事。看起来它与某个鼠标监听器有关吗? idk ..这让我疯了。一些帮助将非常感谢!

            编辑03:

            这似乎是LAF给我带来的麻烦 com.intellij.ide.ui.laf.darcula.DarculaLaf

            来源:https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java

            编辑04

            所以我放弃了SwingX并试图从头开始实现一个JTreeTable组件,看看这是否能解决这个问题。我设法使用在线源代码组合实现。结果很有趣。

            enter image description here

            正如您所看到的那样,问题仍然存在但与以前不同,它不会从一个单元传播到另一个单元。所以基本上,它只显示在当前选定的单元格上。

            无论如何,我使用的实现包含一个MyTreeTable类,它扩展了JTreeTable类。完整的源代码可以找到here

            如果我实例化JTreeTable而不是MyTreeTable,则单元格渲染问题会消失,但JTreeTable的折叠/展开功能也会消失。它基本上变成了一棵扁平的树。 (没用!)所以不管是什么造成了这个问题,

            1. MyTreeTable班级
            2. 提供折叠/展开行为     到树组件
            3. 经过一些调试后,我将其缩小为以下方法。如果我从MyTreeTable类中删除此方法,则无法展开/折叠treetable,一旦包含细胞渲染问题,我就会回来。

                  public boolean editCellAt(int row, int column, EventObject e){
              
                  if(e instanceof MouseEvent){
                      MouseEvent me = (MouseEvent)e;
                      // If the modifiers are not 0 (or the left mouse button),
                      // tree may try and toggle the selection, and table
                      // will then try and toggle, resulting in the
                      // selection remaining the same. To avoid this, we
                      // only dispatch when the modifiers are 0 (or the left mouse
                      // button).
                      if(me.getModifiers()==0 ||
                              me.getModifiers()==InputEvent.BUTTON1_MASK){
                          for(int counter = getColumnCount()-1; counter>= 0;
                              counter--){
                              if(getColumnClass(counter)== TreeTableModel.class){
                                  MouseEvent newME = new MouseEvent
                                          (tree, me.getID(),
                                                  me.getWhen(), me.getModifiers(),
                                                  me.getX()-getCellRect(0, counter, true).x,
                                                  me.getY(), me.getClickCount(),
                                                  me.isPopupTrigger());
                                  tree.dispatchEvent(newME);
                                  break;
                              }
                          }
                      }
                      return false;
                  }
                  return super.editCellAt(row, column, e);
              }
              

              无论如何,这看起来像intellij方面的一个错误,因为它的外观和感觉特定,并且在某种程度上存在于SwingX和标准库JTreeTable实现中。所以也许我接近这个完全错误。但是,如果有可能的解决办法,请分享您的想法。我需要解决这个问题。感谢

0 个答案:

没有答案