From 1ec2fbf00d11652c1bcb76b8f14824d5109a7d29 Mon Sep 17 00:00:00 2001 From: drdev Date: Sun, 26 Oct 2014 02:06:43 +0000 Subject: [PATCH] Add password field --- .gitattributes | 1 + .../java/forge/toolbox/FPasswordField.java | 141 ++++++++++++++++++ .../src/main/java/forge/toolbox/FSkin.java | 35 +++++ .../main/java/forge/toolbox/FTextField.java | 2 +- 4 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 forge-gui-desktop/src/main/java/forge/toolbox/FPasswordField.java diff --git a/.gitattributes b/.gitattributes index 9f814af0113..10db1900168 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1039,6 +1039,7 @@ forge-gui-desktop/src/main/java/forge/toolbox/FMouseAdapter.java -text forge-gui-desktop/src/main/java/forge/toolbox/FOptionPane.java -text forge-gui-desktop/src/main/java/forge/toolbox/FOverlay.java -text forge-gui-desktop/src/main/java/forge/toolbox/FPanel.java -text +forge-gui-desktop/src/main/java/forge/toolbox/FPasswordField.java -text forge-gui-desktop/src/main/java/forge/toolbox/FProgressBar.java -text forge-gui-desktop/src/main/java/forge/toolbox/FRadioButton.java -text forge-gui-desktop/src/main/java/forge/toolbox/FScrollPane.java -text diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FPasswordField.java b/forge-gui-desktop/src/main/java/forge/toolbox/FPasswordField.java new file mode 100644 index 00000000000..968d794e5e4 --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FPasswordField.java @@ -0,0 +1,141 @@ +package forge.toolbox; + +import forge.gui.MouseUtil; +import forge.interfaces.ITextField; +import forge.toolbox.FSkin.SkinnedPasswordField; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +/** + * A custom instance of JPasswordField using Forge skin properties. + * + */ +@SuppressWarnings("serial") +public class FPasswordField extends SkinnedPasswordField implements ITextField { + public static final int HEIGHT = 25; //TODO: calculate this somehow instead of hard-coding it + private static final FSkin.SkinColor textColor = FSkin.getColor(FSkin.Colors.CLR_TEXT); + private static final FSkin.SkinColor ghostTextColor = textColor.stepColor(20); + private static final FSkin.SkinColor backColor = FSkin.getColor(FSkin.Colors.CLR_THEME2); + + private String ghostText; + private boolean showGhostTextWithFocus; + + public FPasswordField() { + this.setForeground(textColor); + this.setBackground(backColor); + this.setCaretColor(textColor); + this.setMargin(new Insets(3, 3, 2, 3)); + this.setOpaque(true); + this.setFocusable(true); + if (this.isEditable()) { + MouseUtil.setComponentCursor(this, Cursor.TEXT_CURSOR); + } + + addFocusListener(new FocusAdapter() { + @Override + public void focusGained(final FocusEvent e) { + final FPasswordField field = (FPasswordField)e.getSource(); + if (field.isEmpty()) { + if (field.ghostText != null && !field.showGhostTextWithFocus) { + field.repaint(); + } + } + else { //if not empty, select all text when focused + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + field.selectAll(); + } + }); + } + } + + @Override + public void focusLost(final FocusEvent e) { + FPasswordField field = (FPasswordField)e.getSource(); + if (field.ghostText != null && field.isEmpty() && !field.showGhostTextWithFocus) { + field.repaint(); + } + } + }); + } + + @SuppressWarnings("deprecation") + public boolean isEmpty() { + String text = this.getText(); + return (text == null || text.isEmpty()); + } + + @SuppressWarnings("deprecation") + public int getAutoSizeWidth() { + FontMetrics metrics = this.getFontMetrics(this.getFont()); + return metrics.stringWidth(this.getText()) + 12; + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (this.ghostText != null && this.isEmpty() && (this.showGhostTextWithFocus || !this.hasFocus())) { + //TODO: Make ghost text look more like regular text + final Insets margin = this.getMargin(); + final Graphics2D g2d = (Graphics2D)g.create(); + g2d.setFont(this.getFont()); + FSkin.setGraphicsColor(g2d, ghostTextColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.drawString(this.ghostText, margin.left + 2, getBaseline(getWidth(), getHeight())); //account for borders (TODO: why +15?) + g2d.dispose(); + } + } + + public String getGhostText() { + return this.ghostText; + } + + public void setGhostText(String ghostText0) { + if ("".equals(this.ghostText)) { ghostText0 = null; } //don't allow empty string to make other logic easier + if (this.ghostText == ghostText0) { return; } + this.ghostText = ghostText0; + if (this.isEmpty()) { + this.repaint(); + } + } + + public boolean getShowGhostTextWithFocus() { + return this.showGhostTextWithFocus; + } + + public void setShowGhostTextWithFocus(boolean showGhostTextWithFocus0) { + if (this.showGhostTextWithFocus == showGhostTextWithFocus0) { return; } + this.showGhostTextWithFocus = showGhostTextWithFocus0; + if (this.isEmpty() && this.hasFocus()) { + this.repaint(); + } + } + + public void addChangeListener(ChangeListener listener) { + this.getDocument().addDocumentListener(listener); + } + + public static abstract class ChangeListener implements DocumentListener { + @Override + public void changedUpdate(DocumentEvent e) { + textChanged(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + textChanged(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + textChanged(); + } + + public abstract void textChanged(); + } +} diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java b/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java index 24e0e68eab3..68501fc1c1d 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java @@ -2505,6 +2505,41 @@ public class FSkin { super.paintComponent(g); } } + public static class SkinnedPasswordField extends JPasswordField implements ISkinnedComponent { + private static final long serialVersionUID = 1557674285031452868L; + + private JTextComponentSkin skin; + public JTextComponentSkin getSkin() { + if (skin == null) { skin = new JTextComponentSkin(); } + return skin; + } + + public SkinnedPasswordField() { super(); } + + public void setForeground(SkinColor skinColor) { getSkin().setForeground(this, skinColor); } + @Override public void setForeground(Color color) { getSkin().resetForeground(); super.setForeground(color); } + + public void setBackground(SkinColor skinColor) { getSkin().setBackground(this, skinColor); } + @Override public void setBackground(Color color) { getSkin().resetBackground(); super.setBackground(color); } + + public void setFont(SkinFont skinFont) { getSkin().setFont(this, skinFont); } + @Override public void setFont(Font font) { getSkin().resetFont(); super.setFont(font); } + + public void setCursor(SkinCursor skinCursor) { getSkin().setCursor(this, skinCursor); } + @Override public void setCursor(Cursor cursor) { getSkin().resetCursor(); super.setCursor(cursor); } + + public void setBorder(SkinBorder skinBorder) { getSkin().setBorder(this, skinBorder); } + @Override public void setBorder(Border border) { getSkin().resetBorder(); super.setBorder(border); } + + public void setCaretColor(SkinColor skinColor) { getSkin().setCaretColor(this, skinColor); } + @Override public void setCaretColor(Color color) { getSkin().resetCaretColor(); super.setCaretColor(color); } + + @Override + protected void paintComponent(Graphics g) { + getSkin().update(this); + super.paintComponent(g); + } + } public static class SkinnedTextArea extends JTextArea implements ISkinnedComponent { private static final long serialVersionUID = 4191648156716570907L; diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FTextField.java b/forge-gui-desktop/src/main/java/forge/toolbox/FTextField.java index 4a4a58eaef3..f457f015970 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FTextField.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FTextField.java @@ -16,7 +16,7 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; /** - * A custom instance of JTextArea using Forge skin properties. + * A custom instance of JTextField using Forge skin properties. * */ @SuppressWarnings("serial")