Поместите JTable в JTree
В связи с потоком Jtable в качестве узла Jtree я помещаю JTable в JTree, но JTree
Представление не отображается правильно на start_up, как я могу setPreferredSize
за JTable
, так как PreferredScrollableViewportSize
усаживается JTable
с рендерингом TableHeader
+ один Row
, один Row
остаются скрытыми, но после расширения узла (ов) TreeRenderer изменить и перекрасить setPreferredSize
к ожидаемому Dimension
import java.awt.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.*;
public class TreeWithTableRenderer extends JFrame {
private static final long serialVersionUID = 1L;
private JTree tree;
public TreeWithTableRenderer() {
DefaultMutableTreeNode AA1 = new DefaultMutableTreeNode("AA1");
DefaultMutableTreeNode AA2 = new DefaultMutableTreeNode("AA2");
DefaultMutableTreeNode A = new DefaultMutableTreeNode("A");
A.add(AA1);
A.add(AA2);
DefaultMutableTreeNode BB1 = new DefaultMutableTreeNode("BB1");
DefaultMutableTreeNode BB2 = new DefaultMutableTreeNode("BB2");
DefaultMutableTreeNode B = new DefaultMutableTreeNode("B");
B.add(BB1);
B.add(BB2);
DefaultMutableTreeNode CC1 = new DefaultMutableTreeNode("CC1");
DefaultMutableTreeNode CC2 = new DefaultMutableTreeNode("CC2");
DefaultMutableTreeNode C = new DefaultMutableTreeNode("C");
C.add(CC1);
C.add(CC2);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
root.add(A);
root.add(B);
root.add(C);
tree = new JTree(root);
tree.setCellRenderer(new MyTableInTreeCellRenderer());
tree.setRowHeight(0);
JScrollPane jsp = new JScrollPane(tree);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(jsp, BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
}
class MyTableInTreeCellRenderer extends JPanel implements TreeCellRenderer {
private static final long serialVersionUID = 1L;
private JTable table;
public MyTableInTreeCellRenderer() {
super(new BorderLayout());
table = new JTable();
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final String v = (String) ((DefaultMutableTreeNode) value).getUserObject();
table.setModel(new DefaultTableModel() {
private static final long serialVersionUID = 1L;
@Override
public int getRowCount() {
return 2;
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public Object getValueAt(int row, int column) {
return v + ":" + row + ":" + column;
}
});
table.setPreferredScrollableViewportSize(table.getPreferredSize());
return this;
}
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TreeWithTableRenderer().setVisible(true);
}
});
}
}
2 ответа
Избавьтесь от scrollPane, он в любом случае не работает (пока я согласен с Расселом:-) и добавьте таблицу и ее заголовок на панель, используя соответствующий LayoutManager:
public MyTableInTreeCellRenderer() {
super();
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
table = new JTable();
add(table.getTableHeader());
add(table);
}
вам, вероятно, придется немного подправить визуальные эффекты, отсутствуют левая и верхняя границы - не совсем уверен, какой компонент обычно их рисует, может быть scrollPane
редактировать
Забыл: причина запроса prefSize scrollPane при расчете необходимого размера (выполненного в делегате пользовательского интерфейса, а именно VariableHeightLayoutCache) компонента рендеринга заключается в том, что scrollPane еще не настроен с заголовком. Запрос выполняется до того, как панель добавлена в rendererPane, полная настройка выполняется в таблице addNotify, которая происходит только после добавления панели в иерархию.
Вы можете просто избавиться от ScrollPane и выложить заголовок и таблицу непосредственно на панель (с помощью null
LayoutManager, чтобы вы могли контролировать все самостоятельно):
static class TableTreeCellRenderer extends JPanel implements TreeCellRenderer {
private final JTable table;
TableTreeCellRenderer() {
table = new JTable();
setLayout(null);
add(table.getTableHeader());
add(table);
}
public Dimension getPreferredSize() {
Dimension headerSize = table.getTableHeader().getPreferredSize();
Dimension tableSize = table.getPreferredSize();
return new Dimension(Math.max(headerSize.width, tableSize.width),
headerSize.height + tableSize.height);
}
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
int headerHeight = table.getTableHeader().getPreferredSize().height;
table.getTableHeader().setBounds(0, 0, width, headerHeight);
table.setBounds(0, headerHeight, width, height - headerHeight);
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final String v = (String) ((DefaultMutableTreeNode) value).getUserObject();
table.setModel(new DefaultTableModel(new Object[][] {
{ v + "0", "1" },
{ v + "2", "3" }
}, new Object[] { "id", "value" } ));
invalidate();
return this;
}
}