Sfoglia il codice sorgente

Add panel for tag information.

Sam Jaffe 5 anni fa
parent
commit
c1f94345b2

+ 112 - 0
src/main/lombok/org/leumasjaffe/recipe/controller/GhostTextController.java

@@ -0,0 +1,112 @@
+package org.leumasjaffe.recipe.controller;
+
+import java.awt.Color;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+
+/**
+ * Code taken from https://stackoverflow.com/questions/10506789/how-to-display-faint-gray-ghost-text-in-a-jtextfield/10507193
+ * @author Guillaume Polet / XaV
+ *
+ */
+public class GhostTextController implements FocusListener, DocumentListener, PropertyChangeListener {
+	private final JTextComponent textComp;
+	private boolean isEmpty;
+	private Color ghostColor;
+	private Color foregroundColor;
+	private final String ghostText;
+
+	public GhostTextController(final JTextComponent textComp, String ghostText) {
+		super();
+		this.textComp = textComp;
+		this.ghostText = ghostText;
+		this.ghostColor = Color.LIGHT_GRAY;
+		textComp.addFocusListener(this);
+		registerListeners();
+		updateState();
+		if (!this.textComp.hasFocus()) {
+			focusLost(null);
+		}
+	}
+
+	public void delete() {
+		unregisterListeners();
+		textComp.removeFocusListener(this);
+	}
+
+	private void registerListeners() {
+		textComp.getDocument().addDocumentListener(this);
+		textComp.addPropertyChangeListener("foreground", this);
+	}
+
+	private void unregisterListeners() {
+		textComp.getDocument().removeDocumentListener(this);
+		textComp.removePropertyChangeListener("foreground", this);
+	}
+
+	public Color getGhostColor() {
+		return ghostColor;
+	}
+
+	public void setGhostColor(Color ghostColor) {
+		this.ghostColor = ghostColor;
+	}
+
+	private void updateState() {
+		isEmpty = textComp.getText().length() == 0;
+		foregroundColor = textComp.getForeground();
+	}
+
+	@Override
+	public void focusGained(FocusEvent e) {
+		if (isEmpty) {
+			unregisterListeners();
+			try {
+				textComp.setText("");
+				textComp.setForeground(foregroundColor);
+			} finally {
+				registerListeners();
+			}
+		}
+	}
+
+	@Override
+	public void focusLost(FocusEvent e) {
+		if (isEmpty) {
+			unregisterListeners();
+			try {
+				textComp.setText(ghostText);
+				textComp.setForeground(ghostColor);
+			} finally {
+				registerListeners();
+			}
+		}
+	}
+
+	@Override
+	public void propertyChange(PropertyChangeEvent evt) {
+		updateState();
+	}
+
+	@Override
+	public void changedUpdate(DocumentEvent e) {
+		updateState();
+	}
+
+	@Override
+	public void insertUpdate(DocumentEvent e) {
+		updateState();
+	}
+
+	@Override
+	public void removeUpdate(DocumentEvent e) {
+		updateState();
+	}
+
+}

+ 81 - 0
src/main/lombok/org/leumasjaffe/recipe/view/TagInputPanel.java

@@ -0,0 +1,81 @@
+package org.leumasjaffe.recipe.view;
+
+import javax.imageio.ImageIO;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.JTextField;
+
+import org.leumasjaffe.recipe.controller.GhostTextController;
+
+@SuppressWarnings("serial")
+public class TagInputPanel extends JPanel {
+	private static final Icon X_MARK;
+	static {
+		BufferedImage tmp = null;
+		try {
+			tmp = ImageIO.read(new File("src/main/resources/x-mark.png"));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		X_MARK = new ImageIcon(tmp);
+	}
+	
+	private final class TagField extends JPanel {
+		private TagField(final String value) {
+			setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
+			add(new JLabel(value));
+			JButton btnRemove = new JButton(X_MARK);
+			btnRemove.setPreferredSize(new Dimension(10, 10));
+			add(btnRemove);
+			btnRemove.addActionListener(e -> {
+				setVisible(false);
+				TagInputPanel.this.remove(this);
+				TagInputPanel.this.revalidate();
+			});
+		}
+	}
+	
+	private JTextField textField;
+
+	public TagInputPanel() {
+		setLayout(new FlowLayout(FlowLayout.LEADING, 5, 5));
+		
+		textField = new JTextField();
+		new GhostTextController(textField, "Tags...");
+		add(textField);
+		textField.setColumns(10);
+		
+		textField.addKeyListener(new KeyListener() {
+			@Override public void keyTyped(KeyEvent e) {}
+			@Override public void keyReleased(KeyEvent e) {}
+			
+			@Override
+			public void keyPressed(KeyEvent e) {
+				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
+					pushTag(textField.getText());
+					textField.setText("");
+				}
+			}
+		});
+	}
+
+	private void pushTag(final String tag) {
+		remove(textField);
+		add(new TagField(tag));
+		add(textField);
+		revalidate();
+		textField.requestFocus();
+	}
+}

