을 다시 그리기. 내가 JXTreeTable
을 넣었을 때, 나는 웬일인지 그 줄이 자동으로 줄무늬를 가지지 않는 것을 알아 차렸다. JXTreeTable, 행 스트라이핑과 적절한 나는 모양을 사용하여 기본적으로 테이블의 행 스트라이핑을 수행하는 느낌이있어
그것은 특별히 대신 전체 셀의 텍스트의 경계를 재 도장되어 JXTreeTable
것 같아를 . 이유를 알아 내기 위해 디버거에서이 문제를 잡아 내려고 노력했지만 프로그램간에 전환 할 때마다 전체 창이 다시 표시되므로이 종류의 것을 잡는 것이 거의 불가능합니다.
JTable
및 JTree
은 모두 올바로 수행 동작합니다. 이 모양과 느낌은 (Quaqua와 Synth와 같은) JTree
의 행 전체를 그리는 것이므로 어쩌면 그것과 관련이 있습니다. 아마도 JXTreeTable
에는 모양과 느낌이 트리의 행을 페인트하지 않는다는 가정이 있습니다. 그렇다면 해결 방법이 있습니까? 이 룩앤필에 문제가있는 것은 아닙니다.
코드 : 1 라운드
import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.decorator.AbstractHighlighter;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
import org.jdesktop.swingx.treetable.DefaultTreeTableModel;
import org.jdesktop.swingx.treetable.TreeTableModel;
import org.trypticon.haqua.HaquaLookAndFeel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.Arrays;
public class TreeTableDemo2 implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new TreeTableDemo2());
}
@Override
public void run() {
try {
UIManager.setLookAndFeel(new HaquaLookAndFeel());
} catch (Exception e) {
throw new RuntimeException(e);
}
JFrame frame = new JFrame("Tree Table Demo");
frame.setLayout(new BorderLayout());
frame.add(createPanel(), BorderLayout.CENTER);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public JPanel createPanel() {
JPanel panel = new JPanel(new BorderLayout());
TreeTableModel treeTableModel = new DummyTreeTableModel();
JXTreeTable treeTable = new FixedTreeTable(treeTableModel);
JScrollPane treeTableScroll = new JScrollPane(treeTable);
panel.add(treeTableScroll, BorderLayout.CENTER);
return panel;
}
private static class FixedTreeTable extends JXTreeTable {
private static final Highlighter oddRowHighlighter = new AbstractHighlighter() {
@Override
protected Component doHighlight(Component component, ComponentAdapter componentAdapter) {
if (componentAdapter.row % 2 != 0 &&
!componentAdapter.isSelected()) {
component.setBackground(UIManager.getColor("Table.alternateRowColor"));
}
return component;
}
};
public FixedTreeTable(TreeTableModel treeModel) {
super(treeModel);
// This hack makes it paint correctly after releasing the mouse, which is not quite good enough.
// getSelectionModel().addListSelectionListener(new ListSelectionListener() {
// @Override
// public void valueChanged(ListSelectionEvent e) {
// Rectangle repaintRange = getCellRect(e.getFirstIndex(), 0, true);
// repaintRange.add(getCellRect(e.getLastIndex(), 0, true));
// repaint(repaintRange);
// }
// });
}
@Override
public void updateUI() {
removeHighlighter(oddRowHighlighter);
super.updateUI();
// JTable does this striping automatically but JXTable's default renderer
// seems to ignore it, so JXTreeTable inherits this broken behaviour.
if (UIManager.get("Table.alternateRowColor") != null) {
addHighlighter(oddRowHighlighter);
}
}
}
private static class DummyTreeTableNode extends DefaultMutableTreeTableNode {
private final Object[] values;
private DummyTreeTableNode(String name) {
super(name);
values = new Object[5];
values[0] = name;
}
private DummyTreeTableNode(Object... values) {
super(values[0]);
this.values = values;
}
@Override
public Object getValueAt(int column) {
return values[column];
}
}
private static class DummyTreeTableModel extends DefaultTreeTableModel {
private static DefaultMutableTreeTableNode rootNode = new DefaultMutableTreeTableNode();
static {
DefaultMutableTreeTableNode blue = new DefaultMutableTreeTableNode("Blue");
blue.add(new DummyTreeTableNode("Orionis C", 33000, 30000.0, 18.0, 5.90));
rootNode.add(blue);
DefaultMutableTreeTableNode bluish = new DefaultMutableTreeTableNode("Bluish");
bluish.add(new DummyTreeTableNode("Becrux", 30000, 16000.0, 16.0, 5.70));
bluish.add(new DummyTreeTableNode("Spica", 22000, 8300.0, 10.5, 5.10));
bluish.add(new DummyTreeTableNode("Achernar", 15000, 750.0, 5.40, 3.70));
bluish.add(new DummyTreeTableNode("Rigel", 12500, 130.0, 3.50, 2.70));
rootNode.add(bluish);
DefaultMutableTreeTableNode blueWhite = new DefaultMutableTreeTableNode("Blue-White");
blueWhite.add(new DummyTreeTableNode("Sirius A", 9500, 63.0, 2.60, 2.30));
blueWhite.add(new DummyTreeTableNode("Fomalhaut", 9000, 40.0, 2.20, 2.00));
blueWhite.add(new DummyTreeTableNode("Altair", 8700, 24.0, 1.90, 1.80));
rootNode.add(blueWhite);
DefaultMutableTreeTableNode white = new DefaultMutableTreeTableNode("White");
white.add(new DummyTreeTableNode("Polaris A", 7400, 9.0, 1.60, 1.50));
white.add(new DummyTreeTableNode("Eta Scorpii", 7100, 6.3, 1.50, 1.30));
white.add(new DummyTreeTableNode("Procyon A", 6400, 4.0, 1.35, 1.20));
rootNode.add(white);
DefaultMutableTreeTableNode yellowWhite = new DefaultMutableTreeTableNode("Yellow-White");
yellowWhite.add(new DummyTreeTableNode("Alpha Centauri A", 5900, 1.45, 1.08, 1.05));
yellowWhite.add(new DummyTreeTableNode("The Sun", 5800, 100.0, 1.00, 1.00));
yellowWhite.add(new DummyTreeTableNode("Mu Cassiopeiae", 5600, 0.70, 0.95, 0.91));
yellowWhite.add(new DummyTreeTableNode("Tau Ceti", 5300, 0.44, 0.85, 0.87));
rootNode.add(yellowWhite);
DefaultMutableTreeTableNode orange = new DefaultMutableTreeTableNode("Orange");
orange.add(new DummyTreeTableNode("Pollux", 5100, 0.36, 0.83, 0.83));
orange.add(new DummyTreeTableNode("Epsilon Eridani", 4830, 0.28, 0.78, 0.79));
orange.add(new DummyTreeTableNode("Alpha Centauri B", 4370, 0.18, 0.68, 0.74));
rootNode.add(orange);
DefaultMutableTreeTableNode red = new DefaultMutableTreeTableNode("Red");
red.add(new DummyTreeTableNode("Lalande 21185", 3400, 0.03, 0.33, 0.36));
red.add(new DummyTreeTableNode("Ross 128", 3200, 0.0005, 0.20, 0.21));
red.add(new DummyTreeTableNode("Wolf 359", 3000, 0.0002, 0.10, 0.12));
rootNode.add(red);
}
private static final Object[] columnNames = {
"Star", "Temperature (K)", "Luminosity", "Mass", "Radius"
};
public DummyTreeTableModel() {
super(rootNode, Arrays.asList(columnNames));
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == 0) {
return String.class;
} else {
return Double.class;
}
}
@Override
public boolean isCellEditable(Object node, int column) {
return false;
}
}
}
추가 조사 : 나는 마침내 JXTreeTable
에 페인트 방법을 보면서 함정에 디버거의 상태를 관리
.
iconRect = {[email protected]}"java.awt.Rectangle[x=20,y=92,width=16,height=16]"
textRect = {[email protected]}"java.awt.Rectangle[x=20,y=-17,width=62,height=15]"
itemRect = {[email protected]}"java.awt.Rectangle[x=20,y=36,width=103,height=18]"
나는 아직, 확실히 사각형을 그리는이 값을 사용하고 있음을 확인하지 않은하지만 : 내가 볼 것은 그들이 의심스러운 행동에 해당 같이 일부 필드를 가지고있는 ClippedTreeCellRenderer
뭔가라는 점이다 textRect
은 정확히 다시 그리는 작은 창 크기입니다. 이제 질문은, 지구상에서 JXTreeTable
이이 값들을 끌어 당기는 이유와 그것들을 사용하는 이유는 무엇입니까?
내 본능은 JXTreeTable
의 렌더러가 트리 셀 렌더러를 사용하여 직접 트리 자체에 페인트를 지정하는 대신 셀을 직접 렌더링한다고 말합니다. 행 배경 및 확장/축소 아이콘을 페인팅하는 논리는 셀이 아닌 트리에 있으므로 트리밍을 수행하는 경우 트리가 일관되게 페인팅되지 않습니다. 2 라운드
추가 조사 :
는 내가 완전히 잘못된 길이었다 생각합니다. 그것은 가 페인트되는입니다 전체 행처럼 보이지만 tree.isPathSelected (경로) 새로 선택된 파란색 행에 대한 false
를 반환하고 방금 해제 행에 대해 true
을 반환합니다.
DefaultTreeSelectionModel
의 중단 점을 통해 마우스를 놓은 후에 트리 선택이 업데이트된다는 것을 확인할 수 있습니다. 따라서 결국 마우스 오른쪽 단추가 올바르게 렌더링됩니다.
나는 동기 사람들을 유지 어떻게 볼 JXTreeTable에 더 발굴해야합니다.