diff --git a/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java index d9603a0b..40c01337 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/ThemeDefaultsInitTask.java @@ -40,7 +40,7 @@ public class ThemeDefaultsInitTask implements DefaultsInitTask { private static final String GLOBAL_PREFIX = "global."; private static final String MAC_OS_MENU_BAR_KEY = "apple.laf.useScreenMenuBar"; - private static final String[] UI_PROPERTIES = new String[]{"borders", "button", "checkBox", "colorChooser", + private static final String[] UI_PROPERTIES = new String[]{"borders", "button", "cell", "checkBox", "colorChooser", "comboBox", "fileChooser", "tristate", "internalFrame", "label", "list", "menu", "menuBar", "menuItem", "numberingPane", "optionPane", "panel", diff --git a/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java b/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java index 43bf767a..53ff6690 100644 --- a/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java +++ b/core/src/main/java/com/github/weisj/darklaf/task/UtilityDefaultsInitTask.java @@ -30,6 +30,7 @@ import com.github.weisj.darklaf.graphics.PaintUtil; import com.github.weisj.darklaf.icons.AwareIconStyle; import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.theme.Theme; +import com.github.weisj.darklaf.ui.cell.CellUtil; public class UtilityDefaultsInitTask implements DefaultsInitTask { @Override @@ -54,6 +55,8 @@ public class UtilityDefaultsInitTask implements DefaultsInitTask { IconLoader.updateAwareStyle(Theme.isDark(currentTheme) ? AwareIconStyle.DARK : AwareIconStyle.LIGHT); IconLoader.updateThemeStatus(currentTheme); + + CellUtil.updateColors(defaults); } private float getOpacity(final UIDefaults defaults, final String key) { diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/cell/CellUtil.java b/core/src/main/java/com/github/weisj/darklaf/ui/cell/CellUtil.java index 174a9f62..050a7432 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/cell/CellUtil.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/cell/CellUtil.java @@ -30,7 +30,9 @@ import javax.swing.*; import javax.swing.plaf.ListUI; import com.github.weisj.darklaf.ui.list.DarkListUI; -import com.github.weisj.darklaf.ui.table.DarkTableCellEditor; +import com.github.weisj.darklaf.ui.table.DarkTableUI; +import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditor; +import com.github.weisj.darklaf.ui.tree.DarkTreeUI; import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.util.PropertyUtil; @@ -38,55 +40,309 @@ public class CellUtil { public static final String KEY_SELECTED_CELL_RENDERER = "JComponent.selectedCellRenderer"; - public static void setupForeground(final Component comp, final JComponent parent, final boolean selected, - final String activeKey, final String inactiveKey) { - setupForeground(comp, parent, selected, UIManager.getColor(activeKey), inactiveKey); + // Default Colors + private static Color cellForeground; + private static Color cellForegroundSelected; + private static Color cellForegroundNoFocus; + private static Color cellForegroundSelectedNoFocus; + + private static Color cellInactiveForeground; + private static Color cellInactiveForegroundSelected; + private static Color cellInactiveForegroundNoFocus; + private static Color cellInactiveForegroundSelectedNoFocus; + + private static Color cellBackground; + private static Color cellBackgroundAlternative; + private static Color cellBackgroundSelected; + private static Color cellBackgroundNoFocus; + private static Color cellBackgroundNoFocusAlternative; + private static Color cellBackgroundSelectedNoFocus; + + private static Color cellInactiveBackground; + private static Color cellInactiveBackgroundAlternative; + private static Color cellInactiveBackgroundSelected; + private static Color cellInactiveBackgroundNoFocus; + private static Color cellInactiveBackgroundNoFocusAlternative; + private static Color cellInactiveBackgroundSelectedNoFocus; + + // Table Colors + private static Color tableCellForeground; + private static Color tableCellForegroundSelected; + private static Color tableCellForegroundNoFocus; + private static Color tableCellForegroundSelectedNoFocus; + + private static Color tableCellInactiveForeground; + private static Color tableCellInactiveForegroundSelected; + private static Color tableCellInactiveForegroundNoFocus; + private static Color tableCellInactiveForegroundSelectedNoFocus; + + private static Color tableCellBackground; + private static Color tableCellBackgroundAlternative; + private static Color tableCellBackgroundSelected; + private static Color tableCellBackgroundNoFocus; + private static Color tableCellBackgroundNoFocusAlternative; + private static Color tableCellBackgroundSelectedNoFocus; + + private static Color tableCellInactiveBackground; + private static Color tableCellInactiveBackgroundAlternative; + private static Color tableCellInactiveBackgroundSelected; + private static Color tableCellInactiveBackgroundNoFocus; + private static Color tableCellInactiveBackgroundNoFocusAlternative; + private static Color tableCellInactiveBackgroundSelectedNoFocus; + + // Tree Colors + private static Color treeCellForeground; + private static Color treeCellForegroundSelected; + private static Color treeCellForegroundNoFocus; + private static Color treeCellForegroundSelectedNoFocus; + + private static Color treeCellInactiveForeground; + private static Color treeCellInactiveForegroundSelected; + private static Color treeCellInactiveForegroundNoFocus; + private static Color treeCellInactiveForegroundSelectedNoFocus; + + private static Color treeCellBackground; + private static Color treeCellBackgroundAlternative; + private static Color treeCellBackgroundSelected; + private static Color treeCellBackgroundNoFocus; + private static Color treeCellBackgroundNoFocusAlternative; + private static Color treeCellBackgroundSelectedNoFocus; + + private static Color treeCellInactiveBackground; + private static Color treeCellInactiveBackgroundAlternative; + private static Color treeCellInactiveBackgroundSelected; + private static Color treeCellInactiveBackgroundNoFocus; + private static Color treeCellInactiveBackgroundNoFocusAlternative; + private static Color treeCellInactiveBackgroundSelectedNoFocus; + + // List Colors + private static Color listCellForeground; + private static Color listCellForegroundSelected; + private static Color listCellForegroundNoFocus; + private static Color listCellForegroundSelectedNoFocus; + + private static Color listCellInactiveForeground; + private static Color listCellInactiveForegroundSelected; + private static Color listCellInactiveForegroundNoFocus; + private static Color listCellInactiveForegroundSelectedNoFocus; + + private static Color listCellBackground; + private static Color listCellBackgroundAlternative; + private static Color listCellBackgroundSelected; + private static Color listCellBackgroundNoFocus; + private static Color listCellBackgroundNoFocusAlternative; + private static Color listCellBackgroundSelectedNoFocus; + + private static Color listCellInactiveBackground; + private static Color listCellInactiveBackgroundAlternative; + private static Color listCellInactiveBackgroundSelected; + private static Color listCellInactiveBackgroundNoFocus; + private static Color listCellInactiveBackgroundNoFocusAlternative; + private static Color listCellInactiveBackgroundSelectedNoFocus; + + public static void updateColors(final UIDefaults defaults) { + UIDefaults d = defaults != null ? defaults : UIManager.getDefaults(); + // Default colors + cellForeground = d.getColor("Cell.foreground"); + cellForegroundSelected = d.getColor("Cell.foregroundSelected"); + cellForegroundNoFocus = d.getColor("Cell.foregroundNoFocus"); + cellForegroundSelectedNoFocus = d.getColor("Cell.foregroundSelectedNoFocus"); + + cellInactiveForeground = d.getColor("Cell.inactiveForeground"); + cellInactiveForegroundSelected = d.getColor("Cell.inactiveForegroundSelected"); + cellInactiveForegroundNoFocus = d.getColor("Cell.inactiveForegroundNoFocus"); + cellInactiveForegroundSelectedNoFocus = d.getColor("Cell.inactiveSelectedNoFocus"); + + cellBackground = d.getColor("Cell.background"); + cellBackgroundAlternative = d.getColor("Cell.backgroundAlternative"); + cellBackgroundSelected = d.getColor("Cell.backgroundSelected"); + cellBackgroundNoFocus = d.getColor("Cell.backgroundNoFocus"); + cellBackgroundNoFocusAlternative = d.getColor("Cell.backgroundNoFocusAlternative"); + cellBackgroundSelectedNoFocus = d.getColor("Cell.backgroundSelectedNoFocus"); + + cellInactiveBackground = d.getColor("Cell.inactiveBackground"); + cellInactiveBackgroundAlternative = d.getColor("Cell.inactiveBackgroundAlternative"); + cellInactiveBackgroundSelected = d.getColor("Cell.inactiveBackgroundSelected"); + cellInactiveBackgroundNoFocus = d.getColor("Cell.inactiveBackgroundNoFocus"); + cellInactiveBackgroundNoFocusAlternative = d.getColor("Cell.inactiveBackgroundNoFocusAlternative"); + cellInactiveBackgroundSelectedNoFocus = d.getColor("Cell.inactiveBackgroundSelectedNoFocus"); + + // Table colors + tableCellForeground = d.getColor("Table.foreground"); + tableCellForegroundSelected = d.getColor("Table.foregroundSelected"); + tableCellForegroundNoFocus = d.getColor("Table.foregroundNoFocus"); + tableCellForegroundSelectedNoFocus = d.getColor("Table.foregroundSelectedNoFocus"); + + tableCellInactiveForeground = d.getColor("Table.inactiveForeground"); + tableCellInactiveForegroundSelected = d.getColor("Table.inactiveForegroundSelected"); + tableCellInactiveForegroundNoFocus = d.getColor("Table.inactiveForegroundNoFocus"); + tableCellInactiveForegroundSelectedNoFocus = d.getColor("Table.inactiveSelectedNoFocus"); + + tableCellBackground = d.getColor("Table.background"); + tableCellBackgroundAlternative = d.getColor("Table.backgroundAlternative"); + tableCellBackgroundSelected = d.getColor("Table.backgroundSelected"); + tableCellBackgroundNoFocus = d.getColor("Table.backgroundNoFocus"); + tableCellBackgroundNoFocusAlternative = d.getColor("Table.backgroundNoFocusAlternative"); + tableCellBackgroundSelectedNoFocus = d.getColor("Table.backgroundSelectedNoFocus"); + + tableCellInactiveBackground = d.getColor("Table.inactiveBackground"); + tableCellInactiveBackgroundAlternative = d.getColor("Table.inactiveBackgroundAlternative"); + tableCellInactiveBackgroundSelected = d.getColor("Table.inactiveBackgroundSelected"); + tableCellInactiveBackgroundNoFocus = d.getColor("Table.inactiveBackgroundNoFocus"); + tableCellInactiveBackgroundNoFocusAlternative = d.getColor("Table.inactiveBackgroundNoFocusAlternative"); + tableCellInactiveBackgroundSelectedNoFocus = d.getColor("Table.inactiveBackgroundSelectedNoFocus"); + + // Tree colors + treeCellForeground = d.getColor("Tree.foreground"); + treeCellForegroundSelected = d.getColor("Tree.foregroundSelected"); + treeCellForegroundNoFocus = d.getColor("Tree.foregroundNoFocus"); + treeCellForegroundSelectedNoFocus = d.getColor("Tree.foregroundSelectedNoFocus"); + + treeCellInactiveForeground = d.getColor("Tree.inactiveForeground"); + treeCellInactiveForegroundSelected = d.getColor("Tree.inactiveForegroundSelected"); + treeCellInactiveForegroundNoFocus = d.getColor("Tree.inactiveForegroundNoFocus"); + treeCellInactiveForegroundSelectedNoFocus = d.getColor("Tree.inactiveSelectedNoFocus"); + + treeCellBackground = d.getColor("Tree.background"); + treeCellBackgroundAlternative = d.getColor("Tree.backgroundAlternative"); + treeCellBackgroundSelected = d.getColor("Tree.backgroundSelected"); + treeCellBackgroundNoFocus = d.getColor("Tree.backgroundNoFocus"); + treeCellBackgroundNoFocusAlternative = d.getColor("Tree.backgroundNoFocusAlternative"); + treeCellBackgroundSelectedNoFocus = d.getColor("Tree.backgroundSelectedNoFocus"); + + treeCellInactiveBackground = d.getColor("Tree.inactiveBackground"); + treeCellInactiveBackgroundAlternative = d.getColor("Tree.inactiveBackgroundAlternative"); + treeCellInactiveBackgroundSelected = d.getColor("Tree.inactiveBackgroundSelected"); + treeCellInactiveBackgroundNoFocus = d.getColor("Tree.inactiveBackgroundNoFocus"); + treeCellInactiveBackgroundNoFocusAlternative = d.getColor("Tree.inactiveBackgroundNoFocusAlternative"); + treeCellInactiveBackgroundSelectedNoFocus = d.getColor("Tree.inactiveBackgroundSelectedNoFocus"); + + // List colors + listCellForeground = d.getColor("List.foreground"); + listCellForegroundSelected = d.getColor("List.foregroundSelected"); + listCellForegroundNoFocus = d.getColor("List.foregroundNoFocus"); + listCellForegroundSelectedNoFocus = d.getColor("List.foregroundSelectedNoFocus"); + + listCellInactiveForeground = d.getColor("List.inactiveForeground"); + listCellInactiveForegroundSelected = d.getColor("List.inactiveForegroundSelected"); + listCellInactiveForegroundNoFocus = d.getColor("List.inactiveForegroundNoFocus"); + listCellInactiveForegroundSelectedNoFocus = d.getColor("List.inactiveSelectedNoFocus"); + + listCellBackground = d.getColor("List.background"); + listCellBackgroundAlternative = d.getColor("List.backgroundAlternative"); + listCellBackgroundSelected = d.getColor("List.backgroundSelected"); + listCellBackgroundNoFocus = d.getColor("List.backgroundNoFocus"); + listCellBackgroundNoFocusAlternative = d.getColor("List.backgroundNoFocusAlternative"); + listCellBackgroundSelectedNoFocus = d.getColor("List.backgroundSelectedNoFocus"); + + listCellInactiveBackground = d.getColor("List.inactiveBackground"); + listCellInactiveBackgroundAlternative = d.getColor("List.inactiveBackgroundAlternative"); + listCellInactiveBackgroundSelected = d.getColor("List.inactiveBackgroundSelected"); + listCellInactiveBackgroundNoFocus = d.getColor("List.inactiveBackgroundNoFocus"); + listCellInactiveBackgroundNoFocusAlternative = d.getColor("List.inactiveBackgroundNoFocusAlternative"); + listCellInactiveBackgroundSelectedNoFocus = d.getColor("List.inactiveBackgroundSelectedNoFocus"); + } + + public static void setupTableForeground(final Component comp, final JTable parent, final boolean selected) { + setupForeground(comp, parent, selected, + tableCellForeground, tableCellForegroundSelected, + tableCellForegroundNoFocus, tableCellForegroundSelectedNoFocus, + tableCellInactiveForeground, tableCellInactiveForegroundSelected, + tableCellInactiveForegroundNoFocus, tableCellInactiveForegroundSelectedNoFocus); + } + + public static void setupTreeForeground(final Component comp, final JTree parent, final boolean selected) { + setupForeground(comp, parent, selected, + treeCellForeground, treeCellForegroundSelected, + treeCellForegroundNoFocus, treeCellForegroundSelectedNoFocus, + treeCellInactiveForeground, treeCellInactiveForegroundSelected, + treeCellInactiveForegroundNoFocus, treeCellInactiveForegroundSelectedNoFocus); } - public static void setupForeground(final Component comp, final JTable parent, final boolean selected, - final String inactiveKey) { - setupForeground(comp, parent, selected, parent.getSelectionForeground(), inactiveKey); + public static void setupListForeground(final Component comp, final JList parent, final boolean selected) { + setupForeground(comp, parent, selected, + listCellForeground, listCellForegroundSelected, + listCellForegroundNoFocus, listCellForegroundSelectedNoFocus, + listCellInactiveForeground, listCellInactiveForegroundSelected, + listCellInactiveForegroundNoFocus, listCellInactiveForegroundSelectedNoFocus); + } + + public static void setupStandardForeground(final Component comp, final JComponent parent, final boolean selected) { + setupForeground(comp, parent, selected, + cellForeground, cellForegroundSelected, + cellForegroundNoFocus, cellForegroundSelectedNoFocus, + cellInactiveForeground, cellInactiveForegroundSelected, + cellInactiveForegroundNoFocus, cellInactiveForegroundSelectedNoFocus); } public static void setupForeground(final Component comp, final JComponent parent, final boolean selected, - final Color activeColor, final String inactiveKey) { - if (selected) { - if (DarkUIUtil.hasFocus(parent)) { - comp.setForeground(activeColor); - } else { - comp.setForeground(UIManager.getColor(inactiveKey)); - } - } else { - comp.setForeground(parent.getForeground()); - } - setSelectedFlag(comp, selected); + final Color fg, final Color selFg, + final Color fgNoFocus, final Color selFgNoFocus, + final Color inactiveFg, final Color inactiveSelFg, + final Color inactiveFgNoFocus, final Color inactiveSelFgNoFocus) { + boolean enabled = comp.isEnabled() && parent.isEnabled(); + boolean focus = hasFocus(parent, comp); + setupForeground(comp, parent, focus, selected, enabled, fg, selFg, fgNoFocus, selFgNoFocus, inactiveFg, + inactiveSelFg, inactiveFgNoFocus, inactiveSelFgNoFocus); } - public static void setSelectedFlag(final Component comp, final boolean selected) { - if (comp instanceof JComponent) { - ((JComponent) comp).putClientProperty(KEY_SELECTED_CELL_RENDERER, selected); + public static void setupForeground(final Component comp, final JComponent parent, + final boolean focus, final boolean selected, final boolean enabled, + final Color fg, final Color selFg, + final Color fgNoFocus, final Color selFgNoFocus, + final Color inactiveFg, final Color inactiveSelFg, + final Color inactiveFgNoFocus, final Color inactiveSelFgNoFocus) { + Color c = getColor(enabled, selected, focus, + fg, selFg, fgNoFocus, selFgNoFocus, inactiveFg, inactiveSelFg, + inactiveFgNoFocus, inactiveSelFgNoFocus); + if (c != null) { + comp.setForeground(c); } } - public static void setupBackground(final Component comp, final JTable parent, - final boolean selected, final int row, - final String altBgKey, final String altColorKey, - final String noFocusSelectionBgKey) { - setupBackground(comp, parent, selected, row, altBgKey, parent.getBackground(), altColorKey, - parent.getSelectionBackground(), noFocusSelectionBgKey); + public static void setupTableBackground(final Component comp, final JTable parent, final boolean selected, + final int row) { + boolean alt = row % 2 == 1 && PropertyUtil.getBooleanProperty(parent, DarkTableUI.KEY_ALTERNATE_ROW_COLOR); + setupBackground(comp, hasFocus(parent, comp), selected, + alt ? tableCellBackgroundAlternative : tableCellBackground, + tableCellBackgroundSelected, + alt ? tableCellBackgroundNoFocusAlternative : tableCellBackgroundNoFocus, + tableCellBackgroundSelectedNoFocus, + alt ? tableCellInactiveBackgroundAlternative : tableCellInactiveBackground, + tableCellInactiveBackgroundSelected, + alt ? tableCellInactiveBackgroundNoFocusAlternative : tableCellInactiveBackgroundNoFocus, + tableCellInactiveBackgroundSelectedNoFocus); } - public static void setupBackground(final Component comp, final JTable parent, - final boolean selected, final int row, - final String altBgKey, final String colorKey, final String altColorKey, - final String noFocusSelectionBgKey) { - setupBackground(comp, parent, selected, row, altBgKey, UIManager.getColor(colorKey), - altColorKey, parent.getSelectionBackground(), noFocusSelectionBgKey); + public static void setupTreeBackground(final Component comp, final JTree parent, final boolean selected, + final int row) { + boolean alt = row % 2 == 1 && PropertyUtil.getBooleanProperty(parent, DarkTreeUI.KEY_ALTERNATE_ROW_COLOR); + setupBackground(comp, hasFocus(parent, comp), selected, + alt ? treeCellBackgroundAlternative : treeCellBackground, + treeCellBackgroundSelected, + alt ? treeCellBackgroundNoFocusAlternative : treeCellBackgroundNoFocus, + treeCellBackgroundSelectedNoFocus, + alt ? treeCellInactiveBackgroundAlternative : treeCellInactiveBackground, + treeCellInactiveBackgroundSelected, + alt ? treeCellInactiveBackgroundNoFocusAlternative : treeCellInactiveBackgroundNoFocus, + treeCellInactiveBackgroundSelectedNoFocus); } - public static void setupBackground(final Component comp, final JList parent, final boolean selected, - final int index, final String altBgKey, final String altColorKey, - final String noFocusSelectionBgKey) { + public static Color getTreeBackground(final JTree tree, final boolean selected, final int row) { + boolean alt = row % 2 == 1 && PropertyUtil.getBooleanProperty(tree, DarkTreeUI.KEY_ALTERNATE_ROW_COLOR); + return getColor(tree.isEnabled(), selected, hasFocus(tree, tree), + alt ? treeCellBackgroundAlternative : treeCellBackground, + treeCellBackgroundSelected, + alt ? treeCellBackgroundNoFocusAlternative : treeCellBackgroundNoFocus, + treeCellBackgroundSelectedNoFocus, + alt ? treeCellInactiveBackgroundAlternative : treeCellInactiveBackground, + treeCellInactiveBackgroundSelected, + alt ? treeCellInactiveBackgroundNoFocusAlternative : treeCellInactiveBackgroundNoFocus, + treeCellInactiveBackgroundSelectedNoFocus); + } + + public static void setupListBackground(final Component comp, final JList parent, final boolean selected, + final int index) { int layout = parent.getLayoutOrientation(); boolean altRow = false; if (layout == JList.VERTICAL) { @@ -100,25 +356,85 @@ public class CellUtil { altRow = false; } } - setupBackground(comp, parent, selected, altRow ? 1 : 0, altBgKey, parent.getBackground(), - altColorKey, parent.getSelectionBackground(), noFocusSelectionBgKey); - } - - protected static void setupBackground(final Component comp, final JComponent parent, - final boolean selected, final int row, - final String altBgKey, final Color bgColor, final String altColorKey, - final Color selectionBackground, final String noFocusSelectionBgKey) { - boolean alternativeRow = PropertyUtil.getBooleanProperty(parent, altBgKey); - Color alternativeRowColor = UIManager.getColor(altColorKey); - Color background = alternativeRow && row % 2 == 1 ? alternativeRowColor : bgColor; - if (selected) { - if (DarkUIUtil.hasFocus(parent)) { - comp.setBackground(selectionBackground); + boolean alt = altRow && PropertyUtil.getBooleanProperty(parent, DarkListUI.KEY_ALTERNATE_ROW_COLOR); + setupBackground(comp, hasFocus(parent, comp), selected, + alt ? listCellBackgroundAlternative : listCellBackground, + listCellBackgroundSelected, + alt ? listCellBackgroundNoFocusAlternative : listCellBackgroundNoFocus, + listCellBackgroundSelectedNoFocus, + alt ? listCellInactiveBackgroundAlternative : listCellInactiveBackground, + listCellInactiveBackgroundSelected, + alt ? listCellInactiveBackgroundNoFocusAlternative : listCellInactiveBackgroundNoFocus, + listCellInactiveBackgroundSelectedNoFocus); + } + + public static void setupStandardBackground(final Component comp, final JComponent parent, final boolean selected) { + setupBackground(comp, hasFocus(parent, comp), selected, + cellBackground, cellBackgroundSelected, + cellBackgroundNoFocus, cellBackgroundSelectedNoFocus, + cellInactiveBackground, cellInactiveBackgroundSelected, + cellInactiveBackgroundNoFocus, cellInactiveBackgroundSelectedNoFocus); + } + + public static void setupBackground(final Component comp, final boolean focus, final boolean selected, + final Color bg, final Color selBg, + final Color bgNoFocus, final Color selBgNoFocus, + final Color inactiveBg, final Color inactiveSelBg, + final Color inactiveBgNoFocus, final Color inactiveSelBgNoFocus) { + boolean enabled = comp.isEnabled(); + Color c = getColor(enabled, selected, focus, + bg, selBg, bgNoFocus, selBgNoFocus, inactiveBg, inactiveSelBg, + inactiveBgNoFocus, inactiveSelBgNoFocus); + if (c != null) { + comp.setBackground(c); + } + } + + public static Color getColor(final boolean enabled, final boolean selected, final boolean focus, + final Color color, final Color selColor, + final Color colorNoFocus, final Color selColorNoFocus, + final Color inactiveColor, final Color inactiveSelColor, + final Color inactiveColorNoFocus, final Color inactiveSelColorNoFocus) { + Color c; + if (enabled) { + if (selected) { + if (focus) { + c = selColor; + } else { + c = selColorNoFocus; + } } else { - comp.setBackground(UIManager.getColor(noFocusSelectionBgKey)); + if (focus) { + c = color; + } else { + c = colorNoFocus; + } } } else { - comp.setBackground(background); + if (selected) { + if (focus) { + c = inactiveSelColor; + } else { + c = inactiveSelColorNoFocus; + } + } else { + if (focus) { + c = inactiveColor; + } else { + c = inactiveColorNoFocus; + } + } + } + return c; + } + + protected static boolean hasFocus(final Component c, final Component comp) { + return comp.hasFocus() || (DarkUIUtil.hasFocus(c) || DarkUIUtil.getParentOfType(JPopupMenu.class, c) != null); + } + + public static void setSelectedFlag(final Component comp, final boolean selected) { + if (comp instanceof JComponent) { + ((JComponent) comp).putClientProperty(KEY_SELECTED_CELL_RENDERER, selected); } } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererPane.java b/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererPane.java new file mode 100644 index 00000000..d1a5ae78 --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererPane.java @@ -0,0 +1,31 @@ +/* + * 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.ui.cell; + +import java.awt.*; + +import javax.swing.*; + +public class DarkCellRendererPane extends CellRendererPane {} diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererToggleButton.java b/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererToggleButton.java index 05a6093c..5ac7b029 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererToggleButton.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/cell/DarkCellRendererToggleButton.java @@ -32,7 +32,6 @@ import javax.swing.tree.TreeCellRenderer; import com.github.weisj.darklaf.components.SelectableTreeNode; import com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder; -import com.github.weisj.darklaf.ui.table.DarkTableUI; import com.github.weisj.darklaf.ui.togglebutton.ToggleButtonConstants; import com.github.weisj.darklaf.ui.tree.DarkTreeCellRenderer; import com.github.weisj.darklaf.util.DarkUIUtil; @@ -65,11 +64,8 @@ public class DarkCellRendererToggleButton= numCols && numCols > 0) { - selectedColumnIndex = numCols - 1; - } - return selectedColumnIndex; - } - - /** - * Selects the specified column in the table header. Repaints the affected header cells and makes sure the newly - * selected one is visible. - * - * @param newColIndex the new col index - */ - void selectColumn(final int newColIndex) { - selectColumn(newColIndex, true); - } - - /** - * Select column. - * - * @param newColIndex the new col index - * @param doScroll the do scroll - */ - void selectColumn(final int newColIndex, final boolean doScroll) { - Rectangle repaintRect = header.getHeaderRect(selectedColumnIndex); - header.repaint(repaintRect); - selectedColumnIndex = newColIndex; - repaintRect = header.getHeaderRect(newColIndex); - header.repaint(repaintRect); - if (doScroll) { - scrollToColumn(newColIndex); - } - } - - /** - * Creates the mouse listener for the {@code JTableHeader}. - * - * @return the mouse listener for the {@code JTableHeader} - */ - protected MouseInputListener createMouseInputListener() { - return new DarkTableHeaderUIBridge.MouseInputHandler(); - } - - // Installation - - /** - * Used by selectColumn to scroll horizontally, if necessary, to ensure that the newly selected column is visible. - * - * @param col the col - */ - protected void scrollToColumn(final int col) { - Container container; - JTable table; - - // Test whether the header is in a scroll pane and has a table. - if ((header.getParent() == null) || - ((container = header.getParent().getParent()) == null) || - !(container instanceof JScrollPane) || - ((table = header.getTable()) == null)) { - return; - } - - // Now scroll, if necessary. - Rectangle vis = table.getVisibleRect(); - Rectangle cellBounds = table.getCellRect(0, col, true); - vis.x = cellBounds.x; - vis.width = cellBounds.width; - table.scrollRectToVisible(vis); - } - - /** - * Select previous column int. - * - * @param doIt the do it - * @return the int - */ - protected int selectPreviousColumn(final boolean doIt) { - int newIndex = getSelectedColumnIndex(); - if (newIndex > 0) { - newIndex--; - if (doIt) { - selectColumn(newIndex); - } - } - return newIndex; - } - - /** - * Change column width int. - * - * @param resizingColumn the resizing column - * @param th the th - * @param oldWidth the old width - * @param newWidth the new width - * @return the int - */ - protected int changeColumnWidth(final TableColumn resizingColumn, - final JTableHeader th, - final int oldWidth, final int newWidth) { - resizingColumn.setWidth(newWidth); - - Container container; - JTable table; - - if ((th.getParent() == null) || - ((container = th.getParent().getParent()) == null) || - !(container instanceof JScrollPane) || - ((table = th.getTable()) == null)) { - return 0; - } - - if (!container.getComponentOrientation().isLeftToRight() && - !th.getComponentOrientation().isLeftToRight()) { - JViewport viewport = ((JScrollPane) container).getViewport(); - int viewportWidth = viewport.getWidth(); - int diff = newWidth - oldWidth; - int newHeaderWidth = table.getWidth() + diff; - - /* Resize a table */ - Dimension tableSize = table.getSize(); - tableSize.width += diff; - table.setSize(tableSize); - - /* - * If this table is in AUTO_RESIZE_OFF mode and - * has a horizontal scrollbar, we need to update - * a view's position. - */ - if ((newHeaderWidth >= viewportWidth) && - (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)) { - Point p = viewport.getViewPosition(); - p.x = Math.max(0, Math.min(newHeaderWidth - viewportWidth, - p.x + diff)); - viewport.setViewPosition(p); - return diff; - } - } - return 0; - } - - /** - * Paint cell. - * - * @param g the g - * @param cellRect the cell rect - * @param columnIndex the column index - */ - protected void paintCell(final Graphics g, final Rectangle cellRect, final int columnIndex) { - Component component = getHeaderRenderer(columnIndex); - rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, - cellRect.width, cellRect.height, true); - } - - /** - * Gets header renderer. - * - * @param columnIndex the column index - * @return the header renderer - */ - protected Component getHeaderRenderer(final int columnIndex) { - TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); - TableCellRenderer renderer = aColumn.getHeaderRenderer(); - if (renderer == null) { - renderer = header.getDefaultRenderer(); - } - - boolean hasFocus = !header.isPaintingForPrint() - && (columnIndex == getSelectedColumnIndex()) - && header.hasFocus(); - return renderer.getTableCellRendererComponent(header.getTable(), - aColumn.getHeaderValue(), - false, hasFocus, - -1, columnIndex); - } - - public void installUI(final JComponent c) { - super.installUI(c); - } - - /** - * Initializes JTableHeader properties such as font, foreground, and background. The font, foreground, and - * background properties are only set if their current value is either null or a UIResource, other properties are - * set if the current value is null. - * - * @see #installUI - */ - protected void installDefaults() { - LookAndFeel.installColorsAndFont(header, "TableHeader.background", - "TableHeader.foreground", "TableHeader.font"); - LookAndFeel.installProperty(header, PropertyKey.OPAQUE, Boolean.TRUE); - } - - /** - * Attaches listeners to the JTableHeader. - */ - protected void installListeners() { - mouseInputListener = createMouseInputListener(); - - header.addMouseListener(mouseInputListener); - header.addMouseMotionListener(mouseInputListener); - header.addFocusListener(focusListener); - } - - // Uninstall methods - - public void uninstallUI(final JComponent c) { - uninstallDefaults(); - uninstallListeners(); - uninstallKeyboardActions(); - - header.remove(rendererPane); - rendererPane = null; - header = null; - } - - /** - * Uninstalls default properties - */ - protected void uninstallDefaults() {} - - /** - * Unregisters listeners. - */ - protected void uninstallListeners() { - header.removeMouseListener(mouseInputListener); - header.removeMouseMotionListener(mouseInputListener); - header.removeFocusListener(focusListener); - - mouseInputListener = null; - } - - /** - * Unregisters default key actions. - */ - protected void uninstallKeyboardActions() { - SwingUtilities.replaceUIInputMap(header, JComponent.WHEN_FOCUSED, null); - SwingUtilities.replaceUIActionMap(header, null); - } - - // - // Support for mouse rollover - // - - /** - * Returns the index of the column header over which the mouse currently is. When the mouse is not over the table - * header, -1 is returned. - * - * @return the index of the current rollover column - * @see #rolloverColumnUpdated(int, int) - * @since 1.6 - */ - protected int getRolloverColumn() { - return rolloverColumn; - } - - /** - * This method gets called every time when a rollover column in the table header is updated. Every look and feel - * that supports a rollover effect in a table header should override this method and repaint the header. - * - * @param oldColumn the index of the previous rollover column or -1 if the mouse was not over a column - * @param newColumn the index of the new rollover column or -1 if the mouse is not over a column - * @see #getRolloverColumn() - * @see JTableHeader#getHeaderRect(int) - * @since 1.6 - */ - protected void rolloverColumnUpdated(final int oldColumn, final int newColumn) {} - - /** - * Returns the baseline. - * - * @throws NullPointerException {@inheritDoc} - * @throws IllegalArgumentException {@inheritDoc} - * @see javax.swing.JComponent#getBaseline(int, int) - * @since 1.6 - */ - public int getBaseline(final JComponent c, final int width, final int height) { - super.getBaseline(c, width, height); - int baseline = -1; - TableColumnModel columnModel = header.getColumnModel(); - for (int column = 0; column < columnModel.getColumnCount(); - column++) { - TableColumn aColumn = columnModel.getColumn(column); - Component comp = getHeaderRenderer(column); - Dimension pref = comp.getPreferredSize(); - int columnBaseline = comp.getBaseline(pref.width, height); - if (columnBaseline >= 0) { - if (baseline == -1) { - baseline = columnBaseline; - } else if (baseline != columnBaseline) { - baseline = -1; - break; - } - } - } - return baseline; - } - - // - // Baseline - // - - public void paint(final Graphics g, final JComponent c) { - if (header.getColumnModel().getColumnCount() <= 0) { - return; - } - boolean ltr = header.getComponentOrientation().isLeftToRight(); - - Rectangle clip = g.getClipBounds(); - Point left = clip.getLocation(); - Point right = new Point(clip.x + clip.width - 1, clip.y); - TableColumnModel cm = header.getColumnModel(); - int cMin = header.columnAtPoint(ltr ? left : right); - int cMax = header.columnAtPoint(ltr ? right : left); - // This should never happen. - if (cMin == -1) { - cMin = 0; - } - // If the table does not have enough columns to fill the view we'll get -1. - // Replace this with the index of the last column. - if (cMax == -1) { - cMax = cm.getColumnCount() - 1; - } - - TableColumn draggedColumn = header.getDraggedColumn(); - int columnWidth; - Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax); - TableColumn aColumn; - if (ltr) { - for (int column = cMin; column <= cMax; column++) { - aColumn = cm.getColumn(column); - columnWidth = aColumn.getWidth(); - cellRect.width = columnWidth; - if (aColumn != draggedColumn) { - paintCell(g, cellRect, column); - } - cellRect.x += columnWidth; - } - } else { - for (int column = cMax; column >= cMin; column--) { - aColumn = cm.getColumn(column); - columnWidth = aColumn.getWidth(); - cellRect.width = columnWidth; - if (aColumn != draggedColumn) { - paintCell(g, cellRect, column); - } - cellRect.x += columnWidth; - } - } - - // Paint the dragged column if we are dragging. - if (draggedColumn != null) { - int draggedColumnIndex = viewIndexForColumn(draggedColumn); - Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); - - // Draw a gray well in place of the moving column. - g.setColor(header.getParent().getBackground()); - g.fillRect(draggedCellRect.x, draggedCellRect.y, - draggedCellRect.width, draggedCellRect.height); - - draggedCellRect.x += header.getDraggedDistance(); - - // Fill the background. - g.setColor(header.getBackground()); - g.fillRect(draggedCellRect.x, draggedCellRect.y, - draggedCellRect.width, draggedCellRect.height); - - paintCell(g, draggedCellRect, draggedColumnIndex); - } - - // Remove all components in the rendererPane. - rendererPane.removeAll(); - } - - // - // Paint Methods and support - // - - /** - * View index for column int. - * - * @param aColumn the a column - * @return the int - */ - protected int viewIndexForColumn(final TableColumn aColumn) { - TableColumnModel cm = header.getColumnModel(); - for (int column = 0; column < cm.getColumnCount(); column++) { - if (cm.getColumn(column) == aColumn) { - return column; - } - } - return -1; - } - - /** - * Create header size dimension. - * - * @param width the width - * @return the dimension - */ - protected Dimension createHeaderSize(long width) { - // None of the callers include the intercell spacing, do it here. - if (width > Integer.MAX_VALUE) { - width = Integer.MAX_VALUE; - } - return new Dimension((int) width, getHeaderHeight()); - } - - /** - * Gets header height. - * - * @return the header height - */ - protected int getHeaderHeight() { - int height = 0; - boolean accomodatedDefault = false; - TableColumnModel columnModel = header.getColumnModel(); - for (int column = 0; column < columnModel.getColumnCount(); column++) { - TableColumn aColumn = columnModel.getColumn(column); - boolean isDefault = (aColumn.getHeaderRenderer() == null); - - if (!isDefault || !accomodatedDefault) { - Component comp = getHeaderRenderer(column); - int rendererHeight = comp.getPreferredSize().height; - height = Math.max(height, rendererHeight); - - // Configuring the header renderer to calculate its preferred size - // is expensive. Optimise this by assuming the default renderer - // always has the same height as the first non-zero height that - // it returns for a non-null/non-empty value. - if (isDefault && rendererHeight > 0) { - Object headerValue = aColumn.getHeaderValue(); - if (headerValue != null) { - headerValue = headerValue.toString(); - - if (headerValue != null && !headerValue.equals("")) { - accomodatedDefault = true; - } - } - } - } - } - return height; - } - - /** - * The type Actions. - */ - protected static class Actions extends UIAction { - /** - * The constant TOGGLE_SORT_ORDER. - */ - public static final String TOGGLE_SORT_ORDER = "toggleSortOrder"; - /** - * The constant SELECT_COLUMN_TO_LEFT. - */ - public static final String SELECT_COLUMN_TO_LEFT = "selectColumnToLeft"; - /** - * The constant SELECT_COLUMN_TO_RIGHT. - */ - public static final String SELECT_COLUMN_TO_RIGHT = "selectColumnToRight"; - /** - * The constant MOVE_COLUMN_LEFT. - */ - public static final String MOVE_COLUMN_LEFT = "moveColumnLeft"; - /** - * The constant MOVE_COLUMN_RIGHT. - */ - public static final String MOVE_COLUMN_RIGHT = "moveColumnRight"; - /** - * The constant RESIZE_LEFT. - */ - public static final String RESIZE_LEFT = "resizeLeft"; - /** - * The constant RESIZE_RIGHT. - */ - public static final String RESIZE_RIGHT = "resizeRight"; - /** - * The constant FOCUS_TABLE. - */ - public static final String FOCUS_TABLE = "focusTable"; - - /** - * Instantiates a new Actions. - * - * @param name the name - */ - public Actions(final String name) { - super(name); - } - - /** - * Accept boolean. - * - * @param sender the sender - * @return the boolean - */ - public boolean accept(final Object sender) { - if (sender instanceof JTableHeader) { - JTableHeader th = (JTableHeader) sender; - TableColumnModel cm = th.getColumnModel(); - if (cm.getColumnCount() <= 0) { - return false; - } - - String key = getName(); - DarkTableHeaderUIBridge ui = (DarkTableHeaderUIBridge) DarkUIUtil.getUIOfType(th.getUI(), - DarkTableHeaderUIBridge.class); - if (ui != null) { - if (Objects.equals(key, MOVE_COLUMN_LEFT)) { - return th.getReorderingAllowed() - && maybeMoveColumn(true, th, ui, false); - } else if (Objects.equals(key, MOVE_COLUMN_RIGHT)) { - return th.getReorderingAllowed() - && maybeMoveColumn(false, th, ui, false); - } else if (Objects.equals(key, RESIZE_LEFT) || - Objects.equals(key, RESIZE_RIGHT)) { - return canResize(cm.getColumn(ui.getSelectedColumnIndex()), th); - } else if (Objects.equals(key, FOCUS_TABLE)) { - return (th.getTable() != null); - } - } - } - return true; - } - - /** - * Maybe move column boolean. - * - * @param leftArrow the left arrow - * @param th the th - * @param ui the ui - * @param doIt the do it - * @return the boolean - */ - protected boolean maybeMoveColumn(final boolean leftArrow, final JTableHeader th, - final DarkTableHeaderUIBridge ui, final boolean doIt) { - int oldIndex = ui.getSelectedColumnIndex(); - int newIndex; - - if (th.getComponentOrientation().isLeftToRight()) { - newIndex = leftArrow ? ui.selectPreviousColumn(doIt) - : ui.selectNextColumn(doIt); - } else { - newIndex = leftArrow ? ui.selectNextColumn(doIt) - : ui.selectPreviousColumn(doIt); - } - - if (newIndex != oldIndex) { - if (doIt) { - th.getColumnModel().moveColumn(oldIndex, newIndex); - } else { - return true; // we'd do the move if asked - } - } - - return false; - } - - public void actionPerformed(final ActionEvent e) { - JTableHeader th = (JTableHeader) e.getSource(); - DarkTableHeaderUIBridge ui = (DarkTableHeaderUIBridge) DarkUIUtil.getUIOfType(th.getUI(), - DarkTableHeaderUIBridge.class); - if (ui == null) { - return; - } - - String name = getName(); - if (Objects.equals(TOGGLE_SORT_ORDER, name)) { - JTable table = th.getTable(); - RowSorter sorter = table == null ? null : table.getRowSorter(); - if (sorter != null) { - int columnIndex = ui.getSelectedColumnIndex(); - columnIndex = table.convertColumnIndexToModel(columnIndex); - sorter.toggleSortOrder(columnIndex); - } - } else if (Objects.equals(SELECT_COLUMN_TO_LEFT, name)) { - if (th.getComponentOrientation().isLeftToRight()) { - ui.selectPreviousColumn(true); - } else { - ui.selectNextColumn(true); - } - } else if (Objects.equals(SELECT_COLUMN_TO_RIGHT, name)) { - if (th.getComponentOrientation().isLeftToRight()) { - ui.selectNextColumn(true); - } else { - ui.selectPreviousColumn(true); - } - } else if (Objects.equals(MOVE_COLUMN_LEFT, name)) { - moveColumn(true, th, ui); - } else if (Objects.equals(MOVE_COLUMN_RIGHT, name)) { - moveColumn(false, th, ui); - } else if (Objects.equals(RESIZE_LEFT, name)) { - resize(true, th, ui); - } else if (Objects.equals(RESIZE_RIGHT, name)) { - resize(false, th, ui); - } else if (Objects.equals(FOCUS_TABLE, name)) { - JTable table = th.getTable(); - if (table != null) { - table.requestFocusInWindow(); - } - } - } - - /** - * Move column. - * - * @param leftArrow the left arrow - * @param th the th - * @param ui the ui - */ - protected void moveColumn(final boolean leftArrow, final JTableHeader th, - final DarkTableHeaderUIBridge ui) { - maybeMoveColumn(leftArrow, th, ui, true); - } - - /** - * Resize. - * - * @param leftArrow the left arrow - * @param th the th - * @param ui the ui - */ - protected void resize(final boolean leftArrow, final JTableHeader th, - final DarkTableHeaderUIBridge ui) { - int columnIndex = ui.getSelectedColumnIndex(); - TableColumn resizingColumn = th.getColumnModel().getColumn(columnIndex); - - th.setResizingColumn(resizingColumn); - int oldWidth = resizingColumn.getWidth(); - int newWidth = oldWidth; - - if (th.getComponentOrientation().isLeftToRight()) { - newWidth = newWidth + (leftArrow ? -1 : 1); - } else { - newWidth = newWidth + (leftArrow ? 1 : -1); - } - - ui.changeColumnWidth(resizingColumn, th, oldWidth, newWidth); - } - } - - // - // Size Methods - // - - /** - * This class should be treated as a "protected" inner class. Instantiate it only within subclasses of - * {@code DarkTableHeaderUIBridge}. - */ - public class MouseInputHandler implements MouseInputListener { - - /** - * The Mouse x offset. - */ - protected int mouseXOffset; - /** - * The Other cursor. - */ - protected Cursor otherCursor = resizeCursor; - - public void mouseClicked(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - if (e.getClickCount() % 2 == 1 && - SwingUtilities.isLeftMouseButton(e)) { - JTable table = header.getTable(); - RowSorter sorter; - if (table != null && (sorter = table.getRowSorter()) != null) { - int columnIndex = header.columnAtPoint(e.getPoint()); - if (columnIndex != -1) { - columnIndex = table.convertColumnIndexToModel(columnIndex); - sorter.toggleSortOrder(columnIndex); - } - } - } - } - - public void mousePressed(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - header.setDraggedColumn(null); - header.setResizingColumn(null); - header.setDraggedDistance(0); - - Point p = e.getPoint(); - - // First find which header cell was hit - TableColumnModel columnModel = header.getColumnModel(); - int index = header.columnAtPoint(p); - - if (index != -1) { - // The last 3 pixels + 3 pixels of next column are for resizing - TableColumn resizingColumn = getResizingColumn(p, index); - if (canResize(resizingColumn, header)) { - header.setResizingColumn(resizingColumn); - if (header.getComponentOrientation().isLeftToRight()) { - mouseXOffset = p.x - resizingColumn.getWidth(); - } else { - mouseXOffset = p.x + resizingColumn.getWidth(); - } - } else if (header.getReorderingAllowed()) { - TableColumn hitColumn = columnModel.getColumn(index); - header.setDraggedColumn(hitColumn); - mouseXOffset = p.x; - } - } - - if (header.getReorderingAllowed()) { - int oldRolloverColumn = rolloverColumn; - rolloverColumn = -1; - rolloverColumnUpdated(oldRolloverColumn, rolloverColumn); - } - } - - /** - * Sets dragged distance. - * - * @param draggedDistance the dragged distance - * @param column the column - */ - protected void setDraggedDistance(final int draggedDistance, final int column) { - header.setDraggedDistance(draggedDistance); - if (column != -1) { - header.getColumnModel().moveColumn(column, column); - } - } - - public void mouseReleased(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - setDraggedDistance(0, viewIndexForColumn(header.getDraggedColumn())); - - header.setResizingColumn(null); - header.setDraggedColumn(null); - - updateRolloverColumn(e); - } - - public void mouseEntered(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - updateRolloverColumn(e); - } - - public void mouseExited(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - int oldRolloverColumn = rolloverColumn; - rolloverColumn = -1; - rolloverColumnUpdated(oldRolloverColumn, rolloverColumn); - } - - /** - * Gets resizing column. - * - * @param p the p - * @return the resizing column - */ - protected TableColumn getResizingColumn(final Point p) { - return getResizingColumn(p, header.columnAtPoint(p)); - } - - public void mouseDragged(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - int mouseX = e.getX(); - - TableColumn resizingColumn = header.getResizingColumn(); - TableColumn draggedColumn = header.getDraggedColumn(); - - boolean headerLeftToRight = header.getComponentOrientation().isLeftToRight(); - - if (resizingColumn != null) { - int oldWidth = resizingColumn.getWidth(); - int newWidth; - if (headerLeftToRight) { - newWidth = mouseX - mouseXOffset; - } else { - newWidth = mouseXOffset - mouseX; - } - mouseXOffset += changeColumnWidth(resizingColumn, header, - oldWidth, newWidth); - } else if (draggedColumn != null) { - TableColumnModel cm = header.getColumnModel(); - int draggedDistance = mouseX - mouseXOffset; - int direction = (draggedDistance < 0) ? -1 : 1; - int columnIndex = viewIndexForColumn(draggedColumn); - int newColumnIndex = columnIndex + (headerLeftToRight ? direction : -direction); - if (0 <= newColumnIndex && newColumnIndex < cm.getColumnCount()) { - int width = cm.getColumn(newColumnIndex).getWidth(); - if (Math.abs(draggedDistance) > (width / 2)) { - - mouseXOffset = mouseXOffset + direction * width; - header.setDraggedDistance(draggedDistance - direction * width); - - // Cache the selected column. - int selectedIndex = SwingUtilities2.convertColumnIndexToModel(header.getColumnModel(), - getSelectedColumnIndex()); - - // Now do the move. - cm.moveColumn(columnIndex, newColumnIndex); - - // Update the selected index. - selectColumn(SwingUtilities2.convertColumnIndexToView(header.getColumnModel(), selectedIndex), - false); - - return; - } - } - setDraggedDistance(draggedDistance, columnIndex); - } - - updateRolloverColumn(e); - } - - public void mouseMoved(final MouseEvent e) { - if (!header.isEnabled()) { - return; - } - if (canResize(getResizingColumn(e.getPoint()), header) != (header.getCursor() == resizeCursor)) { - swapCursor(); - } - updateRolloverColumn(e); - } - - /** - * Gets resizing column. - * - * @param p the p - * @param column the column - * @return the resizing column - */ - protected TableColumn getResizingColumn(final Point p, final int column) { - if (column == -1) { - return null; - } - Rectangle r = header.getHeaderRect(column); - r.grow(-3, 0); - if (r.contains(p)) { - return null; - } - int midPoint = r.x + r.width / 2; - int columnIndex; - if (header.getComponentOrientation().isLeftToRight()) { - columnIndex = (p.x < midPoint) ? column - 1 : column; - } else { - columnIndex = (p.x < midPoint) ? column : column - 1; - } - if (columnIndex == -1) { - return null; - } - return header.getColumnModel().getColumn(columnIndex); - } - // - // Protected & protected Methods - // - - /** - * Swap cursor. - */ - protected void swapCursor() { - Cursor tmp = header.getCursor(); - header.setCursor(otherCursor); - otherCursor = tmp; - } - } - - /** - * Return the minimum size of the header. The minimum width is the sum of the minimum widths of each column (plus - * inter-cell spacing). - */ - public Dimension getMinimumSize(final JComponent c) { - long width = 0; - Enumeration enumeration = header.getColumnModel().getColumns(); - while (enumeration.hasMoreElements()) { - TableColumn aColumn = enumeration.nextElement(); - width = width + aColumn.getMinWidth(); - } - return createHeaderSize(width); - } - - /** - * Return the preferred size of the header. The preferred height is the maximum of the preferred heights of all of - * the components provided by the header renderers. The preferred width is the sum of the preferred widths of each - * column (plus inter-cell spacing). - */ - public Dimension getPreferredSize(final JComponent c) { - long width = 0; - Enumeration enumeration = header.getColumnModel().getColumns(); - while (enumeration.hasMoreElements()) { - TableColumn aColumn = enumeration.nextElement(); - width = width + aColumn.getPreferredWidth(); - } - return createHeaderSize(width); - } - - /** - * Return the maximum size of the header. The maximum width is the sum of the maximum widths of each column (plus - * inter-cell spacing). - */ - public Dimension getMaximumSize(final JComponent c) { - long width = 0; - Enumeration enumeration = header.getColumnModel().getColumns(); - while (enumeration.hasMoreElements()) { - TableColumn aColumn = enumeration.nextElement(); - width = width + aColumn.getMaxWidth(); - } - return createHeaderSize(width); - } -} diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableUI.java index 3c17e611..149ac647 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableUI.java @@ -42,6 +42,10 @@ import sun.swing.SwingUtilities2; import com.github.weisj.darklaf.components.OverlayScrollPane; import com.github.weisj.darklaf.ui.cell.CellUtil; +import com.github.weisj.darklaf.ui.cell.DarkCellRendererPane; +import com.github.weisj.darklaf.ui.table.renderer.DarkColorTableCellRendererEditor; +import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditor; +import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellRenderer; import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.util.PropertyKey; import com.github.weisj.darklaf.util.PropertyUtil; @@ -99,10 +103,12 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { || KEY_RENDER_BOOLEAN_AS_CHECKBOX.equals(key) || KEY_BOOLEAN_RENDER_TYPE.equals(key)) { table.repaint(); + } else if (PropertyKey.ENABLED.equals(key)) { + DarkUIUtil.repaint(table.getTableHeader()); } }; + protected Color selectionBackgroundNoFocus; protected Color selectionBackground; - protected Color selectionFocusBackground; protected Color borderColor; public static ComponentUI createUI(final JComponent c) { @@ -116,7 +122,6 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { @Override public void installUI(final JComponent c) { super.installUI(c); - table.setSurrendersFocusOnKeystroke(true); } @Override @@ -138,7 +143,7 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { public void focusGained(final FocusEvent e) { Color bg = table.getSelectionBackground(); if (bg instanceof UIResource) { - table.setSelectionBackground(selectionFocusBackground); + table.setSelectionBackground(selectionBackground); } table.repaint(); } @@ -150,7 +155,7 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { if (table.isEditing()) { table.setSelectionBackground(table.getBackground()); } else { - table.setSelectionBackground(selectionBackground); + table.setSelectionBackground(selectionBackgroundNoFocus); } } table.repaint(); @@ -170,6 +175,33 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { LookAndFeel.uninstallBorder((JComponent) oldUnwrapped); } + protected Color getBorderColor() { + return borderColor; + } + + @Override + protected void installDefaults() { + super.installDefaults(); + int rowHeight = UIManager.getInt("Table.rowHeight"); + if (rowHeight > 0) { + LookAndFeel.installProperty(table, "rowHeight", ROW_HEIGHT_FALLBACK); + } + table.setDefaultEditor(Object.class, new DarkTableCellEditor()); + PropertyUtil.installBooleanProperty(table, KEY_RENDER_BOOLEAN_AS_CHECKBOX, "Table.renderBooleanAsCheckBox"); + PropertyUtil.installBooleanProperty(table, KEY_ALTERNATE_ROW_COLOR, "Table.alternateRowColor"); + PropertyUtil.installProperty(table, KEY_BOOLEAN_RENDER_TYPE, UIManager.getString("Table.booleanRenderType")); + setupRendererComponents(table); + borderColor = UIManager.getColor("TableHeader.borderColor"); + selectionBackground = UIManager.getColor("Table.backgroundSelected"); + selectionBackgroundNoFocus = UIManager.getColor("Table.backgroundSelectedNoFocus"); + rendererPane = createCellRendererPane(); + table.setSurrendersFocusOnKeystroke(true); + } + + protected CellRendererPane createCellRendererPane() { + return new DarkCellRendererPane(); + } + protected static void setupRendererComponents(final JTable table) { DarkTableCellRenderer cellRenderer = new DarkTableCellRenderer(); DarkTableCellEditor cellEditor = new DarkTableCellEditor(); @@ -192,27 +224,6 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { table.setDefaultEditor(Color.class, colorRendererEditor); } - protected Color getBorderColor() { - return borderColor; - } - - @Override - protected void installDefaults() { - super.installDefaults(); - int rowHeight = UIManager.getInt("Table.rowHeight"); - if (rowHeight > 0) { - LookAndFeel.installProperty(table, "rowHeight", ROW_HEIGHT_FALLBACK); - } - table.setDefaultEditor(Object.class, new DarkTableCellEditor()); - PropertyUtil.installBooleanProperty(table, KEY_RENDER_BOOLEAN_AS_CHECKBOX, "Table.renderBooleanAsCheckBox"); - PropertyUtil.installBooleanProperty(table, KEY_ALTERNATE_ROW_COLOR, "Table.alternateRowColor"); - PropertyUtil.installProperty(table, KEY_BOOLEAN_RENDER_TYPE, UIManager.getString("Table.booleanRenderType")); - setupRendererComponents(table); - borderColor = UIManager.getColor("TableHeader.borderColor"); - selectionFocusBackground = UIManager.getColor("Table.focusSelectionBackground"); - selectionBackground = UIManager.getColor("Table.selectionNoFocusBackground"); - } - protected void checkFocus() { boolean focus = DarkUIUtil.hasFocus(table); if (focus) { @@ -581,8 +592,8 @@ public class DarkTableUI extends DarkTableUIBridge implements FocusListener { } } - protected static int adjustDistance(final int distance, final Rectangle rect, - final JTable comp) { + public static int adjustDistance(final int distance, final Rectangle rect, + final JTable comp) { int dist = distance; int min = 0; int max = comp.getX() + comp.getWidth(); diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/TableUIBridge.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/TableUIBridge.java index a83ec9a1..10eac2c8 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/TableUIBridge.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/TableUIBridge.java @@ -25,37 +25,31 @@ package com.github.weisj.darklaf.ui.table; import java.awt.*; -import java.awt.datatransfer.Transferable; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Enumeration; -import java.util.Objects; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.MouseInputListener; -import javax.swing.plaf.TableHeaderUI; -import javax.swing.plaf.TableUI; import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.*; import sun.swing.DefaultLookup; import sun.swing.SwingUtilities2; -import sun.swing.UIAction; -import com.github.weisj.darklaf.ui.BasicTransferable; import com.github.weisj.darklaf.ui.DragRecognitionSupport; import com.github.weisj.darklaf.util.DarkUIUtil; -import com.github.weisj.darklaf.util.LazyActionMap; import com.github.weisj.darklaf.util.PropertyKey; import com.github.weisj.darklaf.util.PropertyUtil; /** * The type Table ui bridge. */ -public abstract class TableUIBridge extends TableUI { +public abstract class TableUIBridge extends BasicTableUI { /** * The constant BASELINE_COMPONENT_KEY. @@ -66,11 +60,6 @@ public abstract class TableUIBridge extends TableUI { // Instance Variables // - /** - * The constant defaultTransferHandler. - */ - // The JTable that is delegating the painting to this UI. - protected static final TransferHandler defaultTransferHandler = new TableTransferHandler(); /** * The instance of {@code JTable}. */ @@ -112,110 +101,6 @@ public abstract class TableUIBridge extends TableUI { // The Table's focus listener // - /** - * Load action map. - * - * @param map the map - */ - public static void loadActionMap(final LazyActionMap map) { - // IMPORTANT: There is a very close coupling between the parameters - // passed to the Actions constructor. Only certain parameter - // combinations are supported. For example, the following Action would - // not work as expected: - // new Actions(Actions.NEXT_ROW_CELL, 1, 4, false, true) - // Actions which move within the selection only (having a true - // inSelection parameter) require that one of dx or dy be - // zero and the other be -1 or 1. The point of this warning is - // that you should be very careful about making sure a particular - // combination of parameters is supported before changing or - // adding anything here. - - map.put(new Actions(Actions.NEXT_COLUMN, 1, 0, - false, false)); - map.put(new Actions(Actions.NEXT_COLUMN_CHANGE_LEAD, 1, 0, - false, false)); - map.put(new Actions(Actions.PREVIOUS_COLUMN, -1, 0, - false, false)); - map.put(new Actions(Actions.PREVIOUS_COLUMN_CHANGE_LEAD, -1, 0, - false, false)); - map.put(new Actions(Actions.NEXT_ROW, 0, 1, - false, false)); - map.put(new Actions(Actions.NEXT_ROW_CHANGE_LEAD, 0, 1, - false, false)); - map.put(new Actions(Actions.PREVIOUS_ROW, 0, -1, - false, false)); - map.put(new Actions(Actions.PREVIOUS_ROW_CHANGE_LEAD, 0, -1, - false, false)); - map.put(new Actions(Actions.NEXT_COLUMN_EXTEND_SELECTION, - 1, 0, true, false)); - map.put(new Actions(Actions.PREVIOUS_COLUMN_EXTEND_SELECTION, - -1, 0, true, false)); - map.put(new Actions(Actions.NEXT_ROW_EXTEND_SELECTION, - 0, 1, true, false)); - map.put(new Actions(Actions.PREVIOUS_ROW_EXTEND_SELECTION, - 0, -1, true, false)); - map.put(new Actions(Actions.SCROLL_UP_CHANGE_SELECTION, - false, false, true, false)); - map.put(new Actions(Actions.SCROLL_DOWN_CHANGE_SELECTION, - false, true, true, false)); - map.put(new Actions(Actions.FIRST_COLUMN, - false, false, false, true)); - map.put(new Actions(Actions.LAST_COLUMN, - false, true, false, true)); - - map.put(new Actions(Actions.SCROLL_UP_EXTEND_SELECTION, - true, false, true, false)); - map.put(new Actions(Actions.SCROLL_DOWN_EXTEND_SELECTION, - true, true, true, false)); - map.put(new Actions(Actions.FIRST_COLUMN_EXTEND_SELECTION, - true, false, false, true)); - map.put(new Actions(Actions.LAST_COLUMN_EXTEND_SELECTION, - true, true, false, true)); - - map.put(new Actions(Actions.FIRST_ROW, false, false, true, true)); - map.put(new Actions(Actions.LAST_ROW, false, true, true, true)); - - map.put(new Actions(Actions.FIRST_ROW_EXTEND_SELECTION, - true, false, true, true)); - map.put(new Actions(Actions.LAST_ROW_EXTEND_SELECTION, - true, true, true, true)); - - map.put(new Actions(Actions.NEXT_COLUMN_CELL, - 1, 0, false, true)); - map.put(new Actions(Actions.PREVIOUS_COLUMN_CELL, - -1, 0, false, true)); - map.put(new Actions(Actions.NEXT_ROW_CELL, 0, 1, false, true)); - map.put(new Actions(Actions.PREVIOUS_ROW_CELL, - 0, -1, false, true)); - - map.put(new Actions(Actions.SELECT_ALL)); - map.put(new Actions(Actions.CLEAR_SELECTION)); - map.put(new Actions(Actions.CANCEL_EDITING)); - map.put(new Actions(Actions.START_EDITING)); - - map.put(TransferHandler.getCutAction().getValue(Action.NAME), - TransferHandler.getCutAction()); - map.put(TransferHandler.getCopyAction().getValue(Action.NAME), - TransferHandler.getCopyAction()); - map.put(TransferHandler.getPasteAction().getValue(Action.NAME), - TransferHandler.getPasteAction()); - - map.put(new Actions(Actions.SCROLL_LEFT_CHANGE_SELECTION, - false, false, false, false)); - map.put(new Actions(Actions.SCROLL_RIGHT_CHANGE_SELECTION, - false, true, false, false)); - map.put(new Actions(Actions.SCROLL_LEFT_EXTEND_SELECTION, - true, false, false, false)); - map.put(new Actions(Actions.SCROLL_RIGHT_EXTEND_SELECTION, - true, true, false, false)); - - map.put(new Actions(Actions.ADD_TO_SELECTION)); - map.put(new Actions(Actions.TOGGLE_AND_ANCHOR)); - map.put(new Actions(Actions.EXTEND_TO)); - map.put(new Actions(Actions.MOVE_SELECTION_TO)); - map.put(new Actions(Actions.FOCUS_HEADER)); - } - // // The Table's mouse and mouse motion listeners // @@ -243,7 +128,6 @@ public abstract class TableUIBridge extends TableUI { protected static int getAdjustedLead(final JTable table, final boolean row, final ListSelectionModel model) { - int index = model.getLeadSelectionIndex(); int compare = row ? table.getRowCount() : table.getColumnCount(); return index < compare ? index : -1; @@ -276,11 +160,11 @@ public abstract class TableUIBridge extends TableUI { public void installUI(final JComponent c) { table = (JTable) c; + super.installUI(c); rendererPane = new CellRendererPane(); table.add(rendererPane); installDefaults(); - installDefaults2(); installListeners(); installKeyboardActions(); } @@ -327,7 +211,7 @@ public abstract class TableUIBridge extends TableUI { Container parent = DarkUIUtil.getUnwrappedParent(table); // should be viewport if (parent != null) { parent = parent.getParent(); // should be the scrollpane - if (parent != null && parent instanceof JScrollPane) { + if (parent instanceof JScrollPane) { LookAndFeel.installBorder((JScrollPane) parent, "Table.scrollPaneBorder"); } } @@ -335,21 +219,6 @@ public abstract class TableUIBridge extends TableUI { isFileList = PropertyUtil.getBooleanProperty(table, DarkTableUI.KEY_IS_FILE_LIST); } - /** - * Install defaults 2. - */ - protected void installDefaults2() { - TransferHandler th = table.getTransferHandler(); - if (th == null || th instanceof UIResource) { - table.setTransferHandler(defaultTransferHandler); - // default TransferHandler doesn't support drop - // so we don't want drop handling - if (table.getDropTarget() instanceof UIResource) { - table.setDropTarget(null); - } - } - } - /** * Attaches listeners to the JTable. */ @@ -372,18 +241,6 @@ public abstract class TableUIBridge extends TableUI { // The installation/uninstall procedures and support // - /** - * Register all keyboard actions on the JTable. - */ - protected void installKeyboardActions() { - LazyActionMap.installLazyActionMap(table, TableUIBridge.class, "Table.actionMap"); - // var map = new LazyActionMap(null); - // loadActionMap(map); - // SwingUtilities.replaceUIActionMap(table, map); - InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - SwingUtilities.replaceUIInputMap(table, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap); - } - // Installation /** @@ -766,989 +623,6 @@ public abstract class TableUIBridge extends TableUI { */ protected abstract int viewIndexForColumn(final TableColumn aColumn); - /** - * The type Actions. - */ - protected static class Actions extends UIAction { - /** - * The constant CANCEL_EDITING. - */ - protected static final String CANCEL_EDITING = "cancel"; - /** - * The constant SELECT_ALL. - */ - protected static final String SELECT_ALL = "selectAll"; - /** - * The constant CLEAR_SELECTION. - */ - protected static final String CLEAR_SELECTION = "clearSelection"; - /** - * The constant START_EDITING. - */ - protected static final String START_EDITING = "startEditing"; - - /** - * The constant NEXT_ROW. - */ - protected static final String NEXT_ROW = "selectNextRow"; - /** - * The constant NEXT_ROW_CELL. - */ - protected static final String NEXT_ROW_CELL = "selectNextRowCell"; - /** - * The constant NEXT_ROW_EXTEND_SELECTION. - */ - protected static final String NEXT_ROW_EXTEND_SELECTION = "selectNextRowExtendSelection"; - /** - * The constant NEXT_ROW_CHANGE_LEAD. - */ - protected static final String NEXT_ROW_CHANGE_LEAD = "selectNextRowChangeLead"; - /** - * The constant PREVIOUS_ROW. - */ - protected static final String PREVIOUS_ROW = "selectPreviousRow"; - /** - * The constant PREVIOUS_ROW_CELL. - */ - protected static final String PREVIOUS_ROW_CELL = "selectPreviousRowCell"; - /** - * The constant PREVIOUS_ROW_EXTEND_SELECTION. - */ - protected static final String PREVIOUS_ROW_EXTEND_SELECTION = "selectPreviousRowExtendSelection"; - /** - * The constant PREVIOUS_ROW_CHANGE_LEAD. - */ - protected static final String PREVIOUS_ROW_CHANGE_LEAD = "selectPreviousRowChangeLead"; - - /** - * The constant NEXT_COLUMN. - */ - protected static final String NEXT_COLUMN = "selectNextColumn"; - /** - * The constant NEXT_COLUMN_CELL. - */ - protected static final String NEXT_COLUMN_CELL = "selectNextColumnCell"; - /** - * The constant NEXT_COLUMN_EXTEND_SELECTION. - */ - protected static final String NEXT_COLUMN_EXTEND_SELECTION = "selectNextColumnExtendSelection"; - /** - * The constant NEXT_COLUMN_CHANGE_LEAD. - */ - protected static final String NEXT_COLUMN_CHANGE_LEAD = "selectNextColumnChangeLead"; - /** - * The constant PREVIOUS_COLUMN. - */ - protected static final String PREVIOUS_COLUMN = "selectPreviousColumn"; - /** - * The constant PREVIOUS_COLUMN_CELL. - */ - protected static final String PREVIOUS_COLUMN_CELL = "selectPreviousColumnCell"; - /** - * The constant PREVIOUS_COLUMN_EXTEND_SELECTION. - */ - protected static final String PREVIOUS_COLUMN_EXTEND_SELECTION = "selectPreviousColumnExtendSelection"; - /** - * The constant PREVIOUS_COLUMN_CHANGE_LEAD. - */ - protected static final String PREVIOUS_COLUMN_CHANGE_LEAD = "selectPreviousColumnChangeLead"; - - /** - * The constant SCROLL_LEFT_CHANGE_SELECTION. - */ - protected static final String SCROLL_LEFT_CHANGE_SELECTION = "scrollLeftChangeSelection"; - /** - * The constant SCROLL_LEFT_EXTEND_SELECTION. - */ - protected static final String SCROLL_LEFT_EXTEND_SELECTION = "scrollLeftExtendSelection"; - /** - * The constant SCROLL_RIGHT_CHANGE_SELECTION. - */ - protected static final String SCROLL_RIGHT_CHANGE_SELECTION = "scrollRightChangeSelection"; - /** - * The constant SCROLL_RIGHT_EXTEND_SELECTION. - */ - protected static final String SCROLL_RIGHT_EXTEND_SELECTION = "scrollRightExtendSelection"; - - /** - * The constant SCROLL_UP_CHANGE_SELECTION. - */ - protected static final String SCROLL_UP_CHANGE_SELECTION = "scrollUpChangeSelection"; - /** - * The constant SCROLL_UP_EXTEND_SELECTION. - */ - protected static final String SCROLL_UP_EXTEND_SELECTION = "scrollUpExtendSelection"; - /** - * The constant SCROLL_DOWN_CHANGE_SELECTION. - */ - protected static final String SCROLL_DOWN_CHANGE_SELECTION = "scrollDownChangeSelection"; - /** - * The constant SCROLL_DOWN_EXTEND_SELECTION. - */ - protected static final String SCROLL_DOWN_EXTEND_SELECTION = "scrollDownExtendSelection"; - - /** - * The constant FIRST_COLUMN. - */ - protected static final String FIRST_COLUMN = "selectFirstColumn"; - /** - * The constant FIRST_COLUMN_EXTEND_SELECTION. - */ - protected static final String FIRST_COLUMN_EXTEND_SELECTION = "selectFirstColumnExtendSelection"; - /** - * The constant LAST_COLUMN. - */ - protected static final String LAST_COLUMN = "selectLastColumn"; - /** - * The constant LAST_COLUMN_EXTEND_SELECTION. - */ - protected static final String LAST_COLUMN_EXTEND_SELECTION = "selectLastColumnExtendSelection"; - - /** - * The constant FIRST_ROW. - */ - protected static final String FIRST_ROW = "selectFirstRow"; - /** - * The constant FIRST_ROW_EXTEND_SELECTION. - */ - protected static final String FIRST_ROW_EXTEND_SELECTION = "selectFirstRowExtendSelection"; - /** - * The constant LAST_ROW. - */ - protected static final String LAST_ROW = "selectLastRow"; - /** - * The constant LAST_ROW_EXTEND_SELECTION. - */ - protected static final String LAST_ROW_EXTEND_SELECTION = "selectLastRowExtendSelection"; - - /** - * The constant ADD_TO_SELECTION. - */ - // add the lead item to the selection without changing lead or anchor - protected static final String ADD_TO_SELECTION = "addToSelection"; - - /** - * The constant TOGGLE_AND_ANCHOR. - */ - // toggle the selected state of the lead item and move the anchor to it - protected static final String TOGGLE_AND_ANCHOR = "toggleAndAnchor"; - - /** - * The constant EXTEND_TO. - */ - // extend the selection to the lead item - protected static final String EXTEND_TO = "extendTo"; - - /** - * The constant MOVE_SELECTION_TO. - */ - // move the anchor to the lead and ensure only that item is selected - protected static final String MOVE_SELECTION_TO = "moveSelectionTo"; - - /** - * The constant FOCUS_HEADER. - */ - // give focus to the JTableHeader, if one exists - protected static final String FOCUS_HEADER = "focusHeader"; - - /** - * The Dx. - */ - protected int dx; - /** - * The Dy. - */ - protected int dy; - /** - * The Extend. - */ - protected boolean extend; - /** - * The In selection. - */ - protected boolean inSelection; - - /** - * The Forwards. - */ - // horizontally, forwards always means right, - // regardless of component orientation - protected boolean forwards; - /** - * The Vertically. - */ - protected boolean vertically; - /** - * The To limit. - */ - protected boolean toLimit; - - /** - * The Lead row. - */ - protected int leadRow; - /** - * The Lead column. - */ - protected int leadColumn; - - /** - * Instantiates a new Actions. - * - * @param name the name - */ - Actions(final String name) { - super(name); - } - - /** - * Instantiates a new Actions. - * - * @param name the name - * @param extend the extend - * @param forwards the forwards - * @param vertically the vertically - * @param toLimit the to limit - */ - Actions(final String name, final boolean extend, final boolean forwards, - final boolean vertically, final boolean toLimit) { - this(name, 0, 0, extend, false); - this.forwards = forwards; - this.vertically = vertically; - this.toLimit = toLimit; - } - - /** - * Instantiates a new Actions. - * - * @param name the name - * @param dx the dx - * @param dy the dy - * @param extend the extend - * @param inSelection the in selection - */ - Actions(final String name, int dx, int dy, final boolean extend, - final boolean inSelection) { - super(name); - - // Actions spcifying true for "inSelection" are - // fairly sensitive to bad parameter values. They require - // that one of dx and dy be 0 and the other be -1 or 1. - // Bogus parameter values could cause an infinite loop. - // To prevent any problems we massage the params here - // and complain if we get something we can't deal with. - if (inSelection) { - this.inSelection = true; - - // look at the sign of dx and dy only - dx = sign(dx); - dy = sign(dy); - - // make sure one is zero, but not both - assert (dx == 0 || dy == 0) && !(dx == 0 && dy == 0); - } - - this.dx = dx; - this.dy = dy; - this.extend = extend; - } - - /** - * Sign int. - * - * @param num the num - * @return the int - */ - protected static int sign(final int num) { - return Integer.compare(num, 0); - } - - public void actionPerformed(final ActionEvent e) { - String key = getName(); - JTable table = (JTable) e.getSource(); - - ListSelectionModel rsm = table.getSelectionModel(); - leadRow = getAdjustedLead(table, true, rsm); - - ListSelectionModel csm = table.getColumnModel().getSelectionModel(); - leadColumn = getAdjustedLead(table, false, csm); - - if (Objects.equals(key, SCROLL_LEFT_CHANGE_SELECTION) || // Paging Actions - Objects.equals(key, SCROLL_LEFT_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_RIGHT_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_RIGHT_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_UP_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_UP_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_DOWN_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_DOWN_EXTEND_SELECTION) || - Objects.equals(key, FIRST_COLUMN) || - Objects.equals(key, FIRST_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, FIRST_ROW) || - Objects.equals(key, FIRST_ROW_EXTEND_SELECTION) || - Objects.equals(key, LAST_COLUMN) || - Objects.equals(key, LAST_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, LAST_ROW) || - Objects.equals(key, LAST_ROW_EXTEND_SELECTION)) { - if (toLimit) { - if (vertically) { - int rowCount = table.getRowCount(); - this.dx = 0; - this.dy = forwards ? rowCount : -rowCount; - } else { - int colCount = table.getColumnCount(); - this.dx = forwards ? colCount : -colCount; - this.dy = 0; - } - } else { - if (!(DarkUIUtil.getUnwrappedParent(table).getParent() instanceof JScrollPane)) { - return; - } - - Dimension delta = table.getParent().getSize(); - - if (vertically) { - Rectangle r = table.getCellRect(leadRow, 0, true); - if (forwards) { - // scroll by at least one cell - r.y += Math.max(delta.height, r.height); - } else { - r.y -= delta.height; - } - - this.dx = 0; - int newRow = table.rowAtPoint(r.getLocation()); - if (newRow == -1 && forwards) { - newRow = table.getRowCount(); - } - this.dy = newRow - leadRow; - } else { - Rectangle r = table.getCellRect(0, leadColumn, true); - - if (forwards) { - // scroll by at least one cell - r.x += Math.max(delta.width, r.width); - } else { - r.x -= delta.width; - } - - int newColumn = table.columnAtPoint(r.getLocation()); - if (newColumn == -1) { - boolean ltr = table.getComponentOrientation().isLeftToRight(); - - newColumn = forwards ? (ltr ? table.getColumnCount() : 0) - : (ltr ? 0 : table.getColumnCount()); - - } - this.dx = newColumn - leadColumn; - this.dy = 0; - } - } - } - if (Objects.equals(key, NEXT_ROW) || // Navigate Actions - Objects.equals(key, NEXT_ROW_CELL) || - Objects.equals(key, NEXT_ROW_EXTEND_SELECTION) || - Objects.equals(key, NEXT_ROW_CHANGE_LEAD) || - Objects.equals(key, NEXT_COLUMN) || - Objects.equals(key, NEXT_COLUMN_CELL) || - Objects.equals(key, NEXT_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, NEXT_COLUMN_CHANGE_LEAD) || - Objects.equals(key, PREVIOUS_ROW) || - Objects.equals(key, PREVIOUS_ROW_CELL) || - Objects.equals(key, PREVIOUS_ROW_EXTEND_SELECTION) || - Objects.equals(key, PREVIOUS_ROW_CHANGE_LEAD) || - Objects.equals(key, PREVIOUS_COLUMN) || - Objects.equals(key, PREVIOUS_COLUMN_CELL) || - Objects.equals(key, PREVIOUS_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, PREVIOUS_COLUMN_CHANGE_LEAD) || - // Paging Actions. - Objects.equals(key, SCROLL_LEFT_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_LEFT_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_RIGHT_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_RIGHT_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_UP_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_UP_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_DOWN_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_DOWN_EXTEND_SELECTION) || - Objects.equals(key, FIRST_COLUMN) || - Objects.equals(key, FIRST_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, FIRST_ROW) || - Objects.equals(key, FIRST_ROW_EXTEND_SELECTION) || - Objects.equals(key, LAST_COLUMN) || - Objects.equals(key, LAST_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, LAST_ROW) || - Objects.equals(key, LAST_ROW_EXTEND_SELECTION)) { - - if (table.isEditing() && - !table.getCellEditor().stopCellEditing()) { - return; - } - - // Unfortunately, this strategy introduces bugs because - // of the asynchronous nature of requestFocus() call below. - // Introducing a delay with invokeLater() makes this work - // in the typical case though race conditions then allow - // focus to disappear altogether. The right solution appears - // to be to fix requestFocus() so that it queues a request - // for the focus regardless of who owns the focus at the - // time the call to requestFocus() is made. The optimisation - // to ignore the call to requestFocus() when the component - // already has focus may ligitimately be made as the - // request focus event is dequeued, not before. - - // boolean wasEditingWithFocus = table.isEditing() && - // table.getEditorComponent().isFocusOwner(); - - boolean changeLead = false; - if (Objects.equals(key, NEXT_ROW_CHANGE_LEAD) || Objects.equals(key, PREVIOUS_ROW_CHANGE_LEAD)) { - changeLead = (rsm.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - } else if (Objects.equals(key, NEXT_COLUMN_CHANGE_LEAD) || Objects.equals(key, - PREVIOUS_COLUMN_CHANGE_LEAD)) { - changeLead = (csm.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - } - - if (changeLead) { - moveWithinTableRange(table, dx, dy); - if (dy != 0) { - // casting should be safe since the action is only enabled - // for DefaultListSelectionModel - ((DefaultListSelectionModel) rsm).moveLeadSelectionIndex(leadRow); - if (getAdjustedLead(table, false, csm) == -1 - && table.getColumnCount() > 0) { - - ((DefaultListSelectionModel) csm).moveLeadSelectionIndex(0); - } - } else { - // casting should be safe since the action is only enabled - // for DefaultListSelectionModel - ((DefaultListSelectionModel) csm).moveLeadSelectionIndex(leadColumn); - if (getAdjustedLead(table, true, rsm) == -1 - && table.getRowCount() > 0) { - - ((DefaultListSelectionModel) rsm).moveLeadSelectionIndex(0); - } - } - - Rectangle cellRect = table.getCellRect(leadRow, leadColumn, false); - if (cellRect != null) { - table.scrollRectToVisible(cellRect); - } - } else if (!inSelection) { - moveWithinTableRange(table, dx, dy); - table.changeSelection(leadRow, leadColumn, false, extend); - } else { - if (table.getRowCount() <= 0 || table.getColumnCount() <= 0) { - // bail - don't try to move selection on an empty table - return; - } - - if (moveWithinSelectedRange(table, dx, dy, rsm, csm)) { - // this is the only way we have to set both the lead - // and the anchor without changing the selection - if (rsm.isSelectedIndex(leadRow)) { - rsm.addSelectionInterval(leadRow, leadRow); - } else { - rsm.removeSelectionInterval(leadRow, leadRow); - } - - if (csm.isSelectedIndex(leadColumn)) { - csm.addSelectionInterval(leadColumn, leadColumn); - } else { - csm.removeSelectionInterval(leadColumn, leadColumn); - } - - Rectangle cellRect = table.getCellRect(leadRow, leadColumn, false); - if (cellRect != null) { - table.scrollRectToVisible(cellRect); - } - } else { - table.changeSelection(leadRow, leadColumn, - false, false); - } - } - - /* - * if (wasEditingWithFocus) { - * table.editCellAt(leadRow, leadColumn); - * final Component editorComp = table.getEditorComponent(); - * if (editorComp != null) { - * SwingUtilities.invokeLater(new Runnable() { - * public void run() { - * editorComp.requestFocus(); - * } - * }); - * } - * } - */ - } else if (Objects.equals(key, CANCEL_EDITING)) { - table.removeEditor(); - } else if (Objects.equals(key, SELECT_ALL)) { - table.selectAll(); - } else if (Objects.equals(key, CLEAR_SELECTION)) { - table.clearSelection(); - } else if (Objects.equals(key, START_EDITING)) { - if (!table.hasFocus()) { - CellEditor cellEditor = table.getCellEditor(); - if (cellEditor != null && !cellEditor.stopCellEditing()) { - return; - } - table.requestFocus(); - return; - } - table.editCellAt(leadRow, leadColumn, e); - Component editorComp = table.getEditorComponent(); - if (editorComp != null) { - editorComp.requestFocus(); - } - } else if (Objects.equals(key, ADD_TO_SELECTION)) { - if (!table.isCellSelected(leadRow, leadColumn)) { - int oldAnchorRow = rsm.getAnchorSelectionIndex(); - int oldAnchorColumn = csm.getAnchorSelectionIndex(); - rsm.setValueIsAdjusting(true); - csm.setValueIsAdjusting(true); - table.changeSelection(leadRow, leadColumn, true, false); - rsm.setAnchorSelectionIndex(oldAnchorRow); - csm.setAnchorSelectionIndex(oldAnchorColumn); - rsm.setValueIsAdjusting(false); - csm.setValueIsAdjusting(false); - } - } else if (Objects.equals(key, TOGGLE_AND_ANCHOR)) { - table.changeSelection(leadRow, leadColumn, true, false); - } else if (Objects.equals(key, EXTEND_TO)) { - table.changeSelection(leadRow, leadColumn, false, true); - } else if (Objects.equals(key, MOVE_SELECTION_TO)) { - table.changeSelection(leadRow, leadColumn, false, false); - } else if (Objects.equals(key, FOCUS_HEADER)) { - JTableHeader th = table.getTableHeader(); - if (th != null) { - // Set the header's selected column to match the table. - int col = table.getSelectedColumn(); - if (col >= 0) { - TableHeaderUI thUI = th.getUI(); - if (thUI instanceof DarkTableHeaderUI) { - ((DarkTableHeaderUI) thUI).selectColumn(col); - } - } - - // Then give the header the focus. - th.requestFocusInWindow(); - } - } - } - - /** - * Move within table range. - * - * @param table the table - * @param dx the dx - * @param dy the dy - */ - protected void moveWithinTableRange(final JTable table, final int dx, final int dy) { - leadRow = clipToRange(leadRow + dy, 0, table.getRowCount()); - leadColumn = clipToRange(leadColumn + dx, 0, table.getColumnCount()); - } - - /** - * Clip to range int. - * - * @param i the - * @param a the a - * @param b the b - * @return the int - */ - protected static int clipToRange(final int i, final int a, final int b) { - return Math.min(Math.max(i, a), b - 1); - } - - /** - * Called to move within the selected range of the given JTable. This method uses the table's notion of - * selection, which is important to allow the user to navigate between items visually selected on screen. This - * notion may or may not be the same as what could be determined by directly querying the selection models. It - * depends on certain table properties (such as whether or not row or column selection is allowed). When - * performing modifications, it is recommended that caution be taken in order to preserve the intent of this - * method, especially when deciding whether to query the selection models or interact with JTable directly. - * - * @param table the table - * @param dx the dx - * @param dy the dy - * @param rsm the rsm - * @param csm the csm - * @return the boolean - */ - protected boolean moveWithinSelectedRange(final JTable table, final int dx, final int dy, - final ListSelectionModel rsm, final ListSelectionModel csm) { - - // Note: The Actions constructor ensures that only one of - // dx and dy is 0, and the other is either -1 or 1 - - // find out how many items the table is showing as selected - // and the range of items to navigate through - int totalCount; - int minX, maxX, minY, maxY; - - boolean rs = table.getRowSelectionAllowed(); - boolean cs = table.getColumnSelectionAllowed(); - - // both column and row selection - if (rs && cs) { - totalCount = table.getSelectedRowCount() * table.getSelectedColumnCount(); - minX = csm.getMinSelectionIndex(); - maxX = csm.getMaxSelectionIndex(); - minY = rsm.getMinSelectionIndex(); - maxY = rsm.getMaxSelectionIndex(); - // row selection only - } else if (rs) { - totalCount = table.getSelectedRowCount(); - minX = 0; - maxX = table.getColumnCount() - 1; - minY = rsm.getMinSelectionIndex(); - maxY = rsm.getMaxSelectionIndex(); - // column selection only - } else if (cs) { - totalCount = table.getSelectedColumnCount(); - minX = csm.getMinSelectionIndex(); - maxX = csm.getMaxSelectionIndex(); - minY = 0; - maxY = table.getRowCount() - 1; - // no selection allowed - } else { - totalCount = 0; - // A bogus assignment to stop javac from complaining - // about unitialized values. In this case, these - // won't even be used. - minX = maxX = minY = maxY = 0; - } - - // For some cases, there is no point in trying to stay within the - // selected area. Instead, move outside the selection, wrapping at - // the table boundaries. The cases are: - boolean stayInSelection; - - // - nothing selected - if (totalCount == 0 || - // - one item selected, and the lead is already selected - (totalCount == 1 && table.isCellSelected(leadRow, leadColumn))) { - - stayInSelection = false; - - maxX = table.getColumnCount() - 1; - maxY = table.getRowCount() - 1; - - // the mins are calculated like this in case the max is -1 - minX = Math.min(0, maxX); - minY = Math.min(0, maxY); - } else { - stayInSelection = true; - } - - // the algorithm below isn't prepared to deal with -1 lead/anchor - // so massage appropriately here first - if (dy == 1 && leadColumn == -1) { - leadColumn = minX; - leadRow = -1; - } else if (dx == 1 && leadRow == -1) { - leadRow = minY; - leadColumn = -1; - } else if (dy == -1 && leadColumn == -1) { - leadColumn = maxX; - leadRow = maxY + 1; - } else if (dx == -1 && leadRow == -1) { - leadRow = maxY; - leadColumn = maxX + 1; - } - - // In cases where the lead is not within the search range, - // we need to bring it within one cell for the search - // to work properly. Check these here. - leadRow = Math.min(Math.max(leadRow, minY - 1), maxY + 1); - leadColumn = Math.min(Math.max(leadColumn, minX - 1), maxX + 1); - - // find the next position, possibly looping until it is selected - do { - calcNextPos(dx, minX, maxX, dy, minY, maxY); - } while (stayInSelection && !table.isCellSelected(leadRow, leadColumn)); - - return stayInSelection; - } - - /** - * Find the next lead row and column based on the given dx/dy and max/min values. - * - * @param dx the dx - * @param minX the min x - * @param maxX the max x - * @param dy the dy - * @param minY the min y - * @param maxY the max y - */ - protected void calcNextPos(final int dx, final int minX, final int maxX, - final int dy, final int minY, final int maxY) { - - if (dx != 0) { - leadColumn += dx; - if (leadColumn > maxX) { - leadColumn = minX; - leadRow++; - if (leadRow > maxY) { - leadRow = minY; - } - } else if (leadColumn < minX) { - leadColumn = maxX; - leadRow--; - if (leadRow < minY) { - leadRow = maxY; - } - } - } else { - leadRow += dy; - if (leadRow > maxY) { - leadRow = minY; - leadColumn++; - if (leadColumn > maxX) { - leadColumn = minX; - } - } else if (leadRow < minY) { - leadRow = maxY; - leadColumn--; - if (leadColumn < minX) { - leadColumn = maxX; - } - } - } - } - - /** - * Accept boolean. - * - * @param sender the sender - * @return the boolean - */ - public boolean accept(final Object sender) { - String key = getName(); - - if (sender instanceof JTable - && PropertyUtil.getBooleanProperty((JTable) sender, DarkTableUI.KEY_IS_FILE_LIST)) { - if (Objects.equals(key, NEXT_COLUMN) || - Objects.equals(key, NEXT_COLUMN_CELL) || - Objects.equals(key, NEXT_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, NEXT_COLUMN_CHANGE_LEAD) || - Objects.equals(key, PREVIOUS_COLUMN) || - Objects.equals(key, PREVIOUS_COLUMN_CELL) || - Objects.equals(key, PREVIOUS_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, PREVIOUS_COLUMN_CHANGE_LEAD) || - Objects.equals(key, SCROLL_LEFT_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_LEFT_EXTEND_SELECTION) || - Objects.equals(key, SCROLL_RIGHT_CHANGE_SELECTION) || - Objects.equals(key, SCROLL_RIGHT_EXTEND_SELECTION) || - Objects.equals(key, FIRST_COLUMN) || - Objects.equals(key, FIRST_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, LAST_COLUMN) || - Objects.equals(key, LAST_COLUMN_EXTEND_SELECTION) || - Objects.equals(key, NEXT_ROW_CELL) || - Objects.equals(key, PREVIOUS_ROW_CELL)) { - - return false; - } - } - - if (Objects.equals(key, CANCEL_EDITING) && sender instanceof JTable) { - return ((JTable) sender).isEditing(); - } else if (Objects.equals(key, NEXT_ROW_CHANGE_LEAD) || - Objects.equals(key, PREVIOUS_ROW_CHANGE_LEAD)) { - // discontinuous selection actions are only enabled for - // DefaultListSelectionModel - return sender != null && - ((JTable) sender).getSelectionModel() instanceof DefaultListSelectionModel; - } else if (Objects.equals(key, NEXT_COLUMN_CHANGE_LEAD) || - Objects.equals(key, PREVIOUS_COLUMN_CHANGE_LEAD)) { - // discontinuous selection actions are only enabled for - // DefaultListSelectionModel - return sender != null && - ((JTable) sender).getColumnModel().getSelectionModel() instanceof DefaultListSelectionModel; - } else if (Objects.equals(key, ADD_TO_SELECTION) && sender instanceof JTable) { - // This action is typically bound to SPACE. - // If the table is already in an editing mode, SPACE should - // simply enter a space character into the table, and not - // select a cell. Likewise, if the lead cell is already selected - // then hitting SPACE should just enter a space character - // into the cell and begin editing. In both of these cases - // this action will be disabled. - JTable table = (JTable) sender; - int leadRow = getAdjustedLead(table, true); - int leadCol = getAdjustedLead(table, false); - return !(table.isEditing() || table.isCellSelected(leadRow, leadCol)); - } else if (Objects.equals(key, FOCUS_HEADER) && sender instanceof JTable) { - JTable table = (JTable) sender; - return table.getTableHeader() != null; - } - - return true; - } - } - - /** - * The type Table transfer handler. - */ - @SuppressWarnings("serial") // JDK-implementation class - static class TableTransferHandler extends TransferHandler implements UIResource { - - public int getSourceActions(final JComponent c) { - return COPY; - } - - /** - * Create a Transferable to use as the source for a data transfer. - * - * @param c The component holding the data to be transfered. This argument is provided to enable sharing of - * TransferHandlers by multiple components. - * @return The representation of the data to be transfered. - */ - protected Transferable createTransferable(final JComponent c) { - if (c instanceof JTable) { - JTable table = (JTable) c; - int[] rows; - int[] cols; - - if (!table.getRowSelectionAllowed() && !table.getColumnSelectionAllowed()) { - return null; - } - - if (!table.getRowSelectionAllowed()) { - int rowCount = table.getRowCount(); - - rows = new int[rowCount]; - for (int counter = 0; counter < rowCount; counter++) { - rows[counter] = counter; - } - } else { - rows = table.getSelectedRows(); - } - - if (!table.getColumnSelectionAllowed()) { - int colCount = table.getColumnCount(); - - cols = new int[colCount]; - for (int counter = 0; counter < colCount; counter++) { - cols[counter] = counter; - } - } else { - cols = table.getSelectedColumns(); - } - - if (rows == null || cols == null || rows.length == 0 || cols.length == 0) { - return null; - } - - StringBuilder plainStr = new StringBuilder(); - StringBuilder htmlStr = new StringBuilder(); - - htmlStr.append("\n\n\n"); - - for (int value : rows) { - htmlStr.append("\n"); - for (int i : cols) { - Object obj = table.getValueAt(value, i); - String val = ((obj == null) ? "" : obj.toString()); - plainStr.append(val).append('\t'); - htmlStr.append(" \n"); - } - // we want a newline at the end of each line and not a tab - plainStr.deleteCharAt(plainStr.length() - 1).append('\n'); - htmlStr.append("\n"); - } - - // remove the last newline - plainStr.deleteCharAt(plainStr.length() - 1); - htmlStr.append("
").append(val).append("
\n\n"); - - return new BasicTransferable(plainStr.toString(), htmlStr.toString()); - } - - return null; - } - } - - /** - * This class should be treated as a "protected" inner class. Instantiate it only within subclasses of - * {@code BasicTableUI}. - *

- * As of Java 2 platform v1.3 this class is no longer used. - * Instead JTable overrides processKeyBinding to dispatch the event to the current - * TableCellEditor. - */ - public class KeyHandler implements KeyListener { - public void keyTyped(final KeyEvent e) { - getHandler().keyTyped(e); - } - - // NOTE: This class exists only for backward compatibility. All - // its functionality has been moved into Handler. If you need to add - // new functionality add it to the Handler, but make sure this - // class calls into the Handler. - public void keyPressed(final KeyEvent e) { - getHandler().keyPressed(e); - } - - public void keyReleased(final KeyEvent e) { - getHandler().keyReleased(e); - } - } - - /** - * This class should be treated as a "protected" inner class. Instantiate it only within subclasses of - * {@code BasicTableUI}. - */ - public class FocusHandler implements FocusListener { - // NOTE: This class exists only for backward compatibility. All - // its functionality has been moved into Handler. If you need to add - // new functionality add it to the Handler, but make sure this - // class calls into the Handler. - public void focusGained(final FocusEvent e) { - getHandler().focusGained(e); - } - - public void focusLost(final FocusEvent e) { - getHandler().focusLost(e); - } - } - - /** - * This class should be treated as a "protected" inner class. Instantiate it only within subclasses of - * BasicTableUI. - */ - public class MouseInputHandler implements MouseInputListener { - // NOTE: This class exists only for backward compatibility. All - // its functionality has been moved into Handler. If you need to add - // new functionality add it to the Handler, but make sure this - // class calls into the Handler. - public void mouseClicked(final MouseEvent e) { - getHandler().mouseClicked(e); - } - - public void mousePressed(final MouseEvent e) { - getHandler().mousePressed(e); - } - - public void mouseReleased(final MouseEvent e) { - getHandler().mouseReleased(e); - } - - public void mouseEntered(final MouseEvent e) { - getHandler().mouseEntered(e); - } - - public void mouseExited(final MouseEvent e) { - getHandler().mouseExited(e); - } - - public void mouseDragged(final MouseEvent e) { - getHandler().mouseDragged(e); - } - - public void mouseMoved(final MouseEvent e) { - getHandler().mouseMoved(e); - } - } - /** * The type Handler. */ diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderBorder.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderBorder.java similarity index 97% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderBorder.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderBorder.java index 4966d602..a8b22d54 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderBorder.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderBorder.java @@ -20,9 +20,8 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.header; import java.awt.*; diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderCorner.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderCorner.java similarity index 97% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderCorner.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderCorner.java index 7208182b..dd277cb6 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderCorner.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderCorner.java @@ -20,9 +20,8 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.header; import java.awt.*; diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderRenderer.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderRenderer.java new file mode 100644 index 00000000..d3bfb2b4 --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderRenderer.java @@ -0,0 +1,47 @@ +/* + * 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.ui.table.header; + +import java.awt.*; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; + +public class DarkTableHeaderRenderer implements TableCellRenderer { + + private final TableCellRenderer renderer; + + public DarkTableHeaderRenderer(final TableCellRenderer renderer) { + this.renderer = renderer; + } + + @Override + public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, + final boolean hasFocus, final int row, final int column) { + Component c = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + c.setEnabled(table.isEnabled()); + return c; + } +} diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderRendererPane.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderRendererPane.java new file mode 100644 index 00000000..c62f642e --- /dev/null +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderRendererPane.java @@ -0,0 +1,31 @@ +/* + * 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.ui.table.header; + +import com.github.weisj.darklaf.ui.cell.DarkCellRendererPane; + +public class DarkTableHeaderRendererPane extends DarkCellRendererPane { + +} diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderUI.java similarity index 51% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderUI.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderUI.java index 4f4ce2b1..4603d099 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableHeaderUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/header/DarkTableHeaderUI.java @@ -20,28 +20,26 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.header; import java.awt.*; import javax.swing.*; import javax.swing.plaf.ComponentUI; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; +import javax.swing.plaf.basic.BasicTableHeaderUI; +import javax.swing.table.*; import com.github.weisj.darklaf.graphics.GraphicsContext; +import com.github.weisj.darklaf.ui.table.DarkTableScrollPaneBorder; +import com.github.weisj.darklaf.ui.table.DarkTableUI; import com.github.weisj.darklaf.util.DarkUIUtil; /** * @author Jannis Weis */ -public class DarkTableHeaderUI extends DarkTableHeaderUIBridge { +public class DarkTableHeaderUI extends BasicTableHeaderUI { - public static final String KEY_IS_HEADER_RENDERER = "JComponent.isHeaderRenderer"; private static final int HEADER_HEIGHT = 26; protected Color borderColor; protected Color background; @@ -52,7 +50,22 @@ public class DarkTableHeaderUI extends DarkTableHeaderUIBridge { @Override public void installUI(final JComponent c) { - super.installUI(c); + header = (JTableHeader) c; + + rendererPane = createCellRendererPane(); + header.add(rendererPane); + + installDefaults(); + installListeners(); + installKeyboardActions(); + } + + @Override + protected void installDefaults() { + super.installDefaults(); + background = UIManager.getColor("TableHeader.background"); + borderColor = UIManager.getColor("TableHeader.borderColor"); + LookAndFeel.installBorder(header, "TableHeader.border"); Dimension dim = header.getPreferredSize(); int headerHeight = UIManager.getInt("TableHeader.height"); if (headerHeight < 0) { @@ -60,18 +73,19 @@ public class DarkTableHeaderUI extends DarkTableHeaderUIBridge { } header.setPreferredSize(new Dimension(dim.width, Math.max(dim.height, headerHeight))); TableCellRenderer defaultRenderer = header.getDefaultRenderer(); + if (defaultRenderer != null + && defaultRenderer.getClass().getName().equals("sun.swing.table.DefaultTableCellHeaderRenderer")) { + defaultRenderer = new DarkTableHeaderRenderer(defaultRenderer); + header.setDefaultRenderer(defaultRenderer); + } if (defaultRenderer instanceof DefaultTableCellRenderer) { - DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) header.getDefaultRenderer(); + DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) defaultRenderer; renderer.setHorizontalAlignment(SwingConstants.LEADING); } } - @Override - protected void installDefaults() { - super.installDefaults(); - background = UIManager.getColor("TableHeader.background"); - borderColor = UIManager.getColor("TableHeader.borderColor"); - LookAndFeel.installBorder(header, "TableHeader.border"); + protected CellRendererPane createCellRendererPane() { + return new DarkTableHeaderRendererPane(); } @Override @@ -118,83 +132,71 @@ public class DarkTableHeaderUI extends DarkTableHeaderUIBridge { g.setColor(borderColor); TableColumn draggedColumn = header.getDraggedColumn(); - int columnWidth; Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax); - TableColumn aColumn; + paintCells(g, h, ltr, cm, cMin, cMax, borderColor, draggedColumn, cellRect); + + // Paint the dragged column if we are dragging. + if (draggedColumn != null) { + paintDraggedArea(g, ltr, cMin, cMax, borderColor, draggedColumn); + } + + // Remove all components in the rendererPane. + rendererPane.removeAll(); + config.restore(); + } + + public void paintCells(final Graphics2D g, final int h, final boolean ltr, + final TableColumnModel cm, + final int cMin, final int cMax, final Color borderColor, + final TableColumn draggedColumn, final Rectangle cellRect) { if (ltr) { for (int column = cMin; column <= cMax; column++) { - aColumn = cm.getColumn(column); - columnWidth = aColumn.getWidth(); - cellRect.width = columnWidth; - if (aColumn != draggedColumn) { - paintCell(g, cellRect, column); - } - cellRect.x += columnWidth; - if (column != cMax) { - g.setColor(borderColor); - g.fillRect(cellRect.x - 1, 0, 1, h); - } + paintSingleCell(g, h, cm, cMax, borderColor, draggedColumn, cellRect, column); } } else { for (int column = cMax; column >= cMin; column--) { - aColumn = cm.getColumn(column); - columnWidth = aColumn.getWidth(); - cellRect.width = columnWidth; - if (aColumn != draggedColumn) { - paintCell(g, cellRect, column); - } - cellRect.x += columnWidth; - if (column != cMin) { - g.setColor(borderColor); - g.fillRect(cellRect.x - 1, 0, 1, h); - } + paintSingleCell(g, h, cm, cMin, borderColor, draggedColumn, cellRect, column); } } + } - // Paint the dragged column if we are dragging. - if (draggedColumn != null) { - int draggedColumnIndex = viewIndexForColumn(draggedColumn); - boolean scrollPaneRtl = isScrollPaneRtl(); - Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); - int dist = DarkTableUI.adjustDistance(header.getDraggedDistance(), draggedCellRect, header.getTable()); - // Draw a gray well in place of the moving column. - g.setColor(header.getParent().getBackground()); - g.fillRect(draggedCellRect.x, draggedCellRect.y, - draggedCellRect.width, draggedCellRect.height); + public void paintSingleCell(final Graphics2D g, final int h, final TableColumnModel cm, + final int cMax, final Color borderColor, + final TableColumn draggedColumn, + final Rectangle cellRect, final int column) { + TableColumn aColumn; + int columnWidth; + aColumn = cm.getColumn(column); + columnWidth = aColumn.getWidth(); + cellRect.width = columnWidth; + if (aColumn != draggedColumn) { + paintCell(g, cellRect, column); + } + cellRect.x += columnWidth; + if (column != cMax) { g.setColor(borderColor); - if (scrollBarVisible()) { - if (ltr) { - if (!scrollPaneRtl) { - g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, - 1, draggedCellRect.height); - } else { - if (draggedColumnIndex != cMax) { - g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, - 1, draggedCellRect.height); - } else { - g.fillRect(draggedCellRect.x + draggedCellRect.width, draggedCellRect.y, - 1, draggedCellRect.height); - } - if (draggedColumnIndex == cMin) { - g.fillRect(draggedCellRect.x, draggedCellRect.y, 1, draggedCellRect.height); - } - } + g.fillRect(cellRect.x - 1, 0, 1, h); + } + } + + public void paintDraggedArea(final Graphics2D g, final boolean ltr, + final int cMin, final int cMax, + final Color borderColor, final TableColumn draggedColumn) { + int draggedColumnIndex = viewIndexForColumn(draggedColumn); + boolean scrollPaneRtl = isScrollPaneRtl(); + Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); + int dist = DarkTableUI.adjustDistance(header.getDraggedDistance(), draggedCellRect, header.getTable()); + // Draw a gray well in place of the moving column. + g.setColor(header.getParent().getBackground()); + g.fillRect(draggedCellRect.x, draggedCellRect.y, + draggedCellRect.width, draggedCellRect.height); + g.setColor(borderColor); + if (scrollBarVisible()) { + if (ltr) { + if (!scrollPaneRtl) { + g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, + 1, draggedCellRect.height); } else { - if (!scrollPaneRtl) { - g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, - 1, draggedCellRect.height); - } else { - if (draggedColumnIndex != cMin) { - g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, - 1, draggedCellRect.height); - } - if (draggedColumnIndex == cMax) { - g.fillRect(draggedCellRect.x, draggedCellRect.y, 1, draggedCellRect.height); - } - } - } - } else { - if (ltr) { if (draggedColumnIndex != cMax) { g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, 1, draggedCellRect.height); @@ -202,46 +204,66 @@ public class DarkTableHeaderUI extends DarkTableHeaderUIBridge { g.fillRect(draggedCellRect.x + draggedCellRect.width, draggedCellRect.y, 1, draggedCellRect.height); } + if (draggedColumnIndex == cMin) { + g.fillRect(draggedCellRect.x, draggedCellRect.y, 1, draggedCellRect.height); + } + } + } else { + if (!scrollPaneRtl) { + g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, + 1, draggedCellRect.height); } else { if (draggedColumnIndex != cMin) { g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, 1, draggedCellRect.height); } + if (draggedColumnIndex == cMax) { + g.fillRect(draggedCellRect.x, draggedCellRect.y, 1, draggedCellRect.height); + } + } + } + } else { + if (ltr) { + if (draggedColumnIndex != cMax) { + g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, + 1, draggedCellRect.height); + } else { + g.fillRect(draggedCellRect.x + draggedCellRect.width, draggedCellRect.y, + 1, draggedCellRect.height); + } + } else { + if (draggedColumnIndex != cMin) { + g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, + 1, draggedCellRect.height); } } + } - draggedCellRect.x += dist; + draggedCellRect.x += dist; - // Fill the background. - g.setColor(header.getBackground()); - g.fillRect(draggedCellRect.x, draggedCellRect.y, - draggedCellRect.width, draggedCellRect.height); - paintCell(g, draggedCellRect, draggedColumnIndex); + // Fill the background. + g.setColor(header.getBackground()); + g.fillRect(draggedCellRect.x, draggedCellRect.y, + draggedCellRect.width, draggedCellRect.height); + paintCell(g, draggedCellRect, draggedColumnIndex); - g.setColor(borderColor); + g.setColor(borderColor); - boolean onLeftEdge = ltr ? draggedColumnIndex == cMin : draggedColumnIndex == cMax; - boolean onRightEdge = ltr ? draggedColumnIndex == cMax : draggedColumnIndex == cMin; - // left - if (dist != 0 || !onLeftEdge) { - g.fillRect(draggedCellRect.x - 1, draggedCellRect.y, 1, draggedCellRect.height); - } - // right - if (dist != 0 || !onRightEdge) { - g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, - 1, draggedCellRect.height); - } + boolean onLeftEdge = ltr ? draggedColumnIndex == cMin : draggedColumnIndex == cMax; + boolean onRightEdge = ltr ? draggedColumnIndex == cMax : draggedColumnIndex == cMin; + // left + if (dist != 0 || !onLeftEdge) { + g.fillRect(draggedCellRect.x - 1, draggedCellRect.y, 1, draggedCellRect.height); + } + // right + if (dist != 0 || !onRightEdge) { + g.fillRect(draggedCellRect.x + draggedCellRect.width - 1, draggedCellRect.y, + 1, draggedCellRect.height); } - - // Remove all components in the rendererPane. - rendererPane.removeAll(); - config.restore(); } - @Override protected void paintCell(final Graphics g, final Rectangle cellRect, final int columnIndex) { - Component component = getHeaderRenderer(columnIndex); - if (component instanceof JComponent) ((JComponent) component).putClientProperty(KEY_IS_HEADER_RENDERER, true); + Component component = getHeaderCellRenderer(columnIndex); rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } @@ -275,4 +297,28 @@ public class DarkTableHeaderUI extends DarkTableHeaderUIBridge { } return comp instanceof JScrollPane; } + + protected int viewIndexForColumn(final TableColumn aColumn) { + TableColumnModel cm = header.getColumnModel(); + for (int column = 0; column < cm.getColumnCount(); column++) { + if (cm.getColumn(column) == aColumn) { + return column; + } + } + return -1; + } + + protected Component getHeaderCellRenderer(final int columnIndex) { + TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); + TableCellRenderer renderer = aColumn.getHeaderRenderer(); + if (renderer == null) { + renderer = header.getDefaultRenderer(); + } + + boolean hasFocus = !header.isPaintingForPrint() && header.hasFocus(); + return renderer.getTableCellRendererComponent(header.getTable(), + aColumn.getHeaderValue(), + false, hasFocus, + -1, columnIndex); + } } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkColorTableCellRendererEditor.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkColorTableCellRendererEditor.java similarity index 98% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkColorTableCellRendererEditor.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkColorTableCellRendererEditor.java index 6be22f00..e6fba0e2 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkColorTableCellRendererEditor.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkColorTableCellRendererEditor.java @@ -20,9 +20,8 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.renderer; import java.awt.*; import java.awt.event.MouseEvent; diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellEditor.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditor.java similarity index 98% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellEditor.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditor.java index 3f5c2f25..039322bf 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellEditor.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditor.java @@ -20,9 +20,8 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.renderer; import java.awt.*; import java.awt.event.KeyEvent; @@ -44,6 +43,8 @@ import com.github.weisj.darklaf.ui.combobox.ComboBoxConstants; import com.github.weisj.darklaf.ui.combobox.DarkComboBoxUI; import com.github.weisj.darklaf.ui.spinner.DarkSpinnerUI; import com.github.weisj.darklaf.ui.spinner.SpinnerConstants; +import com.github.weisj.darklaf.ui.table.DarkTableUI; +import com.github.weisj.darklaf.ui.table.TextTableCellEditorBorder; import com.github.weisj.darklaf.ui.text.DarkTextUI; import com.github.weisj.darklaf.ui.togglebutton.ToggleButtonConstants; import com.github.weisj.darklaf.util.PropertyUtil; @@ -241,9 +242,7 @@ public class DarkTableCellEditor extends DefaultCellEditor { setupEditorComponent(value, rendererComp); comp = applyRendererIcon(comp, rendererComp); - CellUtil.setupBackground(comp, table, false, row, DarkTableUI.KEY_ALTERNATE_ROW_COLOR, - "Table.alternateRowBackground", - "Table.selectionNoFocusBackground"); + CellUtil.setupTableBackground(comp, table, false, row); return comp; } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellEditorToggleButton.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorToggleButton.java similarity index 89% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellEditorToggleButton.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorToggleButton.java index 5aaeea47..de7311e5 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellEditorToggleButton.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellEditorToggleButton.java @@ -20,9 +20,8 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.renderer; import java.awt.*; import java.util.EventObject; @@ -31,6 +30,8 @@ import javax.swing.*; import javax.swing.table.TableCellEditor; import com.github.weisj.darklaf.ui.cell.CellUtil; +import com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder; +import com.github.weisj.darklaf.ui.table.DarkTableUI; import com.github.weisj.darklaf.util.DarkUIUtil; /** @@ -61,9 +62,8 @@ public class DarkTableCellEditorToggleButton extends AbstractCellEditor implemen && !DarkTableCellFocusBorder.isRowFocusBorder(table); boolean paintSelected = isSelected && !isLeadSelectionCell && !table.isEditing(); - CellUtil.setupForeground(toggleButton, table, paintSelected, "Table.selectionForegroundInactive"); - CellUtil.setupBackground(toggleButton, table, paintSelected, row, DarkTableUI.KEY_ALTERNATE_ROW_COLOR, - "Table.alternateRowBackground", "Table.selectionNoFocusBackground"); + CellUtil.setupTableForeground(toggleButton, table, paintSelected); + CellUtil.setupTableBackground(toggleButton, table, paintSelected, row); return toggleButton; } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellRenderer.java b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellRenderer.java similarity index 93% rename from core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellRenderer.java rename to core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellRenderer.java index ad7f44c9..26f14ffc 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/table/DarkTableCellRenderer.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/table/renderer/DarkTableCellRenderer.java @@ -20,9 +20,8 @@ * 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.ui.table; +package com.github.weisj.darklaf.ui.table.renderer; import java.awt.*; @@ -34,6 +33,8 @@ import javax.swing.table.TableColumn; import com.github.weisj.darklaf.ui.cell.CellUtil; import com.github.weisj.darklaf.ui.cell.DarkCellRendererToggleButton; +import com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder; +import com.github.weisj.darklaf.ui.table.DarkTableUI; import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.util.PropertyUtil; @@ -69,11 +70,10 @@ public class DarkTableCellRenderer extends DefaultTableCellRenderer { boolean isLeadSelectionCell = DarkUIUtil.hasFocus(table) && hasFocus && !isRowFocus; boolean paintSelected = isSelected && !isLeadSelectionCell && !table.isEditing(); + setupBorderStyle(table, row, column, component, isRowFocus); - CellUtil.setupForeground(component, table, paintSelected, "Table.selectionForegroundInactive"); - CellUtil.setupBackground(component, table, paintSelected, row, - DarkTableUI.KEY_ALTERNATE_ROW_COLOR, "Table.alternateRowBackground", - "Table.selectionNoFocusBackground"); + CellUtil.setupTableForeground(component, table, paintSelected); + CellUtil.setupTableBackground(component, table, paintSelected, row); return component; } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/text/DarkTextUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/text/DarkTextUI.java index 393c72e1..925076f5 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/text/DarkTextUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/text/DarkTextUI.java @@ -205,7 +205,9 @@ public abstract class DarkTextUI extends BasicTextUI implements PropertyChangeLi } if (editor.isOpaque()) { - if (DarkUIUtil.isInCell(editor)) { + if (DarkUIUtil.isInCell(editor) + || PropertyUtil.getBooleanProperty(editor, KEY_IS_TREE_EDITOR) + || PropertyUtil.getBooleanProperty(editor, KEY_IS_TABLE_EDITOR)) { g.setColor(getBackground(editor)); g.fillRect(0, 0, editor.getWidth(), editor.getHeight()); } else if (parent != null && parent.isOpaque()) { diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellEditor.java b/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellEditor.java index 90c25cc4..2f7f8336 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellEditor.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellEditor.java @@ -39,11 +39,11 @@ import javax.swing.event.PopupMenuListener; import javax.swing.tree.TreeCellEditor; import com.github.weisj.darklaf.components.SelectableTreeNode; +import com.github.weisj.darklaf.ui.cell.CellUtil; import com.github.weisj.darklaf.ui.combobox.ComboBoxConstants; import com.github.weisj.darklaf.ui.spinner.SpinnerConstants; import com.github.weisj.darklaf.ui.text.DarkTextUI; import com.github.weisj.darklaf.ui.togglebutton.ToggleButtonConstants; -import com.github.weisj.darklaf.util.DarkUIUtil; /** * @author Jannis Weis @@ -166,22 +166,15 @@ public class DarkTreeCellEditor extends DefaultCellEditor implements TreeCellEdi ((JToggleButton) editorComponent).setSelected(!(((JToggleButton) editorComponent).isSelected())); SwingUtilities.invokeLater(tree::stopEditing); } - editorComponent.setOpaque(false); + editorComponent.setOpaque(true); editorComponent.setComponentOrientation(tree.getComponentOrientation()); - if (DarkUIUtil.hasFocus(tree) || DarkUIUtil.hasFocus(editorComponent)) { - editorComponent.setForeground(UIManager.getColor("Tree.selectionForeground")); - } else { - editorComponent.setForeground(UIManager.getColor("Tree.selectionForegroundInactive")); - } + CellUtil.setupTreeBackground(editorComponent, tree, false, row); + CellUtil.setupTreeForeground(editorComponent, tree, false); return editorComponent; } protected void updateFocus(final FocusEvent e) { - if (DarkUIUtil.hasFocus(editorComponent, e)) { - editorComponent.setForeground(UIManager.getColor("Tree.selectionForeground")); - } else { - editorComponent.setForeground(UIManager.getColor("Tree.selectionForegroundInactive")); - } + CellUtil.setupTreeForeground(editorComponent, tree, false); } @Override diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellRenderer.java b/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellRenderer.java index 3187acc2..f7feb62c 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellRenderer.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeCellRenderer.java @@ -74,11 +74,17 @@ public class DarkTreeCellRenderer extends DefaultTreeCellRenderer implements Tre } Component comp; if (parent != null) { + if (parent instanceof JLabel) { + ((JLabel) parent).setIcon(null); + ((JLabel) parent).setDisabledIcon(null); + } comp = parent.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, isFocused); } else { + setIcon(null); + setDisabledIcon(null); comp = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, isFocused); } - CellUtil.setupForeground(comp, tree, sel, getTextSelectionColor(), "Tree.selectionForegroundInactive"); + CellUtil.setupTreeForeground(comp, tree, sel); return comp; } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeUI.java index 7466fb8d..e735f46d 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/tree/DarkTreeUI.java @@ -39,6 +39,8 @@ import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; +import com.github.weisj.darklaf.ui.cell.CellUtil; +import com.github.weisj.darklaf.ui.cell.DarkCellRendererPane; import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.util.PropertyUtil; import com.github.weisj.darklaf.util.SystemInfo; @@ -50,7 +52,6 @@ import com.github.weisj.darklaf.util.SystemInfo; public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { protected static final String KEY_PREFIX = "JTree."; - public static final String KEY_TREE_TABLE_TREE = KEY_PREFIX + "treeTableTree"; public static final String KEY_ALTERNATE_ROW_COLOR = KEY_PREFIX + "alternateRowColor"; public static final String KEY_RENDER_BOOLEAN_AS_CHECKBOX = KEY_PREFIX + "renderBooleanAsCheckBox"; public static final String KEY_BOOLEAN_RENDER_TYPE = KEY_PREFIX + "booleanRenderType"; @@ -107,12 +108,9 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { } } }; - protected Color alternativeBackground; protected Color lineColor; protected Color focusSelectedLineColor; protected Color selectedLineColor; - protected Color selectionBackground; - protected Color focusSelectionBackground; protected Icon expandedFocusSelected; protected Icon expandedSelected; protected Icon expandedFocus; @@ -121,7 +119,7 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { protected Icon collapsedSelected; protected Icon collapsedFocus; protected Icon collapsed; - private boolean myOldRepaintAllRowValue; + private boolean oldRepaintAllRowValue; public static ComponentUI createUI(final JComponent c) { return new DarkTreeUI(); @@ -144,7 +142,7 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { @Override protected void completeUIInstall() { super.completeUIInstall(); - myOldRepaintAllRowValue = UIManager.getBoolean("Tree.repaintWholeRow"); + oldRepaintAllRowValue = UIManager.getBoolean("Tree.repaintWholeRow"); UIManager.put("Tree.repaintWholeRow", true); tree.putClientProperty(DarkTreeUI.KEY_ALTERNATE_ROW_COLOR, UIManager.getBoolean("Tree.alternateRowColor")); @@ -153,13 +151,11 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { @Override protected void installDefaults() { super.installDefaults(); + rendererPane = createCellRendererPane(); LookAndFeel.installColors(tree, "Tree.background", "Tree.foreground"); - selectionBackground = UIManager.getColor("Tree.unfocusedSelectionBackground"); - focusSelectionBackground = UIManager.getColor("Tree.selectionBackground"); focusSelectedLineColor = UIManager.getColor("Tree.lineFocusSelected"); selectedLineColor = UIManager.getColor("Tree.lineSelected"); lineColor = UIManager.getColor("Tree.lineUnselected"); - alternativeBackground = UIManager.getColor("Tree.alternateRowBackground"); expandedFocusSelected = UIManager.getIcon("Tree.expanded.selected.focused.icon"); expandedSelected = UIManager.getIcon("Tree.expanded.selected.unfocused.icon"); expandedFocus = UIManager.getIcon("Tree.expanded.unselected.focused.icon"); @@ -174,6 +170,10 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { LookAndFeel.installProperty(tree, JTree.SHOWS_ROOT_HANDLES_PROPERTY, true); } + protected CellRendererPane createCellRendererPane() { + return new DarkCellRendererPane(); + } + @Override protected void installListeners() { super.installListeners(); @@ -361,7 +361,7 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { @Override protected void uninstallDefaults() { super.uninstallDefaults(); - UIManager.put("Tree.repaintWholeRow", myOldRepaintAllRowValue); + UIManager.put("Tree.repaintWholeRow", oldRepaintAllRowValue); } @Override @@ -523,7 +523,7 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { Graphics2D rowGraphics = (Graphics2D) g.create(); rowGraphics.setClip(clipBounds); - rowGraphics.setColor(getRowBackground(row, selected)); + rowGraphics.setColor(CellUtil.getTreeBackground(tree, selected, row)); rowGraphics.fillRect(xOffset, bounds.y, containerWidth, bounds.height); rowGraphics.dispose(); @@ -538,18 +538,6 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { } } - protected Color getRowBackground(final int row, final boolean selected) { - if (selected) { - boolean isTableTree = PropertyUtil.getBooleanProperty(tree, KEY_TREE_TABLE_TREE); - return getTreeSelectionBackground(hasFocus() || isTableTree || tree.isEditing()); - } - if (row % 2 == 1 && PropertyUtil.getBooleanProperty(tree, KEY_ALTERNATE_ROW_COLOR)) { - return alternativeBackground; - } else { - return tree.getBackground(); - } - } - protected boolean shouldPaintLines() { return !STYLE_NONE.equals(getLineStyle()); } @@ -581,10 +569,6 @@ public class DarkTreeUI extends BasicTreeUI implements PropertyChangeListener { } } - protected Color getTreeSelectionBackground(final boolean focused) { - return focused ? focusSelectionBackground : selectionBackground; - } - protected String getLineStyle() { return PropertyUtil.getString(tree, KEY_LINE_STYLE, ""); } diff --git a/core/src/main/java/com/github/weisj/darklaf/util/DarkUIUtil.java b/core/src/main/java/com/github/weisj/darklaf/util/DarkUIUtil.java index f9ab838f..f8c38393 100644 --- a/core/src/main/java/com/github/weisj/darklaf/util/DarkUIUtil.java +++ b/core/src/main/java/com/github/weisj/darklaf/util/DarkUIUtil.java @@ -37,7 +37,9 @@ import javax.swing.*; import javax.swing.border.Border; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.InsetsUIResource; +import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; +import javax.swing.tree.TreeCellEditor; import javax.swing.tree.TreeCellRenderer; import sun.awt.SunToolkit; @@ -45,7 +47,7 @@ import sun.awt.SunToolkit; import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.ui.cell.CellRenderer; import com.github.weisj.darklaf.ui.popupmenu.DarkPopupMenuUI; -import com.github.weisj.darklaf.ui.table.DarkTableHeaderUI; +import com.github.weisj.darklaf.ui.table.header.DarkTableHeaderRendererPane; /** * @author Konstantin Bulenkov @@ -155,13 +157,11 @@ public final class DarkUIUtil { } public static boolean isInCell(final Component c) { - boolean tableHeaderCell = PropertyUtil.getBooleanProperty(c, DarkTableHeaderUI.KEY_IS_HEADER_RENDERER); - boolean inCellRenderer = !tableHeaderCell - && (getParentOfType(CellRendererPane.class, c) != null - || getParentOfType(TableCellRenderer.class, c) != null - || getParentOfType(TreeCellRenderer.class, c) != null - || getParentOfType(CellRenderer.class, c) != null - || getParentOfType(CellEditor.class, c) != null); + if (getParentOfType(DarkTableHeaderRendererPane.class, c) != null) return false; + boolean inCellRenderer = getParentOfType(c, CellRendererPane.class, CellEditor.class, + TableCellRenderer.class, TableCellEditor.class, + TreeCellRenderer.class, TreeCellEditor.class, + ListCellRenderer.class, CellRenderer.class) != null; return inCellRenderer && getParentOfType(JComboBox.class, c) == null; } @@ -175,6 +175,17 @@ public final class DarkUIUtil { return null; } + public static T getParentOfType(final Component c, final Class... classes) { + for (Component eachParent = c; eachParent != null; eachParent = eachParent.getParent()) { + for (Class cls : classes) { + if (cls.isAssignableFrom(eachParent.getClass())) { + return (T) eachParent; + } + } + } + return null; + } + public static Window getWindow(final Component component) { if (component == null) { return null; diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/cell.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/cell.properties new file mode 100644 index 00000000..4c8efaef --- /dev/null +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/cell.properties @@ -0,0 +1,49 @@ +# +# 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. +# +# +# suppress inspection "UnusedProperty" for whole file +# +Cell.foreground = %textForeground +Cell.foregroundSelected = %textSelectionForeground +Cell.foregroundNoFocus = %textSelectionForegroundInactive +Cell.foregroundSelectedNoFocus = %textSelectionForegroundInactive + +Cell.inactiveForeground = %textForegroundInactive +Cell.inactiveForegroundSelected = %textSelectionForegroundDisabled +Cell.inactiveForegroundNoFocus = %textForegroundInactive +Cell.inactiveSelectedNoFocus = %textForegroundInactive + +Cell.background = %backgroundContainer +Cell.backgroundAlternative = %backgroundAlternative +Cell.backgroundSelected = %highlightFillFocus +Cell.backgroundNoFocus = %backgroundContainer +Cell.backgroundNoFocusAlternative = %backgroundAlternative +Cell.backgroundSelectedNoFocus = %highlightFill + +Cell.inactiveBackground = %backgroundContainer +Cell.inactiveBackgroundAlternative = %backgroundAlternative +Cell.inactiveBackgroundSelected = %highlightFill +Cell.inactiveBackgroundNoFocus = %backgroundContainer +Cell.inactiveBackgroundNoFocusAlternative = %backgroundAlternative +Cell.inactiveBackgroundSelectedNoFocus = %highlightFill diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/label.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/label.properties index ebfc0b85..4c4dc315 100644 --- a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/label.properties +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/label.properties @@ -26,7 +26,3 @@ # LabelUI = com.github.weisj.darklaf.ui.label.DarkLabelUI Label.inactiveForeground = %textForegroundInactive -Label.cellForegroundNoFocus = %textSelectionForegroundInactive -Label.cellInactiveForeground = %textForegroundInactive -Label.cellInactiveForegroundSelected = %textSelectionForegroundDisabled -Label.cellInactiveForegroundSelectedNoFocus = %textForegroundInactive diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/list.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/list.properties index 5b45a8bc..18b6cb56 100644 --- a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/list.properties +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/list.properties @@ -24,17 +24,38 @@ # # suppress inspection "UnusedProperty" for whole file # -ListUI = com.github.weisj.darklaf.ui.list.DarkListUI -List.cellRenderer = com.github.weisj.darklaf.ui.list.DarkListCellRenderer -List.border = com.github.weisj.darklaf.ui.list.DarkListBorder -List.noFocusBorder = com.github.weisj.darklaf.ui.list.DarkListBorder -List.background = %backgroundContainer -List.focusSelectedCellHighlightBorder = com.github.weisj.darklaf.ui.list.DarkListCellFocusBorder -List.focusCellHighlightBorder = com.github.weisj.darklaf.ui.list.DarkListCellBorder -List.cellNoFocusBorder = com.github.weisj.darklaf.ui.list.DarkListCellBorder -List.dropLineColor = %dropForeground -List.selectionBackground = %highlightFillFocus -List.selectionNoFocusBackground = %highlightFill -List.focusBorderColor = %borderFocus -List.alternateRowBackground = %backgroundAlternative -List.selectionForegroundInactive = %textSelectionForegroundInactive +ListUI = com.github.weisj.darklaf.ui.list.DarkListUI +List.cellRenderer = com.github.weisj.darklaf.ui.list.DarkListCellRenderer +List.border = com.github.weisj.darklaf.ui.list.DarkListBorder +List.noFocusBorder = com.github.weisj.darklaf.ui.list.DarkListBorder +List.focusSelectedCellHighlightBorder = com.github.weisj.darklaf.ui.list.DarkListCellFocusBorder +List.focusCellHighlightBorder = com.github.weisj.darklaf.ui.list.DarkListCellBorder +List.cellNoFocusBorder = com.github.weisj.darklaf.ui.list.DarkListCellBorder +List.dropLineColor = %dropForeground +List.focusBorderColor = %borderFocus + +List.alternateRowColor = false + +List.background = %Cell.background +List.backgroundAlternative = %Cell.backgroundAlternative +List.backgroundSelected = %Cell.backgroundSelected +List.backgroundNoFocus = %Cell.backgroundNoFocus +List.backgroundNoFocusAlternative = %Cell.backgroundNoFocusAlternative +List.backgroundSelectedNoFocus = %Cell.backgroundSelectedNoFocus + +List.inactiveBackground = %Cell.inactiveBackground +List.inactiveBackgroundAlternative = %Cell.inactiveBackgroundAlternative +List.inactiveBackgroundSelected = %Cell.inactiveBackgroundSelected +List.inactiveBackgroundNoFocus = %Cell.inactiveBackgroundNoFocus +List.inactiveBackgroundNoFocusAlternative = %Cell.inactiveBackgroundNoFocusAlternative +List.inactiveBackgroundSelectedNoFocus = %Cell.inactiveBackgroundSelectedNoFocus + +List.foreground = %Cell.foreground +List.foregroundSelected = %Cell.foregroundSelected +List.foregroundNoFocus = %Cell.foregroundNoFocus +List.foregroundSelectedNoFocus = %Cell.foregroundSelectedNoFocus + +List.inactiveForeground = %Cell.inactiveForeground +List.inactiveForegroundSelected = %Cell.inactiveForegroundSelected +List.inactiveForegroundNoFocus = %Cell.inactiveForegroundNoFocus +List.inactiveSelectedNoFocus = %Cell.inactiveSelectedNoFocus diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/table.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/table.properties index d98ce093..d6e4422f 100644 --- a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/table.properties +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/table.properties @@ -24,44 +24,59 @@ # # suppress inspection "UnusedProperty" for whole file # -TableHeaderUI = com.github.weisj.darklaf.ui.table.DarkTableHeaderUI -TableHeader.cellBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder -TableHeader.focusCellBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder -TableHeader.border = com.github.weisj.darklaf.ui.table.DarkTableHeaderBorder -TableHeader.background = %backgroundHeader -TableHeader.focusCellBackground = %backgroundHeader -TableHeader.borderColor = %border -TableHeader.height = 26 +TableHeaderUI = com.github.weisj.darklaf.ui.table.header.DarkTableHeaderUI +TableHeader.cellBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder +TableHeader.focusCellBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder +TableHeader.border = com.github.weisj.darklaf.ui.table.header.DarkTableHeaderBorder +TableHeader.background = %backgroundHeader +TableHeader.focusCellBackground = %backgroundHeader +TableHeader.borderColor = %border +TableHeader.height = 26 -TableUI = com.github.weisj.darklaf.ui.table.DarkTableUI -Table.scrollPaneCornerComponent = com.github.weisj.darklaf.ui.table.DarkTableHeaderCorner -Table.cellNoFocusBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder -Table.focusCellHighlightBorder = com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder -Table.focusSelectedCellHighlightBorder = com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder -Table.cellEditorBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder -Table.scrollPaneBorder = com.github.weisj.darklaf.ui.table.DarkTableScrollPaneBorder -Table.border = com.github.weisj.darklaf.ui.table.DarkTableBorder -Table.background = %backgroundContainer -Table.focusBorderColor = %borderFocus -Table.focusRowBorderColor = %borderFocus -Table.gridColor = %gridLine -Table.dropLineColor = %dropForeground -Table.dropLineShortColor = %dropForeground -Table.focusSelectionBackground = %highlightFillFocus -Table.focusCellBackground = %backgroundContainer -Table.focusCellForeground = %textForeground -Table.selectionNoFocusBackground = %highlightFill -Table.selectionBackground = %highlightFillFocus -Table.selectionForegroundInactive = %textSelectionForegroundInactive +TableUI = com.github.weisj.darklaf.ui.table.DarkTableUI +Table.scrollPaneCornerComponent = com.github.weisj.darklaf.ui.table.header.DarkTableHeaderCorner +Table.cellNoFocusBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder +Table.focusCellHighlightBorder = com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder +Table.focusSelectedCellHighlightBorder = com.github.weisj.darklaf.ui.table.DarkTableCellFocusBorder +Table.cellEditorBorder = com.github.weisj.darklaf.ui.table.DarkTableCellBorder +Table.scrollPaneBorder = com.github.weisj.darklaf.ui.table.DarkTableScrollPaneBorder +Table.border = com.github.weisj.darklaf.ui.table.DarkTableBorder +Table.focusBorderColor = %borderFocus +Table.focusRowBorderColor = %borderFocus +Table.gridColor = %gridLine +Table.dropLineColor = %dropForeground +Table.dropLineShortColor = %dropForeground -Table.alternateRowColor = false -Table.alternateRowBackground = %backgroundAlternative +Table.background = %Cell.background +Table.backgroundAlternative = %Cell.backgroundAlternative +Table.backgroundSelected = %Cell.backgroundSelected +Table.backgroundNoFocus = %Cell.backgroundNoFocus +Table.backgroundNoFocusAlternative = %Cell.backgroundNoFocusAlternative +Table.backgroundSelectedNoFocus = %Cell.backgroundSelectedNoFocus -Table.renderBooleanAsCheckBox = true -Table.booleanRenderType = checkBox -Table.rowHeight = 22 +Table.inactiveBackground = %Cell.inactiveBackground +Table.inactiveBackgroundAlternative = %Cell.inactiveBackgroundAlternative +Table.inactiveBackgroundSelected = %Cell.inactiveBackgroundSelected +Table.inactiveBackgroundNoFocus = %Cell.inactiveBackgroundNoFocus +Table.inactiveBackgroundNoFocusAlternative = %Cell.inactiveBackgroundNoFocusAlternative +Table.inactiveBackgroundSelectedNoFocus = %Cell.inactiveBackgroundSelectedNoFocus + +Table.foreground = %Cell.foreground +Table.foregroundSelected = %Cell.foregroundSelected +Table.foregroundNoFocus = %Cell.foregroundNoFocus +Table.foregroundSelectedNoFocus = %Cell.foregroundSelectedNoFocus + +Table.inactiveForeground = %Cell.inactiveForeground +Table.inactiveForegroundSelected = %Cell.inactiveForegroundSelected +Table.inactiveForegroundNoFocus = %Cell.inactiveForegroundNoFocus +Table.inactiveSelectedNoFocus = %Cell.inactiveSelectedNoFocus + +Table.alternateRowColor = false +Table.renderBooleanAsCheckBox = true +Table.booleanRenderType = checkBox +Table.rowHeight = 22 #Icons -Table.ascendingSortIcon = menu/up.svg[themed](8,16) -Table.descendingSortIcon = menu/down.svg[themed](8,16) -Table.naturalSortIcon = empty(8,16) +Table.ascendingSortIcon = menu/up.svg[themed](8,16) +Table.descendingSortIcon = menu/down.svg[themed](8,16) +Table.naturalSortIcon = empty(8,16) diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tree.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tree.properties index 141ec0e9..870ea80a 100644 --- a/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tree.properties +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/ui/tree.properties @@ -28,9 +28,6 @@ TreeUI = com.github.weisj.darklaf.ui.tree.Dark Tree.editorBorder = com.github.weisj.darklaf.ui.tree.DarkTreeCellBorder Tree.editorBorderColor = %widgetBorder Tree.rendererFillBackground = false -Tree.background = %backgroundContainer -Tree.selectionBackground = %highlightFillFocus -Tree.unfocusedSelectionBackground = %highlightFill Tree.selectionBorderColor = null Tree.line = %borderFocus Tree.hash = %borderFocus @@ -38,15 +35,35 @@ Tree.lineFocusSelected = %borderFocus Tree.lineSelected = %gridLine Tree.lineUnselected = %gridLine -Tree.selectionForegroundInactive = %textSelectionForegroundInactive +Tree.background = %Cell.background +Tree.backgroundAlternative = %Cell.backgroundAlternative +Tree.backgroundSelected = %Cell.backgroundSelected +Tree.backgroundNoFocus = %Cell.backgroundNoFocus +Tree.backgroundNoFocusAlternative = %Cell.backgroundNoFocusAlternative +Tree.backgroundSelectedNoFocus = %Cell.backgroundSelectedNoFocus + +Tree.inactiveBackground = %Cell.inactiveBackground +Tree.inactiveBackgroundAlternative = %Cell.inactiveBackgroundAlternative +Tree.inactiveBackgroundSelected = %Cell.inactiveBackgroundSelected +Tree.inactiveBackgroundNoFocus = %Cell.inactiveBackgroundNoFocus +Tree.inactiveBackgroundNoFocusAlternative = %Cell.inactiveBackgroundNoFocusAlternative +Tree.inactiveBackgroundSelectedNoFocus = %Cell.inactiveBackgroundSelectedNoFocus + +Tree.foreground = %Cell.foreground +Tree.foregroundSelected = %Cell.foregroundSelected +Tree.foregroundNoFocus = %Cell.foregroundNoFocus +Tree.foregroundSelectedNoFocus = %Cell.foregroundSelectedNoFocus + +Tree.inactiveForeground = %Cell.inactiveForeground +Tree.inactiveForegroundSelected = %Cell.inactiveForegroundSelected +Tree.inactiveForegroundNoFocus = %Cell.inactiveForegroundNoFocus +Tree.inactiveSelectedNoFocus = %Cell.inactiveSelectedNoFocus Tree.textBackground = %textBackground Tree.rowHeight = 22 Tree.dropLineColor = %dropForeground Tree.alternateRowColor = false -Tree.alternateRowBackground = %backgroundAlternative - Tree.renderBooleanAsCheckBox = true Tree.booleanRenderType = checkBox Tree.defaultLineStyle = line diff --git a/core/src/main/resources/com/github/weisj/darklaf/properties/unused.properties b/core/src/main/resources/com/github/weisj/darklaf/properties/unused.properties index 37e84c3f..9975cece 100644 --- a/core/src/main/resources/com/github/weisj/darklaf/properties/unused.properties +++ b/core/src/main/resources/com/github/weisj/darklaf/properties/unused.properties @@ -32,6 +32,7 @@ Button.select = null Button.toolBarBorderBackground = null Button.gradient = null Button.rolloverIconType = null +Button.disabledToolBarBorderBackground = null CheckBox.focus = null Checkbox.select = null @@ -116,6 +117,9 @@ ToolBar.highlight = null ToolBar.light = null ToolBar.shadow = null +Table.focusCellForeground = null +Table.focusCellBackground = null + Label.disabledShadow = null MenuBar.shadow = null MenuBar.gradient = null diff --git a/core/src/test/java/defaults/UIManagerDefaults.java b/core/src/test/java/defaults/UIManagerDefaults.java index fa60ed54..055b60fb 100644 --- a/core/src/test/java/defaults/UIManagerDefaults.java +++ b/core/src/test/java/defaults/UIManagerDefaults.java @@ -43,7 +43,7 @@ import javax.swing.table.DefaultTableModel; import ui.ComponentDemo; import com.github.weisj.darklaf.components.OverlayScrollPane; -import com.github.weisj.darklaf.ui.table.DarkColorTableCellRendererEditor; +import com.github.weisj.darklaf.ui.table.renderer.DarkColorTableCellRendererEditor; public class UIManagerDefaults implements ItemListener, ComponentDemo { private static final String[] COLUMN_NAMES = {"Key", "Value", "Sample"}; diff --git a/core/src/test/java/ui/list/ListDemo.java b/core/src/test/java/ui/list/ListDemo.java index 4e9c5c99..f06c11a8 100644 --- a/core/src/test/java/ui/list/ListDemo.java +++ b/core/src/test/java/ui/list/ListDemo.java @@ -51,6 +51,12 @@ public final class ListDemo implements ComponentDemo { DemoPanel panel = new DemoPanel(list, new BorderLayout(), 0); JPanel controlPanel = panel.addControls(); + controlPanel.add(new JCheckBox("enabled") { + { + setSelected(list.isEnabled()); + addActionListener(e -> list.setEnabled(isSelected())); + } + }); controlPanel.add(new JCheckBox(DarkListUI.KEY_ALTERNATE_ROW_COLOR) { { setSelected(PropertyUtil.getBooleanProperty(list, DarkListUI.KEY_ALTERNATE_ROW_COLOR)); diff --git a/core/src/test/java/ui/table/TableDemo.java b/core/src/test/java/ui/table/TableDemo.java index 431f1120..bb12d941 100644 --- a/core/src/test/java/ui/table/TableDemo.java +++ b/core/src/test/java/ui/table/TableDemo.java @@ -34,8 +34,8 @@ import javax.swing.table.TableCellEditor; import ui.ComponentDemo; import ui.DemoPanel; -import com.github.weisj.darklaf.ui.table.DarkTableCellEditor; import com.github.weisj.darklaf.ui.table.DarkTableUI; +import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditor; import com.github.weisj.darklaf.util.PropertyKey; import com.github.weisj.darklaf.util.PropertyUtil; diff --git a/core/src/test/java/ui/tree/TreeDemo.java b/core/src/test/java/ui/tree/TreeDemo.java index ffe1d7d0..d3a4dd2e 100644 --- a/core/src/test/java/ui/tree/TreeDemo.java +++ b/core/src/test/java/ui/tree/TreeDemo.java @@ -73,13 +73,19 @@ public class TreeDemo implements ComponentDemo { final boolean leaf, final int row, final boolean hasFocus) { Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); - component.setEnabled(value != parent1 && value != child); + component.setEnabled(tree.isEnabled() && (value != parent1 && value != child)); return component; } }); DemoPanel panel = new DemoPanel(new OverlayScrollPane(tree), new BorderLayout(), 0); JPanel controlPanel = panel.addControls(); controlPanel.setLayout(new MigLayout("fillx, wrap 2", "[][grow]")); + controlPanel.add(new JCheckBox(PropertyKey.ENABLED) { + { + setSelected(tree.isEnabled()); + addActionListener(e -> tree.setEnabled(isSelected())); + } + }); controlPanel.add(new JCheckBox(PropertyKey.EDITABLE) { { setSelected(tree.isEditable()); diff --git a/utils/src/main/java/com/github/weisj/darklaf/util/PropertyKey.java b/utils/src/main/java/com/github/weisj/darklaf/util/PropertyKey.java index 307311dc..13267328 100644 --- a/utils/src/main/java/com/github/weisj/darklaf/util/PropertyKey.java +++ b/utils/src/main/java/com/github/weisj/darklaf/util/PropertyKey.java @@ -36,6 +36,7 @@ public class PropertyKey { public static final String OPAQUE = "opaque"; public static final String ANCESTOR = "ancestor"; public static final String EDITABLE = "editable"; + public static final String ENABLED = "enabled"; public static final String BACKGROUND = "background"; public static final String FOREGROUND = "foreground"; public static final String FONT = "font";