assertj / assertj/assertj-swing

Select + drag may fail in JTree in JScrollPane if the row is only partially visible

オープン
#33 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

bug Critical import from fest-swing
主要言語
Java
スター
121
フォーク
52
PR マージ指標
30日以内にマージされた PR はありません

説明

_Issue by **[Per Rovegård](http://jira.codehaus.org/secure/ViewProfile.jspa?name=provegard)** from Thu, 20 Jan 2011 02:34:16 -0600_
_Originally opened as http://jira.codehaus.org/browse/FEST-422_

---

Description

I have created a small test program where a JTree is put in a JScrollPane. The tree has a root and a child with a really, really long name. The scroll pane is placed in a JSplitPane with the divider location set so that the row with the really long name is only partially visible. The other split pane component is a label.

The tree supports drag and drop with printouts to the console, and the label prints a message on the console if a mouse button is pressed.

When the test program runs, notice that selectRow fails, as does drag. When these calls are made, the mouse click occurs on the label instead, as can be seen on the console.

Test program


import static org.fest.swing.timing.Pause.pause;

import java.awt.Component;
import java.awt.datatransfer.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.tree.*;

import org.fest.swing.core.*;
import org.fest.swing.finder.WindowFinder;
import org.fest.swing.fixture.FrameFixture;

public class SelectAndDnDTest
{
public static void main(String[] args)
{
Robot robot = BasicRobot.robotWithNewAwtHierarchy();

SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JSplitPane pane = new JSplitPane();
pane.setDividerLocation(150);

JLabel label = new JLabel("Test");
label.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
System.out.println("Mouse press on label");
}
});

pane.setLeftComponent(new JScrollPane(createTree()));
pane.setRightComponent(label);

JFrame frame = new JFrame("Test");
frame.setSize(640, 480);
frame.getContentPane().add(pane);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});

FrameFixture window = WindowFinder.findFrame(JFrame.class).using(robot);

pause(1000);
window.tree().selectRow(1);
pause(1000);
window.tree().drag(1);
pause(1000);
window.tree().drop(0);

robot.cleanUp();
}

protected static Component createTree()
{
final JTree tree = new JTree();
tree.setDragEnabled(true);
tree.setDropMode(DropMode.ON);
tree.setTransferHandler(new TransferHandler()
{
@Override
public int getSourceActions(JComponent c)
{
return COPY;
}

@Override
public boolean importData(TransferSupport support)
{
Transferable t = support.getTransferable();
try
{
String s = (String) t.getTransferData(DataFlavor.stringFlavor);
DropLocation loc = support.getDropLocation();
TreePath dropPath = tree.getPathForLocation(loc.getDropPoint().x, loc.getDropPoint().y);

System.out.println("Dragged " + s + " and dropped on " + dropPath);
}
catch (Exception ex)
{
ex.printStackTrace(System.err);
return false;
}
return true;
}

@Override
public boolean canImport(TransferSupport support)
{
return true;
}

@Override
protected Transferable createTransferable(JComponent c)
{
TreePath path = tree.getSelectionPath();
return new StringSelection(path.toString());
}
});

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root", true);
TreeModel model = new DefaultTreeModel(root);

root.add(new DefaultMutableTreeNode(
"Child with a really, really long name that makes the center point move to the right very much."));

tree.setModel(model);

return tree;
}
}


Actual printout


Mouse press on label

Mouse press on label

Mouse press on label

Expected printout


Dragged [Root, Child with a really, really long name that makes the center point move to the right very much.] and dropped on [Root]

Fix

The problem seems to be in JTreeLocation.rowBoundsAndCoordinates. Although the JavaDoc comment says "Returns the bounds and visible coordinates of the given row", the method fails to take into account the visible rectangle of the tree. Suggested fix:


  @RunsInCurrentThread

public Pair<Rectangle, Point> rowBoundsAndCoordinates(JTree tree, int row) {
Rectangle rowBounds = tree.getRowBounds(validIndex(tree, row));
// BEGIN FIX
Rectangle visibleRect = tree.getVisibleRect();
rowBounds = rowBounds.intersection(visibleRect);
// END FIX
if (rowBounds != null) return new Pair<Rectangle, Point>(rowBounds, pointAt(rowBounds));
throw new LocationUnavailableException(concat("The tree row ", row, " is not visible"));
}

---

votes (original issue): 0
watches (original issue): 0

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

JTreeLocation.rowBoundsAndCoordinates から開始し、ツリー行が一部だけ表示されている状態で、提供されている SelectAndDnDTest プログラムを実行します。ツリーの表示領域に照らして位置の計算を確認します。選択とドラッグ&ドロップの対象が JTree になり、ラベル上でのマウスプレスではなく、期待されるドラッグ&ドロップの出力が生成されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
java
領域
desktop, testing-qa
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
43/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。