mirror of https://github.com/weisJ/darklaf.git
Browse Source
MAde ThemedIcon patch colors lazily. Added TristateCheckBox. Fixed NPE during titlePane uninstall process. Added missing properties for striped table/tree.pull/15/head
weisj
5 years ago
19 changed files with 340 additions and 52 deletions
@ -0,0 +1,78 @@
|
||||
package com.weis.darklaf.components.tristate; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.event.ItemEvent; |
||||
|
||||
public class TristateButtonModel extends JToggleButton.ToggleButtonModel { |
||||
private TristateState state = TristateState.DESELECTED; |
||||
|
||||
public TristateButtonModel(final TristateState state) { |
||||
setState(state); |
||||
} |
||||
|
||||
public TristateButtonModel() { |
||||
this(TristateState.DESELECTED); |
||||
} |
||||
|
||||
public void setIndeterminate() { |
||||
setState(TristateState.INDETERMINATE); |
||||
} |
||||
|
||||
public boolean isIndeterminate() { |
||||
return state == TristateState.INDETERMINATE; |
||||
} |
||||
|
||||
// Overrides of superclass methods
|
||||
public void setEnabled(final boolean enabled) { |
||||
super.setEnabled(enabled); |
||||
// Restore state display
|
||||
displayState(); |
||||
} |
||||
|
||||
public void setSelected(final boolean selected) { |
||||
setState(selected ? TristateState.SELECTED : TristateState.DESELECTED); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isSelected() { |
||||
return state == TristateState.SELECTED; |
||||
} |
||||
|
||||
// Empty overrides of superclass methods
|
||||
public void setArmed(final boolean b) { |
||||
} |
||||
|
||||
public void setPressed(final boolean b) { |
||||
} |
||||
|
||||
protected void iterateState() { |
||||
setState(state.next()); |
||||
} |
||||
|
||||
public void setState(final TristateState state) { |
||||
//Set internal state
|
||||
this.state = state; |
||||
displayState(); |
||||
if (state == TristateState.INDETERMINATE && isEnabled()) { |
||||
// force the events to fire
|
||||
|
||||
// Send ChangeEvent
|
||||
fireStateChanged(); |
||||
|
||||
// Send ItemEvent
|
||||
int indeterminate = 3; |
||||
//noinspection MagicConstant
|
||||
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, this, indeterminate)); |
||||
} |
||||
} |
||||
|
||||
protected void displayState() { |
||||
super.setSelected(state != TristateState.DESELECTED); |
||||
super.setArmed(state == TristateState.INDETERMINATE); |
||||
super.setPressed(state == TristateState.INDETERMINATE); |
||||
} |
||||
|
||||
public TristateState getState() { |
||||
return state; |
||||
} |
||||
} |
@ -0,0 +1,100 @@
|
||||
package com.weis.darklaf.components.tristate; |
||||
|
||||
import com.weis.darklaf.DarkLaf; |
||||
import org.jetbrains.annotations.Contract; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import javax.swing.*; |
||||
import javax.swing.event.ChangeListener; |
||||
import javax.swing.plaf.ActionMapUIResource; |
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.InputEvent; |
||||
import java.awt.event.MouseAdapter; |
||||
import java.awt.event.MouseEvent; |
||||
|
||||
public class TristateCheckBox extends JCheckBox { |
||||
private final ChangeListener enableListener = e -> TristateCheckBox.this.setFocusable(getModel().isEnabled()); |
||||
|
||||
public TristateCheckBox(final String text) { |
||||
this(text, null, TristateState.DESELECTED); |
||||
} |
||||
|
||||
@NotNull |
||||
@Contract(pure = true) |
||||
public String getUIClassID() { |
||||
if (UIManager.getLookAndFeel() instanceof DarkLaf) { |
||||
return "TristateCheckBoxUI"; |
||||
} else { |
||||
return super.getUIClassID(); |
||||
} |
||||
} |
||||
|
||||
public TristateCheckBox(final String text, final Icon icon, final TristateState initial) { |
||||
super(text, icon); |
||||
setModel(new TristateButtonModel(initial)); |
||||
// override action behaviour
|
||||
super.addMouseListener(new MouseAdapter() { |
||||
public void mousePressed(final MouseEvent e) { |
||||
System.out.println(getState()); |
||||
TristateCheckBox.this.iterateState(); |
||||
} |
||||
}); |
||||
ActionMap actions = new ActionMapUIResource(); |
||||
actions.put("pressed", new AbstractAction() { |
||||
public void actionPerformed(final ActionEvent e) { |
||||
TristateCheckBox.this.iterateState(); |
||||
} |
||||
}); |
||||
actions.put("released", null); |
||||
SwingUtilities.replaceUIActionMap(this, actions); |
||||
} |
||||
|
||||
public void setIndeterminate() { |
||||
getTristateModel().setIndeterminate(); |
||||
} |
||||
|
||||
public void setState(final TristateState state) { |
||||
getTristateModel().setState(state); |
||||
} |
||||
|
||||
public boolean isIndeterminate() { |
||||
return getTristateModel().isIndeterminate(); |
||||
} |
||||
|
||||
public TristateState getState() { |
||||
return getTristateModel().getState(); |
||||
} |
||||
|
||||
@Override |
||||
public void setModel(final ButtonModel newModel) { |
||||
super.setModel(newModel); |
||||
|
||||
if (model instanceof TristateButtonModel) { |
||||
model.addChangeListener(enableListener); |
||||
} |
||||
} |
||||
|
||||
private void iterateState() { |
||||
if (!getModel().isEnabled()) return; |
||||
|
||||
grabFocus(); |
||||
getTristateModel().iterateState(); |
||||
repaint(); |
||||
|
||||
int modifiers = 0; |
||||
AWTEvent currentEvent = EventQueue.getCurrentEvent(); |
||||
if (currentEvent instanceof InputEvent) { |
||||
modifiers = ((InputEvent) currentEvent).getModifiersEx(); |
||||
} else if (currentEvent instanceof ActionEvent) { |
||||
modifiers = ((ActionEvent) currentEvent).getModifiers(); |
||||
} |
||||
fireActionPerformed(new ActionEvent(this, |
||||
ActionEvent.ACTION_PERFORMED, getText(), |
||||
System.currentTimeMillis(), modifiers)); |
||||
} |
||||
|
||||
public TristateButtonModel getTristateModel() { |
||||
return (TristateButtonModel) super.getModel(); |
||||
} |
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.weis.darklaf.components.tristate; |
||||
|
||||
public enum TristateState { |
||||
SELECTED { |
||||
public TristateState next() { |
||||
return INDETERMINATE; |
||||
} |
||||
}, |
||||
INDETERMINATE { |
||||
public TristateState next() { |
||||
return DESELECTED; |
||||
} |
||||
}, |
||||
DESELECTED { |
||||
public TristateState next() { |
||||
return SELECTED; |
||||
} |
||||
}; |
||||
|
||||
public abstract TristateState next(); |
||||
} |
@ -0,0 +1,31 @@
|
||||
package com.weis.darklaf.icons; |
||||
|
||||
import com.weis.darklaf.LafManager; |
||||
import com.weis.darklaf.theme.Theme; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import java.awt.*; |
||||
import java.net.URI; |
||||
|
||||
public class ThemedSVGIcon extends DarkSVGIcon { |
||||
|
||||
private Theme currentTheme; |
||||
|
||||
public ThemedSVGIcon(@NotNull final URI uri, final int displayWidth, final int displayHeight) { |
||||
super(uri, displayWidth, displayHeight); |
||||
} |
||||
|
||||
@Override |
||||
public void paintIcon(final Component c, final Graphics g, final int x, final int y) { |
||||
ensureTheme(); |
||||
super.paintIcon(c, g, x, y); |
||||
} |
||||
|
||||
private void ensureTheme() { |
||||
var theme = LafManager.getTheme(); |
||||
if (currentTheme != theme) { |
||||
IconColorMapper.patchColors(getSVGIcon()); |
||||
currentTheme = theme; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,46 @@
|
||||
package com.weis.darklaf.ui.tristate; |
||||
|
||||
import com.weis.darklaf.components.tristate.TristateCheckBox; |
||||
import com.weis.darklaf.components.tristate.TristateState; |
||||
import com.weis.darklaf.ui.checkbox.DarkCheckBoxUI; |
||||
import org.jetbrains.annotations.Contract; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import javax.swing.*; |
||||
import javax.swing.plaf.ComponentUI; |
||||
|
||||
public class DarkTristateCheckBoxUI extends DarkCheckBoxUI { |
||||
|
||||
@NotNull |
||||
@Contract("_ -> new") |
||||
public static ComponentUI createUI(final JComponent c) { |
||||
return new DarkTristateCheckBoxUI(); |
||||
} |
||||
|
||||
private Icon checkBoxIndeterminateIcon; |
||||
private Icon checkBoxIndeterminateDisabledIcon; |
||||
private Icon checkBoxIndeterminateFocusedIcon; |
||||
|
||||
@Override |
||||
public void installDefaults(final AbstractButton b) { |
||||
super.installDefaults(b); |
||||
checkBoxIndeterminateIcon = UIManager.getIcon("CheckBox.indeterminate.icon"); |
||||
checkBoxIndeterminateDisabledIcon = UIManager.getIcon("CheckBox.indeterminateDisabled.icon"); |
||||
checkBoxIndeterminateFocusedIcon = UIManager.getIcon("CheckBox.indeterminateFocused.icon"); |
||||
} |
||||
|
||||
@Override |
||||
protected Icon getCheckIcon(@NotNull final AbstractButton b) { |
||||
if (b instanceof TristateCheckBox) { |
||||
var state = ((TristateCheckBox) b).getState(); |
||||
if (state == TristateState.INDETERMINATE) { |
||||
if (b.isEnabled()) { |
||||
return b.hasFocus() ? checkBoxIndeterminateFocusedIcon : checkBoxIndeterminateIcon; |
||||
} else { |
||||
return checkBoxIndeterminateDisabledIcon; |
||||
} |
||||
} |
||||
} |
||||
return super.getCheckIcon(b); |
||||
} |
||||
} |
@ -0,0 +1,2 @@
|
||||
# suppress inspection "UnusedProperty" for whole file |
||||
TristateCheckBoxUI = com.weis.darklaf.ui.tristate.DarkTristateCheckBoxUI |
Loading…
Reference in new issue