mirror of https://github.com/weisJ/darklaf.git
weisj
5 years ago
17 changed files with 1440 additions and 248 deletions
@ -0,0 +1,121 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.table.TableCellRenderer; |
||||||
|
import javax.swing.tree.TreeModel; |
||||||
|
import javax.swing.tree.TreePath; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.ui.tree.DarkTreeUI; |
||||||
|
import com.github.weisj.darklaf.util.DarkUIUtil; |
||||||
|
|
||||||
|
public class DefaultTreeTableCellRenderer extends JComponent implements TableCellRenderer { |
||||||
|
|
||||||
|
private final JTreeTable treeTable; |
||||||
|
private final RendererTree rendererTree = new RendererTree(); |
||||||
|
private int paintingRow; |
||||||
|
|
||||||
|
public DefaultTreeTableCellRenderer(final JTreeTable treeTable, final TreeModel model) { |
||||||
|
this.treeTable = treeTable; |
||||||
|
rendererTree.setRowHeight(rendererTree.getRowHeight()); |
||||||
|
rendererTree.setModel(model); |
||||||
|
rendererTree.setBounds(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintComponent(final Graphics g) { |
||||||
|
DarkTreeUI ui = DarkUIUtil.getUIOfType(rendererTree.getUI(), DarkTreeUI.class); |
||||||
|
if (ui != null) { |
||||||
|
ui.paintRow(g, paintingRow); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, |
||||||
|
final boolean hasFocus, final int row, final int column) { |
||||||
|
paintingRow = row; |
||||||
|
rendererTree.setFocus(hasFocus || table.hasFocus()); |
||||||
|
rendererTree.setSelectable(!hasFocus); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TreeTableTree getTree() { |
||||||
|
return rendererTree; |
||||||
|
} |
||||||
|
|
||||||
|
protected class RendererTree extends TreeTableTree { |
||||||
|
private boolean focus; |
||||||
|
private boolean selectable; |
||||||
|
|
||||||
|
public void setRowHeight(final int rowHeight) { |
||||||
|
if (rowHeight > 0) { |
||||||
|
super.setRowHeight(rowHeight); |
||||||
|
if (treeTable != null && treeTable.getRowHeight() != rowHeight) { |
||||||
|
treeTable.setRowHeight(getRowHeight()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void repaint(final int x, final int y, final int width, final int height) { |
||||||
|
treeTable.repaint(x, y, treeTable.getColumnModel().getColumn(0).getWidth(), height); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isRowSelected(final int row) { |
||||||
|
return selectable && super.isRowSelected(row); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isPathSelected(final TreePath path) { |
||||||
|
return selectable && super.isPathSelected(path); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void scrollRectToVisible(final Rectangle aRect) { |
||||||
|
treeTable.scrollRectToVisible(aRect); |
||||||
|
} |
||||||
|
|
||||||
|
public void setFocus(final boolean focus) { |
||||||
|
this.focus = focus; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSelectable(final boolean selectable) { |
||||||
|
this.selectable = selectable; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hasFocus() { |
||||||
|
return focus; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isFocusOwner() { |
||||||
|
return super.hasFocus(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.InputEvent; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.TreeSelectionEvent; |
||||||
|
import javax.swing.event.TreeSelectionListener; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.components.treetable.model.AbstractTreeTableModel; |
||||||
|
import com.github.weisj.darklaf.components.treetable.model.DefaultTreeTableSelectionModel; |
||||||
|
import com.github.weisj.darklaf.components.treetable.model.TreeTableModel; |
||||||
|
import com.github.weisj.darklaf.ui.cell.hint.CellHintPopupListener; |
||||||
|
import com.github.weisj.darklaf.ui.tree.DarkTreeUI; |
||||||
|
import com.github.weisj.darklaf.util.DarkUIUtil; |
||||||
|
|
||||||
|
public class JTreeTable extends JTable implements TreeSelectionListener { |
||||||
|
|
||||||
|
private final TreeTableTree tree; |
||||||
|
|
||||||
|
public JTreeTable(final AbstractTreeTableModel treeTableModel) { |
||||||
|
DefaultTreeTableCellRenderer treeCellRenderer = new DefaultTreeTableCellRenderer(this, treeTableModel); |
||||||
|
tree = treeCellRenderer.getTree(); |
||||||
|
|
||||||
|
add(tree); |
||||||
|
|
||||||
|
tree.putClientProperty(DarkTreeUI.KEY_IS_TABLE_TREE, true); |
||||||
|
|
||||||
|
DefaultTreeTableSelectionModel selectionModel = new DefaultTreeTableSelectionModel(tree); |
||||||
|
tree.setSelectionModel(selectionModel); |
||||||
|
setSelectionModel(selectionModel); |
||||||
|
tree.addTreeSelectionListener(this); |
||||||
|
|
||||||
|
setDefaultRenderer(TreeTableModel.class, treeCellRenderer); |
||||||
|
super.setModel(new TreeTableModelAdapter(treeTableModel, tree)); |
||||||
|
setShowHorizontalLines(false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doLayout() { |
||||||
|
super.doLayout(); |
||||||
|
int grid = getShowVerticalLines() ? getIntercellSpacing().width : 0; |
||||||
|
tree.setBounds(0, 0, getColumnModel().getColumn(0).getWidth() - grid, getHeight()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void repaint(final Rectangle r) { |
||||||
|
super.repaint(r); |
||||||
|
SwingUtilities.invokeLater(() -> { |
||||||
|
DarkTreeUI ui = DarkUIUtil.getUIOfType(tree.getUI(), DarkTreeUI.class); |
||||||
|
if (ui != null) { |
||||||
|
CellHintPopupListener<JTree, ?> listener = ui.getPopupListener(); |
||||||
|
if (listener != null) listener.repaint(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getComponentCount() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void processEvent(final AWTEvent e) { |
||||||
|
if (e instanceof InputEvent) { |
||||||
|
if (e instanceof KeyEvent) { |
||||||
|
if (getColumnModel().getSelectionModel().getLeadSelectionIndex() == 0 |
||||||
|
&& !((KeyEvent) e).isShiftDown()) { |
||||||
|
tree.processEvent(e); |
||||||
|
} |
||||||
|
} |
||||||
|
if (((InputEvent) e).isConsumed()) return; |
||||||
|
} |
||||||
|
super.processEvent(e); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void valueChanged(final TreeSelectionEvent e) { |
||||||
|
repaint(0, 0, getColumnModel().getColumn(0).getWidth(), getHeight()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.TreeExpansionEvent; |
||||||
|
import javax.swing.event.TreeExpansionListener; |
||||||
|
import javax.swing.table.AbstractTableModel; |
||||||
|
import javax.swing.tree.TreeNode; |
||||||
|
import javax.swing.tree.TreePath; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.components.treetable.model.TreeTableModel; |
||||||
|
|
||||||
|
public class TreeTableModelAdapter extends AbstractTableModel { |
||||||
|
|
||||||
|
private final JTree tree; |
||||||
|
private final TreeTableModel treeTableModel; |
||||||
|
|
||||||
|
public TreeTableModelAdapter(final TreeTableModel treeTableModel, final JTree tree) { |
||||||
|
this.tree = tree; |
||||||
|
this.treeTableModel = treeTableModel; |
||||||
|
|
||||||
|
tree.addTreeExpansionListener(new TreeExpansionListener() { |
||||||
|
public void treeExpanded(final TreeExpansionEvent event) { |
||||||
|
TreePath path = event.getPath(); |
||||||
|
int start = tree.getRowForPath(path); |
||||||
|
int length = ((TreeNode) path.getLastPathComponent()).getChildCount(); |
||||||
|
int selection = tree.getLeadSelectionRow(); |
||||||
|
fireTableRowsInserted(start, start + length); |
||||||
|
tree.setSelectionRow(selection); |
||||||
|
} |
||||||
|
|
||||||
|
public void treeCollapsed(final TreeExpansionEvent event) { |
||||||
|
TreePath path = event.getPath(); |
||||||
|
int start = tree.getRowForPath(path); |
||||||
|
int length = ((TreeNode) path.getLastPathComponent()).getChildCount(); |
||||||
|
int selection = tree.getLeadSelectionRow(); |
||||||
|
fireTableRowsDeleted(start, start + length); |
||||||
|
tree.setSelectionRow(selection); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void fireTableRowsDeleted(final int firstRow, final int lastRow) { |
||||||
|
super.fireTableRowsDeleted(firstRow, lastRow); |
||||||
|
} |
||||||
|
|
||||||
|
public int getColumnCount() { |
||||||
|
return treeTableModel.getColumnCount(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getColumnName(final int column) { |
||||||
|
return treeTableModel.getColumnName(column); |
||||||
|
} |
||||||
|
|
||||||
|
public Class<?> getColumnClass(final int column) { |
||||||
|
return treeTableModel.getColumnClass(column); |
||||||
|
} |
||||||
|
|
||||||
|
public int getRowCount() { |
||||||
|
return tree.getRowCount(); |
||||||
|
} |
||||||
|
|
||||||
|
protected Object nodeForRow(final int row) { |
||||||
|
TreePath treePath = tree.getPathForRow(row); |
||||||
|
return treePath.getLastPathComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
public Object getValueAt(final int row, final int column) { |
||||||
|
return treeTableModel.getValueAt(nodeForRow(row), column); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isCellEditable(final int row, final int column) { |
||||||
|
return treeTableModel.isCellEditable(nodeForRow(row), column); |
||||||
|
} |
||||||
|
|
||||||
|
public void setValueAt(final Object value, final int row, final int column) { |
||||||
|
treeTableModel.setValueAt(value, nodeForRow(row), column); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.tree.TreeSelectionModel; |
||||||
|
|
||||||
|
public interface TreeTableSelectionModel extends TreeSelectionModel, ListSelectionModel {} |
@ -0,0 +1,40 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
public class TreeTableTree extends JTree { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void processEvent(final AWTEvent e) { |
||||||
|
super.processEvent(e); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void paint(final Graphics g) {} |
||||||
|
} |
@ -0,0 +1,119 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import javax.swing.event.EventListenerList; |
||||||
|
import javax.swing.event.TreeModelEvent; |
||||||
|
import javax.swing.event.TreeModelListener; |
||||||
|
import javax.swing.tree.TreePath; |
||||||
|
|
||||||
|
public abstract class AbstractTreeTableModel implements TreeTableModel { |
||||||
|
protected TreeTableNode root; |
||||||
|
protected EventListenerList listenerList = new EventListenerList(); |
||||||
|
|
||||||
|
private static final int CHANGED = 0; |
||||||
|
private static final int INSERTED = 1; |
||||||
|
private static final int REMOVED = 2; |
||||||
|
private static final int STRUCTURE_CHANGED = 3; |
||||||
|
|
||||||
|
public AbstractTreeTableModel(final TreeTableNode root) { |
||||||
|
this.root = root; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public TreeTableNode getRoot() { |
||||||
|
return root; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isLeaf(final Object node) { |
||||||
|
return getChildCount(node) == 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void valueForPathChanged(final TreePath path, final Object newValue) {} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getIndexOfChild(final Object parent, final Object child) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addTreeModelListener(final TreeModelListener l) { |
||||||
|
listenerList.add(TreeModelListener.class, l); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeTreeModelListener(final TreeModelListener l) { |
||||||
|
listenerList.remove(TreeModelListener.class, l); |
||||||
|
} |
||||||
|
|
||||||
|
private void fireTreeNode(final int changeType, final Object source, final Object[] path, final int[] childIndices, |
||||||
|
final Object[] children) { |
||||||
|
Object[] listeners = listenerList.getListenerList(); |
||||||
|
TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children); |
||||||
|
for (int i = listeners.length - 2; i >= 0; i -= 2) { |
||||||
|
if (listeners[i] == TreeModelListener.class) { |
||||||
|
switch (changeType) { |
||||||
|
case CHANGED : |
||||||
|
((TreeModelListener) listeners[i + 1]).treeNodesChanged(e); |
||||||
|
break; |
||||||
|
case INSERTED : |
||||||
|
((TreeModelListener) listeners[i + 1]).treeNodesInserted(e); |
||||||
|
break; |
||||||
|
case REMOVED : |
||||||
|
((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e); |
||||||
|
break; |
||||||
|
case STRUCTURE_CHANGED : |
||||||
|
((TreeModelListener) listeners[i + 1]).treeStructureChanged(e); |
||||||
|
break; |
||||||
|
default : |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected void fireTreeNodesChanged(final Object source, final Object[] path, |
||||||
|
final int[] childIndices, final Object[] children) { |
||||||
|
fireTreeNode(CHANGED, source, path, childIndices, children); |
||||||
|
} |
||||||
|
|
||||||
|
protected void fireTreeNodesInserted(final Object source, final Object[] path, |
||||||
|
final int[] childIndices, final Object[] children) { |
||||||
|
fireTreeNode(INSERTED, source, path, childIndices, children); |
||||||
|
} |
||||||
|
|
||||||
|
protected void fireTreeNodesRemoved(final Object source, final Object[] path, |
||||||
|
final int[] childIndices, final Object[] children) { |
||||||
|
fireTreeNode(REMOVED, source, path, childIndices, children); |
||||||
|
} |
||||||
|
|
||||||
|
protected void fireTreeStructureChanged(final Object source, final Object[] path, |
||||||
|
final int[] childIndices, final Object[] children) { |
||||||
|
fireTreeNode(STRUCTURE_CHANGED, source, path, childIndices, children); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.util.DarkUIUtil; |
||||||
|
|
||||||
|
public class DefaultTreeTableModel extends AbstractTreeTableModel { |
||||||
|
|
||||||
|
private final String[] headers; |
||||||
|
private Class<?>[] columnClasses; |
||||||
|
|
||||||
|
public DefaultTreeTableModel(final TreeTableNode root, final String[] headers) { |
||||||
|
super(root); |
||||||
|
this.headers = headers; |
||||||
|
} |
||||||
|
|
||||||
|
public void setColumnClasses(final Class<?>[] columnClasses) { |
||||||
|
this.columnClasses = columnClasses; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getColumnCount() { |
||||||
|
return headers.length; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(final int column) { |
||||||
|
return headers[column]; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<?> getColumnClass(final int column) { |
||||||
|
if (column == 0) { |
||||||
|
return TreeTableModel.class; |
||||||
|
} else if (columnClasses != null && column < columnClasses.length) { |
||||||
|
return columnClasses[column]; |
||||||
|
} else { |
||||||
|
return Object.class; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getValueAt(final Object node, final int column) { |
||||||
|
TreeTableNode treeTableNode = DarkUIUtil.nullableCast(TreeTableNode.class, node); |
||||||
|
if (treeTableNode == null) return null; |
||||||
|
return treeTableNode.getValueAt(column); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isCellEditable(final Object node, final int column) { |
||||||
|
return column != 0; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setValueAt(final Object aValue, final Object node, final int column) { |
||||||
|
TreeTableNode treeTableNode = DarkUIUtil.nullableCast(TreeTableNode.class, node); |
||||||
|
if (treeTableNode != null) { |
||||||
|
treeTableNode.setValueAt(column, aValue); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getChild(final Object parent, final int index) { |
||||||
|
TreeTableNode treeTableNode = DarkUIUtil.nullableCast(TreeTableNode.class, parent); |
||||||
|
return treeTableNode != null ? treeTableNode.getChildAt(index) : null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getChildCount(final Object parent) { |
||||||
|
TreeTableNode treeTableNode = DarkUIUtil.nullableCast(TreeTableNode.class, parent); |
||||||
|
return treeTableNode != null ? treeTableNode.getChildCount() : 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class DefaultTreeTableNode implements TreeTableNode { |
||||||
|
|
||||||
|
private final List<TreeTableNode> children; |
||||||
|
private final TreeTableNode parent; |
||||||
|
private final List<Object> columns; |
||||||
|
|
||||||
|
public DefaultTreeTableNode(final TreeTableNode parent, |
||||||
|
final Object[] columns) { |
||||||
|
this(parent, Arrays.asList(columns)); |
||||||
|
} |
||||||
|
|
||||||
|
public DefaultTreeTableNode(final TreeTableNode parent, final List<Object> columns) { |
||||||
|
this.parent = parent; |
||||||
|
this.columns = columns; |
||||||
|
this.children = new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<TreeTableNode> getChildren() { |
||||||
|
return children; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public TreeTableNode getParent() { |
||||||
|
return parent; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean getAllowsChildren() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public void addChild(final TreeTableNode child) { |
||||||
|
children.add(child); |
||||||
|
} |
||||||
|
|
||||||
|
public void removeChild(final TreeTableNode child) { |
||||||
|
children.remove(child); |
||||||
|
} |
||||||
|
|
||||||
|
public String toString() { |
||||||
|
return getTreeValue().toString(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Object> getColumns() { |
||||||
|
return columns; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,99 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.tree.DefaultTreeSelectionModel; |
||||||
|
import javax.swing.tree.TreePath; |
||||||
|
|
||||||
|
public class DefaultTreeTableSelectionModel extends DefaultTreeSelectionModel |
||||||
|
implements DelegatingListSelectionModel { |
||||||
|
|
||||||
|
private final JTree tree; |
||||||
|
private final ListSelectionModel bridgeModel; |
||||||
|
|
||||||
|
public DefaultTreeTableSelectionModel(final JTree tree) { |
||||||
|
this.tree = tree; |
||||||
|
bridgeModel = new TreeTableListSelectionModel(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ListSelectionModel getListDelegate() { |
||||||
|
return bridgeModel; |
||||||
|
} |
||||||
|
|
||||||
|
protected class TreeTableListSelectionModel implements DelegatingListSelectionModel { |
||||||
|
|
||||||
|
@Override |
||||||
|
public ListSelectionModel getListDelegate() { |
||||||
|
return listSelectionModel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setSelectionInterval(final int index0, final int index1) { |
||||||
|
setSelectionPaths(getTreePaths(index0, index1)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addSelectionInterval(final int index0, final int index1) { |
||||||
|
addSelectionPaths(getTreePaths(index0, index1)); |
||||||
|
} |
||||||
|
|
||||||
|
protected TreePath[] getTreePaths(final int index0, final int index1) { |
||||||
|
int start = Math.min(index0, index1); |
||||||
|
int end = Math.max(index0, index1); |
||||||
|
TreePath[] paths = new TreePath[end - start + 1]; |
||||||
|
for (int i = start; i <= end; i++) { |
||||||
|
paths[i - start] = tree.getPathForRow(i); |
||||||
|
} |
||||||
|
return paths; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeSelectionInterval(final int index0, final int index1) { |
||||||
|
removeSelectionPaths(getTreePaths(index0, index1)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setLeadSelectionIndex(final int index) { |
||||||
|
tree.setLeadSelectionPath(tree.getPathForRow(index)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getLeadSelectionIndex() { |
||||||
|
return getLeadSelectionRow(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setAnchorSelectionIndex(final int index) { |
||||||
|
tree.setAnchorSelectionPath(tree.getPathForRow(index)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getAnchorSelectionIndex() { |
||||||
|
return tree.getRowForPath(tree.getAnchorSelectionPath()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,166 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.ListSelectionListener; |
||||||
|
|
||||||
|
public interface DelegatingListSelectionModel extends ListSelectionModel { |
||||||
|
ListSelectionModel getListDelegate(); |
||||||
|
|
||||||
|
@Override |
||||||
|
default void setSelectionInterval(final int index0, final int index1) { |
||||||
|
getListDelegate().setSelectionInterval(index0, index1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void addSelectionInterval(final int index0, final int index1) { |
||||||
|
getListDelegate().addSelectionInterval(index0, index1); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void removeSelectionInterval(final int index0, final int index1) { |
||||||
|
getListDelegate().removeSelectionInterval(index0, index1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getMinSelectionIndex() { |
||||||
|
return getListDelegate().getMinSelectionIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getMaxSelectionIndex() { |
||||||
|
return getListDelegate().getMaxSelectionIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default boolean isSelectedIndex(final int index) { |
||||||
|
return getListDelegate().isSelectedIndex(index); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getAnchorSelectionIndex() { |
||||||
|
return getListDelegate().getAnchorSelectionIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void setAnchorSelectionIndex(final int index) { |
||||||
|
getListDelegate().setAnchorSelectionIndex(index); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getLeadSelectionIndex() { |
||||||
|
return getListDelegate().getLeadSelectionIndex(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void setLeadSelectionIndex(final int index) { |
||||||
|
getListDelegate().setLeadSelectionIndex(index); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void clearSelection() { |
||||||
|
getListDelegate().clearSelection(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default boolean isSelectionEmpty() { |
||||||
|
return getListDelegate().isSelectionEmpty(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void insertIndexInterval(final int index, final int length, final boolean before) { |
||||||
|
getListDelegate().insertIndexInterval(index, length, before); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void removeIndexInterval(final int index0, final int index1) { |
||||||
|
getListDelegate().removeIndexInterval(index0, index1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void setValueIsAdjusting(final boolean valueIsAdjusting) { |
||||||
|
getListDelegate().setValueIsAdjusting(valueIsAdjusting); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default boolean getValueIsAdjusting() { |
||||||
|
return getListDelegate().getValueIsAdjusting(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void setSelectionMode(final int selectionMode) { |
||||||
|
getListDelegate().setSelectionMode(selectionMode); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getSelectionMode() { |
||||||
|
return getListDelegate().getSelectionMode(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void addListSelectionListener(final ListSelectionListener x) { |
||||||
|
getListDelegate().addListSelectionListener(x); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default void removeListSelectionListener(final ListSelectionListener x) { |
||||||
|
getListDelegate().removeListSelectionListener(x); |
||||||
|
} |
||||||
|
|
||||||
|
default int[] getSelectedIndices() { |
||||||
|
int iMin = getMinSelectionIndex(); |
||||||
|
int iMax = getMaxSelectionIndex(); |
||||||
|
|
||||||
|
if ((iMin < 0) || (iMax < 0)) { |
||||||
|
return new int[0]; |
||||||
|
} |
||||||
|
|
||||||
|
int[] rvTmp = new int[1 + (iMax - iMin)]; |
||||||
|
int n = 0; |
||||||
|
for (int i = iMin; i <= iMax; i++) { |
||||||
|
if (isSelectedIndex(i)) { |
||||||
|
rvTmp[n++] = i; |
||||||
|
} |
||||||
|
} |
||||||
|
int[] rv = new int[n]; |
||||||
|
System.arraycopy(rvTmp, 0, rv, 0, n); |
||||||
|
return rv; |
||||||
|
} |
||||||
|
|
||||||
|
default int getSelectedItemsCount() { |
||||||
|
int iMin = getMinSelectionIndex(); |
||||||
|
int iMax = getMaxSelectionIndex(); |
||||||
|
int count = 0; |
||||||
|
|
||||||
|
for (int i = iMin; i <= iMax; i++) { |
||||||
|
if (isSelectedIndex(i)) { |
||||||
|
count++; |
||||||
|
} |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import javax.swing.tree.TreeModel; |
||||||
|
|
||||||
|
public interface TreeTableModel extends TreeModel { |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the number of available columns. |
||||||
|
* |
||||||
|
* @return Number of Columns |
||||||
|
*/ |
||||||
|
int getColumnCount(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the column name. |
||||||
|
* |
||||||
|
* @param column Column number |
||||||
|
* @return Column name |
||||||
|
*/ |
||||||
|
String getColumnName(int column); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the type (class) of a column. |
||||||
|
* |
||||||
|
* @param column Column number |
||||||
|
* @return Class |
||||||
|
*/ |
||||||
|
Class<?> getColumnClass(int column); |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns the value of a node in a column. |
||||||
|
* |
||||||
|
* @param node Node |
||||||
|
* @param column Column number |
||||||
|
* @return Value of the node in the column |
||||||
|
*/ |
||||||
|
Object getValueAt(Object node, int column); |
||||||
|
|
||||||
|
/** |
||||||
|
* Check if a cell of a node in one column is editable. |
||||||
|
* |
||||||
|
* @param node Node |
||||||
|
* @param column Column number |
||||||
|
* @return true/false |
||||||
|
*/ |
||||||
|
boolean isCellEditable(Object node, int column); |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets a value for a node in one column. |
||||||
|
* |
||||||
|
* @param aValue New value |
||||||
|
* @param node Node |
||||||
|
* @param column Column number |
||||||
|
*/ |
||||||
|
void setValueAt(Object aValue, Object node, int column); |
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package com.github.weisj.darklaf.components.treetable.model; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Enumeration; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import javax.swing.tree.TreeNode; |
||||||
|
|
||||||
|
public interface TreeTableNode extends TreeNode { |
||||||
|
|
||||||
|
List<TreeTableNode> getChildren(); |
||||||
|
|
||||||
|
@Override |
||||||
|
default Enumeration<? extends TreeTableNode> children() { |
||||||
|
return Collections.enumeration(getChildren()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
TreeTableNode getParent(); |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getIndex(final TreeNode node) { |
||||||
|
if (!(node instanceof TreeTableNode)) return -1; |
||||||
|
return getIndex((TreeTableNode) node); |
||||||
|
} |
||||||
|
|
||||||
|
default int getIndex(final TreeTableNode node) { |
||||||
|
return getChildren().indexOf(node); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default int getChildCount() { |
||||||
|
return getChildren().size(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default TreeTableNode getChildAt(final int index) { |
||||||
|
if (index < 0 || index >= getChildCount()) return null; |
||||||
|
return getChildren().get(index); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
default boolean isLeaf() { |
||||||
|
return getChildCount() == 0; |
||||||
|
} |
||||||
|
|
||||||
|
List<Object> getColumns(); |
||||||
|
|
||||||
|
default Object getValueAt(final int column) { |
||||||
|
return getColumns().get(column); |
||||||
|
} |
||||||
|
|
||||||
|
default Object getTreeValue() { |
||||||
|
return getColumns().get(0); |
||||||
|
} |
||||||
|
|
||||||
|
default int getColumnCount() { |
||||||
|
return getColumns().size(); |
||||||
|
} |
||||||
|
|
||||||
|
default void setValueAt(final int column, final Object aValue) { |
||||||
|
getColumns().set(column, aValue); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,96 @@ |
|||||||
|
/* |
||||||
|
* MIT License |
||||||
|
* |
||||||
|
* Copyright (c) 2020 Jannis Weis |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package ui.treetable; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
import com.github.weisj.darklaf.components.treetable.JTreeTable; |
||||||
|
import com.github.weisj.darklaf.components.treetable.model.*; |
||||||
|
|
||||||
|
import ui.ComponentDemo; |
||||||
|
import ui.DemoPanel; |
||||||
|
|
||||||
|
public class TreeTableDemo implements ComponentDemo { |
||||||
|
|
||||||
|
public static void main(final String[] args) { |
||||||
|
ComponentDemo.showDemo(new TreeTableDemo()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JComponent createComponent() { |
||||||
|
AbstractTreeTableModel treeTableModel = new DemoModel(createDataStructure()); |
||||||
|
JTreeTable treeTable = new JTreeTable(treeTableModel); |
||||||
|
return new DemoPanel(new JScrollPane(treeTable), new BorderLayout(), 0); |
||||||
|
} |
||||||
|
|
||||||
|
private DemoNode createDataStructure() { |
||||||
|
Random r = new Random(); |
||||||
|
DemoNode root = new DemoNode(null, "R1", "R1", new Date(r.nextLong()), 10); |
||||||
|
for (int i = 0; i < 16; i++) { |
||||||
|
DefaultTreeTableNode node = new DemoNode(root, "N" + i, "C1", new Date(r.nextLong()), 10); |
||||||
|
if (i % 2 == 0) { |
||||||
|
node.addChild(new DemoNode(node, "N12N12N12", "C12", new Date(r.nextLong()), 50)); |
||||||
|
node.addChild(new DemoNode(node, "N13N12N12", "C13", new Date(r.nextLong()), 60)); |
||||||
|
node.addChild(new DemoNode(node, "N14N12N12", "C14", new Date(r.nextLong()), 70)); |
||||||
|
node.addChild(new DemoNode(node, "N15N12N12", "C15", new Date(r.nextLong()), 80)); |
||||||
|
} else { |
||||||
|
node.addChild(new DemoNode(node, "N12N12N12", "C12", new Date(r.nextLong()), 10)); |
||||||
|
node.addChild(new DemoNode(node, "N13N12N12", "C13", new Date(r.nextLong()), 20)); |
||||||
|
node.addChild(new DemoNode(node, "N14N12N12", "C14", new Date(r.nextLong()), 30)); |
||||||
|
node.addChild(new DemoNode(node, "N15N12N12", "C15", new Date(r.nextLong()), 40)); |
||||||
|
} |
||||||
|
root.addChild(node); |
||||||
|
} |
||||||
|
return root; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getTitle() { |
||||||
|
return "TreeTable Demo"; |
||||||
|
} |
||||||
|
|
||||||
|
protected static class DemoNode extends DefaultTreeTableNode { |
||||||
|
|
||||||
|
public DemoNode(final TreeTableNode parent, final String name, final String capital, |
||||||
|
final Date declared, final Integer area) { |
||||||
|
super(parent, new Object[]{name, capital, declared, area}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static class DemoModel extends DefaultTreeTableModel { |
||||||
|
static protected String[] columnNames = {"TreeNode", "String", "Date", "Integer"}; |
||||||
|
static protected Class<?>[] columnTypes = {TreeTableModel.class, String.class, Date.class, Integer.class}; |
||||||
|
|
||||||
|
public DemoModel(final TreeTableNode rootNode) { |
||||||
|
super(rootNode, columnNames); |
||||||
|
setColumnClasses(columnTypes); |
||||||
|
root = rootNode; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue