1

JTreeの中に がありJScrollPane、スクロールバーを使用すると、下の画像でわかるように、ツリーがすべてぼやけます。

ウィンドウを最小化して復元するか、ツリーをクリックしてノードを展開または折りたたむなど、再描画するために何かを行うと、通常に戻ります(ただし、ウィンドウを画面からドラッグしても、ぼやけは消えません戻るか、別のウィンドウをその前にドラッグします)。

JTree にはカスタムTreeModelレンダラーとセル レンダラーがあります。最近の変更はTreeModel; セル レンダラーは長い間そこにあり、正常に動作していました。セル レンダラーは のサブクラスであり、(カスタム アイコンを表示するために) メソッドDefaultTreeCellRendererのみがgetTreeCellRendererComponentオーバーライドされています。

DefaultMutableTreeNode以前は、表示するデータを含むデータ構造から sを生成していましたが、ノード数が多い場合 (10,000 以上など) にパフォーマンスの問題が発生していました。私が持っていたデータはすでにツリー構造になっていたので、 を使用せずにその周りにカスタム TreeModel を作成するのは非常に簡単であることに気付きましたDefaultMutableTreeNode。これにより、JTree のデータがより迅速に読み込まれましたが、このぼやけたスクロールの問題が残っています。

ぼやけた JTree

以下のコードはアプリケーションからのものではありませんが、そのままコンパイルされ、問題が示されます。線を削除tree.setBackgroundすると、ぼやけた動作が停止します。

package stackoverflow;

import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.*;
import java.awt.Color;


public class NumberTreeModel implements TreeModel {

   public static final int ROOT_NUMBER = 100;

   public Object getChild(Object parent, int index) {
      return index;
   }

   public int getChildCount(Object node) {
      return isLeaf(node) ? 0 : ROOT_NUMBER;
   }

   @Override
   public int getIndexOfChild(Object parent, Object child) {
      int parentValue = ((Integer) parent).intValue();
      int childValue = ((Integer) child).intValue();
      return parentValue == ROOT_NUMBER ? childValue : -1 ;
   }

   public Object getRoot() {
      return ROOT_NUMBER;
   }

   public boolean isLeaf(Object node) {
      return ((Integer) node).intValue() < ROOT_NUMBER;
   }

   public void addTreeModelListener(TreeModelListener listener) { }
   public void removeTreeModelListener(TreeModelListener listener) { }
   public void valueForPathChanged(TreePath path, Object obj) { }

   public static void display() {

      JFrame frame = new JFrame("Number JTree");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      NumberTree tree = new NumberTree();
      tree.setModel(new NumberTreeModel());
      tree.setBackground(new Color(0,0,0,0));
      JScrollPane scroll = new JScrollPane(tree);
      frame.add(scroll);
      scroll.getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE);
      tree.expandRow(0);
      frame.pack();
      frame.setSize(300, 400);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static class NumberTree extends JTree {
      static final long serialVersionUID = 1;

      @Override
      public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf,
               int row, boolean hasFocus) {
         if (value instanceof Integer) {
            int n = ((Integer) value).intValue();
            return n + "=========".substring(0, n % 10);
         } else {
            System.out.println("value class=" + value.getClass());
            return value.toString();
         }
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            display();
         }
      });
   }
}
4

2 に答える 2

2

ここに示されているように、上書きpaintComponent()したものの無視したと思われます。super.paintComponent(g)

可能性は低いですがsetScrollMode()、スクロール ペインのビューポートで試してみるかもしれません。

質問を編集してsscceを含めると、問題が明確になる場合があります。

補遺: 参考までに、質問に見られるレンダリング アーティファクトを示さない例を次に示します。

ここに画像の説明を入力

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;

/**
 * @see https://stackoverflow.com/a/15696825/230513
 */
public class Sscce {

    private void display() {
        JFrame f = new JFrame("Sscce");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTree tree = new JTree();
        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandRow(i);
        }
        f.add(new JScrollPane(tree));
        f.pack();
        f.setSize(200, 200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Sscce().display();
            }
        });
    }
}
于 2013-03-29T03:21:59.003 に答える
0

解決:

  • 不透明でない色setColorの背景を変更するために使用しないでください。JTree

  • ノードの視覚的な透明性のために、 JTree set background of node to nonopaqueで説明されているように、およびTreeCellRendererに対して null を返すカスタムを実装します。getBackgroundNonSelectionColorgetBackground

    • のビューポート モードを に設定するとJScrollPaneJViewport.SIMPLE_SCROLL_MODEスクロールのぼやけの問題が改善されますが、ndo の展開と折りたたみに関する問題が再描画されるとは限りません。
于 2013-03-29T19:18:08.283 に答える