Java/Swing Components/LayeredPane
LayeredPane With Warning
/*
* Copyright (c) 2007, Romain Guy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the TimingFramework project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JLayeredPane;
import javax.swing.JTextField;
import javax.swing.OverlayLayout;
import javax.swing.text.JTextComponent;
/**
*
* @author Romain Guy
*/
public class Layers extends javax.swing.JFrame {
/** Creates new form Layers */
public Layers() {
initComponents();
addLayeredValidator();
addValidations();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.JLabel jLabel1;
javax.swing.JLabel jLabel2;
javax.swing.JLabel jLabel3;
javax.swing.JLabel jLabel4;
javax.swing.JLabel jLabel5;
javax.swing.JList jList1;
javax.swing.JScrollPane jScrollPane1;
javax.swing.JScrollPane jScrollPane2;
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
jLabel5 = new javax.swing.JLabel();
firstName = new javax.swing.JTextField();
lastName = new javax.swing.JTextField();
phoneNumber = new javax.swing.JTextField();
email = new javax.swing.JTextField();
jScrollPane2 = new javax.swing.JScrollPane();
address = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Layered Panes");
jList1.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Jeff Dinkins", "Richard Bair", "Amy Fowler", "Scott Violet", "Hans Muller", "Chris Campbell", "Chet Haase" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
jScrollPane1.setViewportView(jList1);
jLabel1.setText("First Name");
jLabel2.setText("Last Name");
jLabel3.setText("Phone");
jLabel4.setText("Email");
jLabel5.setText("Address");
address.setColumns(15);
address.setRows(5);
jScrollPane2.setViewportView(address);
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 152, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel5)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel4)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel3)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel2)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel1))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(firstName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
.add(lastName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
.add(phoneNumber, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
.add(email, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
.add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel1)
.add(firstName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel2)
.add(lastName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel3)
.add(phoneNumber, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel4)
.add(email, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jLabel5)
.add(jScrollPane2))
.add(6, 6, 6))
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
.addContainerGap())
);
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-489)/2, (screenSize.height-266)/2, 489, 266);
}// </editor-fold>//GEN-END:initComponents
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Layers().setVisible(true);
}
});
}
private void addLayeredValidator() {
validator = new Validator();
JLayeredPane layeredPane = getRootPane().getLayeredPane();
layeredPane.setLayout(new OverlayLayout(layeredPane));
layeredPane.add(validator, (Integer) (JLayeredPane.DEFAULT_LAYER + 50));
//validator.setBounds(0, 0, getWidth(), getHeight());
}
private void addValidations() {
addValidationForText(address);
addValidationForText(firstName);
addValidationForText(lastName);
addValidationForNumber(phoneNumber);
addValidationForEmail(email);
}
private void addValidationForText(JTextComponent field) {
field.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent focusEvent) {
}
public void focusLost(FocusEvent focusEvent) {
JTextComponent field = (JTextComponent) focusEvent.getComponent();
String text = field.getText();
if (text.matches("[-A-Za-z ]*")) {
validator.addWarning(field);
} else {
validator.removeWarning(field);
}
}
});
}
private void addValidationForNumber(JTextComponent field) {
field.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent focusEvent) {
}
public void focusLost(FocusEvent focusEvent) {
JTextField field = (JTextField) focusEvent.getComponent();
String text = field.getText();
if (text.matches("[-()0-9 ]*")) {
validator.addWarning(field);
} else {
validator.removeWarning(field);
}
}
});
}
private void addValidationForEmail(JTextComponent field) {
field.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent focusEvent) {
}
public void focusLost(FocusEvent focusEvent) {
JTextComponent field = (JTextComponent) focusEvent.getComponent();
String text = field.getText();
if (text.matches("[^@]+@([^.]+\\.)+[^.]+")) {
validator.addWarning(field);
} else {
validator.removeWarning(field);
}
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextArea address;
private javax.swing.JTextField email;
private javax.swing.JTextField firstName;
private javax.swing.JTextField lastName;
private javax.swing.JTextField phoneNumber;
// End of variables declaration//GEN-END:variables
private Validator validator;
}
/*
* Copyright (c) 2007, Romain Guy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the TimingFramework project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
*
* @author Romain Guy <romain.guy@mac.ru>
*/
class Validator extends JComponent {
private Set<JComponent> invalidFields = new HashSet<JComponent>();
private BufferedImage warningIcon;
/** Creates a new instance of Validator */
public Validator() {
loadImages();
}
public void addWarning(JComponent field) {
if (invalidFields.contains(field)) {
invalidFields.remove(field);
repaintBadge(field);
}
}
public void removeWarning(JComponent field) {
invalidFields.add(field);
repaintBadge(field);
}
private void repaintBadge(JComponent field) {
Point p = field.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(p, this);
int x = p.x - warningIcon.getWidth() / 2;
int y = (int) (p.y + field.getHeight() - warningIcon.getHeight() / 1.5);
repaint(x, y, warningIcon.getWidth(), warningIcon.getHeight());
}
private void loadImages() {
try {
warningIcon = ImageIO.read(getClass().getResource("dialog-warning.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
protected void paintComponent(Graphics g) {
for (JComponent invalid : invalidFields) {
if (invalid.getParent() instanceof JViewport) {
JViewport viewport = (JViewport) invalid.getParent();
// the parent of the viewport is a JScrollPane
invalid = (JComponent) viewport.getParent();
}
Point p = invalid.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(p, this);
int x = p.x - warningIcon.getWidth() / 2;
int y = (int) (p.y + invalid.getHeight() - warningIcon.getHeight() / 1.5);
if (g.getClipBounds().intersects(x, y,
warningIcon.getWidth(), warningIcon.getHeight())) {
g.drawImage(warningIcon, x, y, null);
}
}
}
}