com.lyonesgamer.propertygrid.properties.FontProperty Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JPropertyGrid Show documentation
Show all versions of JPropertyGrid Show documentation
A property editor component for Swing.
The newest version!
package com.lyonesgamer.propertygrid.properties;
import com.lyonesgamer.propertygrid.PGProperty;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
/**
* Represents a font, either system or custom.
*
* @author Tristan Patch
* @since 1.0
*/
public class FontProperty extends PGProperty {
/**
* The current value of the property.
*/
protected Font value;
/**
* An array of all the fonts installed on this system. Cached here for quick access.
*/
protected static Font[] systemFonts;
/**
* The editor to use.
*/
protected FontEditor editor = new FontEditor();
/**
* The renderer to use.
*/
protected FontRenderer renderer = new FontRenderer();
static {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font[] fonts = env.getAllFonts();
systemFonts = new Font[fonts.length];
for (int i = 0; i < fonts.length; i++)
systemFonts[i] = fonts[i].deriveFont(12.f);
}
/**
* Creates a new property.
*
* @param name The name of the property in the grid.
* @param value The initial value of the property.
*/
public FontProperty(String name, Font value) {
super(name);
this.value = value;
}
@Override
protected void doAfterAdded() {}
/**
* Validates the property. Until a better scheme can be decided, determines if the font is capable of displaying
* the sentence "the quick brown fox jumps over the lazy dog", which contains all English letters. The problem with
* this is it would mark CJK fonts as invalid.
*
* @param value The value to be validated.
* @return If the property is valid according to these rules.
*/
@Override
public boolean onValidateValue(Font value) {
return value.canDisplayUpTo("the quick brown fox jumps over the lazy dog") == -1;
}
@Override
public void onSetValue(Font value) {
if (parent != null)
parent.firePropertyChangeEvent(this, value);
this.value = value;
}
/**
* Attempts to decode the value as a font (using {@link Font#decode(String)}). If this fails, attempts to read the font
* as a filename.
*
* @param value The string to attempt to set from.
*/
@Override
public void setValueFromString(String value) {
Font f = Font.decode(value);
if (value.contains(f.getFontName()) || f.getFontName().contains(value))
setValue(f);
else {
try {
setValue(Font.createFont(Font.PLAIN, new File(value)).deriveFont(12.f));
} catch (FontFormatException | IOException ignored) {
}
}
}
@Override
public void setValueFromLong(long value) {}
@Override
public Font getValue() {
return value;
}
/**
* Attempts to decode the value as a font (using {@link Font#decode(String)}). If this fails, attempts to read the font
* as a filename.
*
* @param value The string to attempt to set from.
*/
@Override
public Font stringToValue(String value) {
Font f = Font.decode(value);
if (value.contains(f.getFontName()) || f.getFontName().contains(value))
return f;
else {
try {
return Font.createFont(Font.PLAIN, new File(value));
} catch (FontFormatException | IOException e) {
return null;
}
}
}
/**
* Not implemented.
*
* @param value The value to convert to a value type of this property.
* @return An empty Optional.
*/
@Override
public Font longToValue(long value) {
return null;
}
/**
* If the value is a valid font, returns the system name of the font.
*
* @param value The value to convert.
* @return The name of the font, or an empty string if invalid.
*/
@Override
public String valueToString(Font value) {
if (value == null)
return "";
return value.getFontName();
}
@Override
public PGCellRenderer getRenderer() {
return renderer;
}
@Override
public PGCellEditor getEditor() {
return editor;
}
protected class FontEditor extends JComboBox implements PGCellEditor, ActionListener {
//No need to use an EventListenerList if we only have one listener type
protected final List listeners = new ArrayList<>();
protected final Set listenersToRemove = new HashSet<>();
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
for (Font font : systemFonts)
this.addItem(font);
if (value instanceof Font)
this.setSelectedItem(value);
this.addActionListener(this);
return this;
}
@Override
public ListCellRenderer getRenderer() {
return new FontCellRenderer();
}
@Override
public void actionPerformed(ActionEvent e) {
onSetValue((Font)this.getSelectedItem());
}
@Override
public Object getCellEditorValue() {
return valueToString(getValue());
}
@Override
public boolean isCellEditable(EventObject anEvent) {
return !disabled;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
@Override
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
@Override
public void cancelCellEditing() {
fireEditingCancelled();
}
public void fireEditingCancelled() {
ChangeEvent event = new ChangeEvent(this);
for (CellEditorListener l : listeners)
l.editingCanceled(event);
doClearListeners();
}
public void fireEditingStopped() {
ChangeEvent event = new ChangeEvent(this);
for (CellEditorListener l : listeners)
l.editingStopped(event);
doClearListeners();
}
@Override
public void addCellEditorListener(CellEditorListener l) {
listeners.add(l);
}
@Override
public void removeCellEditorListener(CellEditorListener l) {
listenersToRemove.add(l);
}
protected void doClearListeners() {
listeners.removeAll(listenersToRemove);
listenersToRemove.clear();
}
}
protected class FontRenderer extends JComboBox implements PGCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
for (Font font : systemFonts)
this.addItem(font);
this.setSelectedItem(value);
setToolTipText(helpString);
return this;
}
@Override
public ListCellRenderer getRenderer() {
return new FontCellRenderer();
}
}
protected class FontCellRenderer extends JLabel implements ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Font value, int index, boolean isSelected, boolean cellHasFocus) {
this.setText(value.getFontName());
this.setFont(value);
return this;
}
}
}