mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-29 14:52:52 +00:00
6490753: JComboBox doesn't look as native combobox in different states of component
Reviewed-by: serb, alexsch
This commit is contained in:
parent
ce4a8c41db
commit
bc2bb1fae1
@ -36,7 +36,6 @@ import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
|
||||
import com.sun.java.swing.plaf.windows.TMSchema.State;
|
||||
import static com.sun.java.swing.plaf.windows.TMSchema.State.*;
|
||||
import com.sun.java.swing.plaf.windows.TMSchema.Part;
|
||||
@ -383,18 +382,25 @@ class AnimationController implements ActionListener, PropertyChangeListener {
|
||||
updateProgress();
|
||||
if (! isDone()) {
|
||||
Graphics2D g = (Graphics2D) _g.create();
|
||||
skin.paintSkinRaw(g, dx, dy, dw, dh, startState);
|
||||
float alpha;
|
||||
if (isForward) {
|
||||
alpha = progress;
|
||||
if (skin.haveToSwitchStates()) {
|
||||
skin.paintSkinRaw(g, dx, dy, dw, dh, state);
|
||||
g.setComposite(AlphaComposite.SrcOver.derive(1 - progress));
|
||||
skin.paintSkinRaw(g, dx, dy, dw, dh, startState);
|
||||
} else {
|
||||
alpha = 1 - progress;
|
||||
skin.paintSkinRaw(g, dx, dy, dw, dh, startState);
|
||||
float alpha;
|
||||
if (isForward) {
|
||||
alpha = progress;
|
||||
} else {
|
||||
alpha = 1 - progress;
|
||||
}
|
||||
g.setComposite(AlphaComposite.SrcOver.derive(alpha));
|
||||
skin.paintSkinRaw(g, dx, dy, dw, dh, state);
|
||||
}
|
||||
g.setComposite(AlphaComposite.SrcOver.derive(alpha));
|
||||
skin.paintSkinRaw(g, dx, dy, dw, dh, state);
|
||||
g.dispose();
|
||||
} else {
|
||||
skin.paintSkinRaw(_g, dx, dy, dw, dh, state);
|
||||
skin.switchStates(false);
|
||||
}
|
||||
}
|
||||
boolean isDone() {
|
||||
|
||||
@ -121,6 +121,12 @@ class TMSchema {
|
||||
|
||||
LBP_LISTBOX(Control.LISTBOX, 0),
|
||||
|
||||
LBCP_BORDER_HSCROLL (Control.LISTBOX, 1),
|
||||
LBCP_BORDER_HVSCROLL (Control.LISTBOX, 2),
|
||||
LBCP_BORDER_NOSCROLL (Control.LISTBOX, 3),
|
||||
LBCP_BORDER_VSCROLL (Control.LISTBOX, 4),
|
||||
LBCP_ITEM (Control.LISTBOX, 5),
|
||||
|
||||
LVP_LISTVIEW(Control.LISTVIEW, 0),
|
||||
|
||||
PP_PROGRESS (Control.PROGRESS, 0),
|
||||
@ -343,6 +349,12 @@ class TMSchema {
|
||||
stateMap.put(Part.HP_HEADERSORTARROW,
|
||||
new State[] {SORTEDDOWN, SORTEDUP});
|
||||
|
||||
State[] listBoxStates = new State[] { NORMAL, PRESSED, HOT, DISABLED};
|
||||
stateMap.put(Part.LBCP_BORDER_HSCROLL, listBoxStates);
|
||||
stateMap.put(Part.LBCP_BORDER_HVSCROLL, listBoxStates);
|
||||
stateMap.put(Part.LBCP_BORDER_NOSCROLL, listBoxStates);
|
||||
stateMap.put(Part.LBCP_BORDER_VSCROLL, listBoxStates);
|
||||
|
||||
State[] scrollBarStates = new State[] { NORMAL, HOT, PRESSED, DISABLED, HOVER };
|
||||
stateMap.put(Part.SBP_SCROLLBAR, scrollBarStates);
|
||||
stateMap.put(Part.SBP_THUMBBTNVERT, scrollBarStates);
|
||||
|
||||
@ -41,6 +41,7 @@ import static com.sun.java.swing.plaf.windows.XPStyle.Skin;
|
||||
import sun.swing.DefaultLookup;
|
||||
import sun.swing.StringUIClientPropertyKey;
|
||||
|
||||
import com.sun.java.swing.plaf.windows.WindowsBorders.DashedBorder;
|
||||
|
||||
/**
|
||||
* Windows combo box.
|
||||
@ -97,6 +98,9 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
} else if (source instanceof XPComboBoxButton) {
|
||||
rv = ((XPComboBoxButton) source)
|
||||
.getWindowsComboBoxUI().comboBox;
|
||||
} else if (source instanceof JTextField &&
|
||||
((JTextField) source).getParent() instanceof JComboBox) {
|
||||
rv = (JComboBox) ((JTextField) source).getParent();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -149,6 +153,8 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
//is initialized after installListeners is invoked
|
||||
comboBox.addMouseListener(rolloverListener);
|
||||
arrowButton.addMouseListener(rolloverListener);
|
||||
// set empty border as default to see vista animated border
|
||||
comboBox.setBorder(new EmptyBorder(0,0,0,0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +230,9 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
state = State.DISABLED;
|
||||
} else if (isPopupVisible(comboBox)) {
|
||||
state = State.PRESSED;
|
||||
} else if (comboBox.isEditable()
|
||||
&& comboBox.getEditor().getEditorComponent().isFocusOwner()) {
|
||||
state = State.PRESSED;
|
||||
} else if (isRollover) {
|
||||
state = State.HOT;
|
||||
}
|
||||
@ -242,7 +251,7 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
skin = xp.getSkin(c, Part.CP_READONLY);
|
||||
}
|
||||
if (skin == null) {
|
||||
skin = xp.getSkin(c, Part.CP_COMBOBOX);
|
||||
skin = xp.getSkin(c, Part.CP_BORDER);
|
||||
}
|
||||
skin.paintSkin(g, 0, 0, c.getWidth(), c.getHeight(), state);
|
||||
}
|
||||
@ -368,7 +377,7 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
}
|
||||
|
||||
protected ComboPopup createPopup() {
|
||||
return super.createPopup();
|
||||
return new WinComboPopUp(comboBox);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -414,8 +423,10 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
|
||||
@SuppressWarnings("serial") // Superclass is not serializable across versions
|
||||
private class XPComboBoxButton extends XPStyle.GlyphButton {
|
||||
private State prevState = null;
|
||||
|
||||
public XPComboBoxButton(XPStyle xp) {
|
||||
super(null,
|
||||
super(comboBox,
|
||||
(! xp.isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT))
|
||||
? Part.CP_DROPDOWNBUTTON
|
||||
: (comboBox.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
|
||||
@ -428,18 +439,33 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
@Override
|
||||
protected State getState() {
|
||||
State rv;
|
||||
|
||||
getModel().setPressed(comboBox.isPopupVisible());
|
||||
|
||||
rv = super.getState();
|
||||
XPStyle xp = XPStyle.getXP();
|
||||
if (rv != State.DISABLED
|
||||
&& comboBox != null && ! comboBox.isEditable()
|
||||
&& xp != null && xp.isSkinDefined(comboBox,
|
||||
Part.CP_DROPDOWNBUTTONRIGHT)) {
|
||||
&& comboBox != null && ! comboBox.isEditable()
|
||||
&& xp != null && xp.isSkinDefined(comboBox,
|
||||
Part.CP_DROPDOWNBUTTONRIGHT)) {
|
||||
/*
|
||||
* for non editable ComboBoxes Vista seems to have the
|
||||
* same glyph for all non DISABLED states
|
||||
*/
|
||||
rv = State.NORMAL;
|
||||
}
|
||||
if (rv == State.NORMAL && (prevState == State.HOT || prevState == State.PRESSED)) {
|
||||
/*
|
||||
* State NORMAL of combobox button cannot overpaint states HOT or PRESSED
|
||||
* Therefore HOT state must be painted from alpha 1 to 0 and not as usual that
|
||||
* NORMAL state is painted from alpha 0 to alpha 1.
|
||||
*/
|
||||
skin.switchStates(true);
|
||||
}
|
||||
if (rv != prevState) {
|
||||
prevState = rv;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -484,6 +510,39 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial") // Same-version serialization only
|
||||
protected class WinComboPopUp extends BasicComboPopup {
|
||||
private Skin listBoxBorder = null;
|
||||
private XPStyle xp;
|
||||
|
||||
public WinComboPopUp(JComboBox<Object> combo) {
|
||||
super(combo);
|
||||
xp = XPStyle.getXP();
|
||||
if (xp != null && xp.isSkinDefined(combo, Part.LBCP_BORDER_NOSCROLL)) {
|
||||
this.listBoxBorder = new Skin(combo, Part.LBCP_BORDER_NOSCROLL);
|
||||
this.setBorder(new EmptyBorder(1,1,1,1));
|
||||
}
|
||||
}
|
||||
|
||||
protected KeyListener createKeyListener() {
|
||||
return new InvocationKeyHandler();
|
||||
}
|
||||
|
||||
protected class InvocationKeyHandler extends BasicComboPopup.InvocationKeyHandler {
|
||||
protected InvocationKeyHandler() {
|
||||
WinComboPopUp.this.super();
|
||||
}
|
||||
}
|
||||
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
if (this.listBoxBorder != null) {
|
||||
this.listBoxBorder.paintSkinRaw(g, this.getX(), this.getY(),
|
||||
this.getWidth(), this.getHeight(), State.HOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subclassed to highlight selected item in an editable combo box.
|
||||
@ -498,6 +557,7 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
protected JTextField createEditorComponent() {
|
||||
JTextField editor = super.createEditorComponent();
|
||||
Border border = (Border)UIManager.get("ComboBox.editorBorder");
|
||||
|
||||
if (border != null) {
|
||||
editor.setBorder(border);
|
||||
}
|
||||
@ -524,6 +584,31 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
private static final Object BORDER_KEY
|
||||
= new StringUIClientPropertyKey("BORDER_KEY");
|
||||
private static final Border NULL_BORDER = new EmptyBorder(0, 0, 0, 0);
|
||||
|
||||
// Create own version of DashedBorder with more space on left side
|
||||
private class WindowsComboBoxDashedBorder extends DashedBorder {
|
||||
|
||||
public WindowsComboBoxDashedBorder(Color color, int thickness) {
|
||||
super(color, thickness);
|
||||
}
|
||||
|
||||
public WindowsComboBoxDashedBorder(Color color) {
|
||||
super(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets i) {
|
||||
return new Insets(0,2,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
public WindowsComboBoxRenderer() {
|
||||
super();
|
||||
|
||||
// correct space on the left side of text items in the combo popup list
|
||||
Insets i = getBorder().getBorderInsets(this);
|
||||
setBorder(new EmptyBorder(0, 2, 0, i.right));
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -542,7 +627,7 @@ public class WindowsComboBoxUI extends BasicComboBoxUI {
|
||||
if (index == -1 && isSelected) {
|
||||
Border border = component.getBorder();
|
||||
Border dashedBorder =
|
||||
new WindowsBorders.DashedBorder(list.getForeground());
|
||||
new WindowsComboBoxDashedBorder(list.getForeground());
|
||||
component.setBorder(dashedBorder);
|
||||
//store current border in client property if needed
|
||||
if (component.getClientProperty(BORDER_KEY) == null) {
|
||||
|
||||
@ -672,7 +672,7 @@ public class WindowsLookAndFeel extends BasicLookAndFeel
|
||||
"ComboBox.buttonHighlight", ControlHighlightColor,
|
||||
"ComboBox.selectionBackground", SelectionBackgroundColor,
|
||||
"ComboBox.selectionForeground", SelectionTextColor,
|
||||
"ComboBox.editorBorder", new XPValue(new EmptyBorder(1,2,1,1),
|
||||
"ComboBox.editorBorder", new XPValue(new EmptyBorder(1,4,1,1),
|
||||
new EmptyBorder(1,4,1,4)),
|
||||
"ComboBox.disabledBackground",
|
||||
new XPColorValue(Part.CP_COMBOBOX, State.DISABLED,
|
||||
|
||||
@ -479,6 +479,7 @@ class XPStyle {
|
||||
|
||||
private final String string;
|
||||
private Dimension size = null;
|
||||
private boolean switchStates = false;
|
||||
|
||||
Skin(Component component, Part part) {
|
||||
this(component, part, null);
|
||||
@ -513,6 +514,14 @@ class XPStyle {
|
||||
return (insets != null) ? insets : new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
boolean haveToSwitchStates() {
|
||||
return switchStates;
|
||||
}
|
||||
|
||||
void switchStates(boolean b) {
|
||||
switchStates = b;
|
||||
}
|
||||
|
||||
private int getWidth(State state) {
|
||||
if (size == null) {
|
||||
size = getPartSize(part, state);
|
||||
@ -689,7 +698,7 @@ class XPStyle {
|
||||
|
||||
@SuppressWarnings("serial") // Superclass is not serializable across versions
|
||||
static class GlyphButton extends JButton {
|
||||
private Skin skin;
|
||||
protected Skin skin;
|
||||
|
||||
public GlyphButton(Component parent, Part part) {
|
||||
XPStyle xp = getXP();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user