+ 15 - 8
src/main/lombok/org/leumasjaffe/recipe/view/summary/SummaryPanel.java

@@ -20,6 +20,7 @@ import org.leumasjaffe.recipe.model.Element;
 import org.leumasjaffe.recipe.model.RecipeCard;
 import org.leumasjaffe.recipe.view.CollatedDurationPanel;
 import org.leumasjaffe.recipe.view.ImagePanel;
+import org.leumasjaffe.recipe.view.TagInputPanel;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
@@ -49,9 +50,9 @@ public class SummaryPanel extends JPanel {
 		
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 0, 0};
-		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0};
+		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0};
 		gridBagLayout.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
-		gridBagLayout.rowWeights = new double[]{0.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
+		gridBagLayout.rowWeights = new double[]{0.0, 1.0, 1.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
 		
 		JPanel panelHeader = new JPanel();
@@ -115,7 +116,7 @@ public class SummaryPanel extends JPanel {
 		
 		JPanel panelIngredients = new JPanel();
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
-		gbc_panelIngredients.insets = new Insets(0, 0, 5, 5);
+		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
 		gbc_panelIngredients.fill = GridBagConstraints.BOTH;
 		gbc_panelIngredients.gridx = 0;
 		gbc_panelIngredients.gridy = 2;
@@ -125,16 +126,15 @@ public class SummaryPanel extends JPanel {
 		JPanel panel = new JPanel();
 		GridBagConstraints gbc_panel = new GridBagConstraints();
 		gbc_panel.gridheight = 2;
-		gbc_panel.insets = new Insets(0, 0, 5, 0);
 		gbc_panel.fill = GridBagConstraints.BOTH;
 		gbc_panel.gridx = 1;
 		gbc_panel.gridy = 1;
 		add(panel, gbc_panel);
 		GridBagLayout gbl_panel = new GridBagLayout();
 		gbl_panel.columnWidths = new int[]{0, 0};
-		gbl_panel.rowHeights = new int[]{0, 0, 0};
+		gbl_panel.rowHeights = new int[]{0, 0, 0, 0};
 		gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE};
-		gbl_panel.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
+		gbl_panel.rowWeights = new double[]{0.0, 0.0, 1.0, Double.MIN_VALUE};
 		panel.setLayout(gbl_panel);
 		
 		JPanel panelPhoto = new ImagePanel();
@@ -145,14 +145,21 @@ public class SummaryPanel extends JPanel {
 		gbc_panelPhoto.gridy = 0;
 		panel.add(panelPhoto, gbc_panelPhoto);
 		
+		JPanel panelTags = new TagInputPanel();
+		GridBagConstraints gbc_panelTags = new GridBagConstraints();
+		gbc_panelTags.insets = new Insets(0, 0, 5, 0);
+		gbc_panelTags.fill = GridBagConstraints.BOTH;
+		gbc_panelTags.gridx = 0;
+		gbc_panelTags.gridy = 1;
+		panel.add(panelTags, gbc_panelTags);
+		
 		txaDescription = new JTextArea(5, 20);
 		txaDescription.setWrapStyleWord(true);
 		txaDescription.setLineWrap(true);
 		GridBagConstraints gbc_txaDescription = new GridBagConstraints();
-		gbc_txaDescription.insets = new Insets(0, 0, 5, 0);
 		gbc_txaDescription.fill = GridBagConstraints.BOTH;
 		gbc_txaDescription.gridx = 0;
-		gbc_txaDescription.gridy = 1;
+		gbc_txaDescription.gridy = 2;
 		panel.add(txaDescription, gbc_txaDescription);
 		
 		titleBinding = new TextBinding<>(txtTitle,

BIN
src/main/resources/x-mark.png