. , combobox, , , , . , , ,
JXLayer ( JLayer, ), API InputVerifer, , , . , , ;).
Pushing Pixels, JXLayer
, , , ... ... ;)

...
import com.jhlabs.image.GaussianFilter;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import javax.swing.InputVerifier;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.plaf.AbstractLayerUI;
public class FormValidationExample {
public static void main(String[] args) {
new FormValidationExample();
}
public FormValidationExample() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JXLayer<JPanel> layer;
private javax.swing.JComboBox cboOne;
private javax.swing.JTextField txtOne;
private javax.swing.JTextField txtTwo;
private DefaultValidationHighlightModel validationModel;
private boolean ignoreValidationRequest;
public TestPane() {
setLayout(new BorderLayout());
JPanel content = new JPanel(new GridBagLayout());
ValidationUI ui = new ValidationUI();
validationModel = new DefaultValidationHighlightModel(ui);
layer = new JXLayer<>(content, ui);
add(layer);
cboOne = new javax.swing.JComboBox();
cboOne.setInputVerifier(new AbstractValidationInputVerifier(validationModel) {
@Override
public boolean verify(JComponent input) {
boolean valid = false;
JComboBox cb = (JComboBox) input;
String textOfOne = txtOne.getText();
String textOfTwo = txtTwo.getText();
if (cb.getSelectedIndex() == 2) {
valid = true;
} else if (cb.getSelectedIndex() == 0
&& "123".equals(textOfOne)
&& "456".equals(textOfTwo)) {
valid = true;
} else if (cb.getSelectedIndex() == 1
&& "456".equals(textOfOne)
&& "789".equals(textOfTwo)) {
valid = true;
}
return valid;
}
});
txtOne = new javax.swing.JTextField("123", 10);
txtOne.setInputVerifier(new AbstractValidationInputVerifier(validationModel) {
@Override
public boolean verify(JComponent input) {
JTextField field = (JTextField) input;
String text = field.getText();
return "123".equals(text) || "456".equals(text);
}
});
txtTwo = new javax.swing.JTextField("123", 10);
txtTwo.setInputVerifier(new AbstractValidationInputVerifier(validationModel) {
@Override
public boolean verify(JComponent input) {
JTextField field = (JTextField) input;
String text = field.getText();
return "456".equals(text) || "789".equals(text);
}
});
cboOne.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Only works with 123, 456", "Only works with 456, 789", "Works with everybody"}));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(4, 4, 4, 4);
content.add(cboOne, gbc);
content.add(txtOne, gbc);
content.add(txtTwo, gbc);
validateFields();
}
protected void validateFields() {
if (!ignoreValidationRequest) {
ignoreValidationRequest = true;
try {
cboOne.getInputVerifier().shouldYieldFocus(cboOne);
txtOne.getInputVerifier().shouldYieldFocus(txtOne);
txtTwo.getInputVerifier().shouldYieldFocus(txtTwo);
} finally {
ignoreValidationRequest = false;
}
}
}
public abstract class AbstractValidationInputVerifier extends InputVerifier {
private IValidationHighlightModel model;
public AbstractValidationInputVerifier(IValidationHighlightModel model) {
this.model = model;
}
public IValidationHighlightModel getModel() {
return model;
}
@Override
public boolean shouldYieldFocus(JComponent input) {
if (verify(input)) {
getModel().removeInvalidField(input);
} else {
getModel().addInvalidField(input);
}
validateFields();
return true;
}
}
}
}
JXLayer, ...
public class ValidationUI extends HighlightComponentUI {
public ValidationUI() {
super(Color.RED);
}
}
public class HighlightComponentUI extends AbstractLayerUI<JPanel> {
private List<WeakReference<Component>> lstHighlights;
private Color highlightColor;
public HighlightComponentUI(Color highlight) {
highlightColor = highlight;
lstHighlights = new ArrayList<WeakReference<Component>>(25);
}
protected void cleanReferences() {
if (lstHighlights.size() > 0) {
List<WeakReference<Component>> removed = new ArrayList<WeakReference<Component>>(lstHighlights.size());
for (WeakReference<Component> wr : lstHighlights) {
Component weak = wr.get();
if (weak == null) {
removed.add(wr);
}
}
lstHighlights.removeAll(removed);
setDirty(true);
}
}
protected boolean contains(Component comp) {
boolean contains = false;
cleanReferences();
for (WeakReference<Component> wr : lstHighlights) {
Component weak = wr.get();
if (weak.equals(comp)) {
contains = true;
break;
}
}
return contains;
}
protected void clearHighlights() {
lstHighlights.clear();
setDirty(true);
}
protected void addHighlight(Component comp) {
if (comp != null) {
if (!contains(comp)) {
lstHighlights.add(new WeakReference<Component>(comp));
setDirty(true);
}
}
}
public Component[] getHighlightedComponents() {
List<Component> comps = new ArrayList<>(lstHighlights.size());
for (WeakReference<Component> wr : lstHighlights) {
Component comp = wr.get();
if (comp != null) {
comps.add(comp);
}
}
return comps.toArray(new Component[comps.size()]);
}
protected void removeHighlight(Component comp) {
cleanReferences();
WeakReference<Component> toRemove = null;
for (WeakReference<Component> wr : lstHighlights) {
Component weak = wr.get();
if (weak.equals(comp)) {
toRemove = wr;
break;
}
}
if (toRemove != null) {
lstHighlights.remove(toRemove);
setDirty(true);
}
}
public Color getHighlight() {
return highlightColor;
}
public boolean contains(Container parent, Component child) {
boolean contains = false;
if (child.getParent() != null) {
if (child.getParent().equals(parent)) {
contains = true;
} else {
for (Component comp : parent.getComponents()) {
if (comp instanceof Container) {
if (contains((Container) comp, child)) {
contains = true;
break;
}
}
}
}
}
return contains;
}
@Override
protected void paintLayer(Graphics2D g2, JXLayer<? extends JPanel> l) {
super.paintLayer(g2, l);
Graphics2D c = (Graphics2D) g2.create();
JComponent view = l.getView();
while (view instanceof JXLayer) {
view = (JComponent) ((JXLayer) view).getView();
}
for (WeakReference<Component> wr : lstHighlights) {
Component comp = wr.get();
if (comp != null && contains(view, comp)) {
BufferedImage img = new BufferedImage(comp.getWidth(), comp.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
g2d.setComposite(AlphaComposite.SrcOver);
comp.printAll(g2d);
g2d.dispose();
BufferedImage glow = GlowEffectFactory.generateGlow(img, 8, getHighlight(), 0.75f);
Point point = comp.getLocation();
point = SwingUtilities.convertPoint(comp.getParent(), point, view);
int x = point.x - ((glow.getWidth() - comp.getWidth()) / 2);
int y = point.y - ((glow.getHeight() - comp.getHeight()) / 2);
c.drawImage(glow, x, y, l);
}
}
c.dispose();
}
}
, ( interfaces abstract API , ). , ChangeListener, ...
public class DefaultValidationHighlightModel extends AbstractValidationHighlightModel {
private HighlightComponentUI ui;
public DefaultValidationHighlightModel(HighlightComponentUI ui) {
this.ui = ui;
}
@Override
public void addInvalidField(Component comp) {
if (!ui.contains(comp)) {
ui.addHighlight(comp);
fireStateChanged();
}
}
@Override
public void removeInvalidField(Component comp) {
if (ui.contains(comp)) {
ui.removeHighlight(comp);
fireStateChanged();
}
}
@Override
public Component[] getInvalidFields() {
return ui.getHighlightedComponents();
}
}
public abstract class AbstractValidationHighlightModel implements IValidationHighlightModel {
private EventListenerList listenerList;
public EventListenerList getListenerList() {
if (listenerList == null) {
listenerList = new EventListenerList();
}
return listenerList;
}
@Override
public void addChangeListener(ChangeListener listener) {
getListenerList().add(ChangeListener.class, listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
getListenerList().remove(ChangeListener.class, listener);
}
protected ChangeListener[] getChangeListeners() {
return getListenerList().getListeners(ChangeListener.class);
}
protected void fireStateChanged() {
ChangeListener[] listeners = getChangeListeners();
if (listeners != null && listeners.length > 0) {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
}
public interface IValidationHighlightModel {
public void addInvalidField(Component comp);
public void removeInvalidField(Component comp);
public Component[] getInvalidFields();
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
public static class GlowEffectFactory {
public static BufferedImage createCompatibleImage(int width, int height) {
return createCompatibleImage(width, height, Transparency.TRANSLUCENT);
}
public static BufferedImage createCompatibleImage(Dimension size) {
return createCompatibleImage(size.width, size.height);
}
public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(width, height, transparency);
image.coerceData(true);
return image;
}
public static BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
BufferedImage maskedImage = null;
if (sourceImage != null) {
int width = maskImage.getWidth(null);
int height = maskImage.getHeight(null);
maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D mg = maskedImage.createGraphics();
int x = (width - sourceImage.getWidth(null)) / 2;
int y = (height - sourceImage.getHeight(null)) / 2;
mg.drawImage(sourceImage, x, y, null);
mg.setComposite(AlphaComposite.getInstance(method));
mg.drawImage(maskImage, 0, 0, null);
mg.dispose();
}
return maskedImage;
}
public static BufferedImage generateBlur(BufferedImage imgSource, int size, Color color, float alpha) {
GaussianFilter filter = new GaussianFilter(size);
int imgWidth = imgSource.getWidth();
int imgHeight = imgSource.getHeight();
BufferedImage imgBlur = createCompatibleImage(imgWidth, imgHeight);
Graphics2D g2 = imgBlur.createGraphics();
g2.drawImage(imgSource, 0, 0, null);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha));
g2.setColor(color);
g2.fillRect(0, 0, imgSource.getWidth(), imgSource.getHeight());
g2.dispose();
imgBlur = filter.filter(imgBlur, null);
return imgBlur;
}
public static BufferedImage generateBlur(BufferedImage imgSource, int size) {
GaussianFilter filter = new GaussianFilter(size);
int imgWidth = imgSource.getWidth();
int imgHeight = imgSource.getHeight();
BufferedImage imgBlur = createCompatibleImage(imgWidth, imgHeight);
Graphics2D g2 = imgBlur.createGraphics();
g2.drawImage(imgSource, 0, 0, null);
g2.dispose();
imgBlur = filter.filter(imgBlur, null);
return imgBlur;
}
public static BufferedImage generateGlow(BufferedImage imgSource, int size, Color color, float alpha) {
int imgWidth = imgSource.getWidth() + (size * 2);
int imgHeight = imgSource.getHeight() + (size * 2);
BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight);
Graphics2D g2 = imgMask.createGraphics();
int x = Math.round((imgWidth - imgSource.getWidth()) / 2f);
int y = Math.round((imgHeight - imgSource.getHeight()) / 2f);
g2.drawImage(imgSource, x, y, null);
g2.dispose();
BufferedImage imgGlow = generateBlur(imgMask, size, color, alpha);
imgGlow = applyMask(imgGlow, imgMask, AlphaComposite.DST_OUT);
return imgGlow;
}
}
JXLayer ( 3) ( ...) SwingX ( 1.6.4)
JXLayer ( 3) Piet zip, , , , .
JHLabs