Durante meus estudos sobre programação com Java Swing percebi que muitos programadores desenvolvem seus próprios componentes. Isto é, ao invés de criarem diretamente um novo componente Swing pela IDE e editá-lo na ferramenta padrão de design, criam classes Java que estendem a classe do componente, sobrescrevendo seus métodos. Assim, quase toda a programação dos componentes visuais acontece através de código e nem tanto com o drag and drop.
Gostaria de entender se há alguma vantagem nisso. É mais aconselhável criar seus próprios componentes Java Swing ou apenas arrastá-los para o editor da IDE, modificando as propriedades que ali estão?
A título de exemplo, deixo aqui um código que encontrei que amplia a classe JTextField do Java Swing. Ela requer para seu funcionamento que esteja instalada no projeto a biblioteca TimingFramework: TimingFramework-0.55.jar (100,8,KB)
package main;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.TimingTarget;
import org.jdesktop.animation.timing.TimingTargetAdapter;
public class TextField extends JTextField {
public String getHelperText() {
return helperText;
}
public void setHelperText(String helperText) {
this.helperText = helperText;
repaint();
}
public String getLabelText() {
return labelText;
}
public void setLabelText(String labelText) {
this.labelText = labelText;
}
public Color getLineColor() {
return lineColor;
}
public void setLineColor(Color lineColor) {
this.lineColor = lineColor;
}
private final Animator animator;
private boolean animateHinText = true;
private float location;
private boolean show;
private boolean mouseOver = false;
private String labelText = "Label";
private String helperText = "";
private int spaceHelperText = 15;
private Color lineColor = new Color(3, 155, 216);
public TextField() {
setBorder(new EmptyBorder(20, 3, 23, 3));
setSelectionColor(new Color(76, 204, 255));
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
mouseOver = true;
repaint();
}
@Override
public void mouseExited(MouseEvent me) {
mouseOver = false;
repaint();
}
});
addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent fe) {
showing(false);
}
@Override
public void focusLost(FocusEvent fe) {
showing(true);
}
});
TimingTarget target = new TimingTargetAdapter() {
@Override
public void begin() {
animateHinText = getText().equals("");
}
@Override
public void timingEvent(float fraction) {
location = fraction;
repaint();
}
};
animator = new Animator(300, target);
animator.setResolution(0);
animator.setAcceleration(0.5f);
animator.setDeceleration(0.5f);
}
private void showing(boolean action) {
if (animator.isRunning()) {
animator.stop();
} else {
location = 1;
}
animator.setStartFraction(1f - location);
show = action;
location = 1f - location;
animator.start();
}
@Override
public void paint(Graphics grphcs) {
super.paint(grphcs);
Graphics2D g2 = (Graphics2D) grphcs;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
int width = getWidth();
int height = getHeight();
if (mouseOver) {
g2.setColor(lineColor);
} else {
g2.setColor(new Color(150, 150, 150));
}
g2.fillRect(2, height - spaceHelperText - 1, width - 4, 1);
createHintText(g2);
createLineStyle(g2);
createHelperText(g2);
g2.dispose();
}
private void createHintText(Graphics2D g2) {
Insets in = getInsets();
g2.setColor(new Color(150, 150, 150));
FontMetrics ft = g2.getFontMetrics();
Rectangle2D r2 = ft.getStringBounds(labelText, g2);
double height = getHeight() - in.top - in.bottom;
double textY = (height - r2.getHeight()) / 2;
double size;
if (animateHinText) {
if (show) {
size = 18 * (1 - location);
} else {
size = 18 * location;
}
} else {
size = 18;
}
g2.drawString(labelText, in.right, (int) (in.top + textY + ft.getAscent() - size));
}
private void createLineStyle(Graphics2D g2) {
if (isFocusOwner()) {
double width = getWidth() - 4;
int height = getHeight() - spaceHelperText;
g2.setColor(lineColor);
double size;
if (show) {
size = width * (1 - location);
} else {
size = width * location;
}
double x = (width - size) / 2;
g2.fillRect((int) (x + 2), height - 2, (int) size, 2);
}
}
private void createHelperText(Graphics2D g2) {
if (helperText != null && !helperText.equals("")) {
Insets in = getInsets();
int height = getHeight() - 15;
g2.setColor(new Color(255, 76, 76));
Font font = getFont();
g2.setFont(font.deriveFont(0, font.getSize() - 1));
FontMetrics ft = g2.getFontMetrics();
Rectangle2D r2 = ft.getStringBounds(labelText, g2);
double textY = (15 - r2.getHeight()) / 2f;
g2.drawString(helperText, in.right, (int) (height + ft.getAscent() - textY));
}
}
@Override
public void setText(String string) {
if (!getText().equals(string)) {
showing(string.equals(""));
}
super.setText(string);
}
}
Desde já, agradeço e peço perdão se a pergunta for muito iniciante.