Continuación del tutorial «Google Circles en java» o.O 🙂
La Interfaz
El proyecto consta de una sola interfaz la cual es un JFrame, dentro este esta un JPanel de tamaño 400×400.
Por el momento dejamos la interfaz como esta, añadiremos algo de código al final.
Botón circular – JButtonCircle.java
Este botón se extiende un JButton pero modificando algunas de sus propiedades para eliminar los bordes y el relieve, así también se reescribe el método paintComponent para pintar una imagen de forma circular.
package google; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Cursor; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.RenderingHints; import java.awt.geom.Ellipse2D; import javax.swing.ImageIcon; import javax.swing.JButton; /** * @web https://www.jc-mouse.net/ * @author Mouse * Clase original de javaface-elblogdelprogramador */ public class JButtonCircle extends JButton { private Image image = null; private ImageIcon icono = new ImageIcon(getClass().getResource("/google/fotos/default.jpg")); /** Constructor de clase */ public JButtonCircle(){} /** * Constructor de clase * @param coord de tipo Point * Es la coordenada de la esquina superior derecha del boton */ public JButtonCircle( Point coord ) { this.setBounds( coord.x, coord.y, 60, 60 ); this.setCursor( new Cursor(Cursor.HAND_CURSOR)); this.setContentAreaFilled(false); this.setBorderPainted(false); this.setToolTipText("jc mouse"); this.image = ((ImageIcon)icono).getImage(); this.repaint(); } public void setFotografia( ImageIcon icono ) { this.image = ((ImageIcon)icono).getImage(); } public Image getFotografia() { return this.image; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); int w = getWidth(); int h = getHeight(); Graphics2D g2 = (Graphics2D)g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(new Color(255,255,255));//COLOR DE FONDO g2.fill(new Ellipse2D.Double(3, 3, w-6, h-6));//FORMA DEL BOTON g2.setColor(new Color(100, 100, 100));//COLOR DEL CONTORNO g2.drawOval(3, 3, getWidth()-7, getHeight()-7);//DIBUJO UN CIRCULO g2.setColor(new Color(255, 255, 255, 50)); g2.drawOval(3, 3, getWidth()-6, getHeight()-6); g2.setClip( new Ellipse2D.Float(3, 3, w-6,h-6) ); g2.drawImage(image,3,3, w-6,h-6,this);//PINTO LA IMAGEN EN EL BOTON g2.dispose(); } @Override protected void paintBorder(Graphics g) { int w = getWidth(); int h = getHeight(); Graphics2D g2 = (Graphics2D)g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke(new BasicStroke(1.8f)); g2.setColor(new Color(21,160,203)); g2.drawOval(3, 3, w-6 , h-6); g2.dispose(); } }//--> fin
La clase original corresponde a javaface-elblogdelprogramador, la modifique un poco para que se adecue a mis necesidades 😀
EL botón G+ -«JPanelCircle.java»
Para formar el botón de Google Plus, se hace uso de un JPanel de tamaño [400,400], en este se añaden los botones circulares (JButtonCircle) y se reescribe el método paintComponent para pintar con java2d la forma del botón circular.
Para lograr el efecto de G+, se hace uso de TimerTask para ejecutar un método cada N tiempo (5 milisegundos) paralelamente a la aplicación principal pintando según sea necesario la contracción o extensión del botón. Así también implementamos MouseListener y ActionListener para capturar los eventos sobre el JPanel y los botones y realizar las acciones correspondientes.
package google; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import javax.swing.JPanel; import java.util.Timer; import java.util.TimerTask; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JOptionPane; /** * @web https://www.jc-mouse.net/ * @author Mouse */ public class JPanelCircle extends JPanel implements MouseListener,ActionListener{ /* tamaño del JPanel circular */ private Dimension size = new Dimension( 400,400 ); //bandera boolean para saber si el cursor del mouse esta dentro o fuera del JPanel private boolean __in__ = false; private Timer timer; // private float alto_ancho = 200; //ancho de circulo private float posicionxy = 100; //coordenada de la esquina sup derecha del ciruculo /* array de botones circulares */ private JButtonCircle[] btn = new JButtonCircle[8]; /* coordenadas de los botones circulares */ private Point[] pB = { new Point(62,170), new Point(278,170) , new Point(170,64) , new Point(170,278) , new Point(90,248) , new Point(90,98) , new Point(252,98) , new Point(252,248) }; /* array de ImageIcon -> fotos para los botones */ private ImageIcon[] icono = { new ImageIcon(getClass().getResource("/google/fotos/foto1.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto2.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto3.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto4.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto5.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto6.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto7.jpg")), new ImageIcon(getClass().getResource("/google/fotos/foto8.jpg")) }; /** * ActionCommand de los 8 botones circulares */ public enum Accion { __1, __2, __3, __4, __5, __6, __7, __8 } /** * Constructor de clase */ public JPanelCircle() { this.setPreferredSize( size ); this.setSize( size ); this.setVisible(true); this.addMouseListener(this); //añade los botones circulares al jpanel circular for( int i=0; i<8 ; i++) { btn[i] = new JButtonCircle( pB[i] ); btn[i].setVisible( false ); btn[i].setActionCommand("__" + (i+1) ); btn[i].setToolTipText("Boton circular " + (i+1) ); btn[i].setFotografia( icono[i] ); btn[i].addActionListener( this ); btn[i].addMouseListener(this); this.add( btn[i] ); } //JLabel JLabel label = new JLabel(); label.setText("Bloggers"); label.setForeground( Color.white ); label.setFont( new Font("Arial", Font.PLAIN,18) ); label.setOpaque(false); label.setBounds(160, 184, 140, 30); label.setVisible(true); this.add(label); //se asigna layout al JPCircle !importante: siempre al final this.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); //inicia animacion animacion(); } @Override protected void paintComponent(Graphics g) { Graphics2D g2 =(Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //para el fondo blanco se pinta un rectangulo en todo el JPanel circular g2.setColor( new Color(255,255,255) ); Rectangle2D body = new Rectangle2D.Float(0, 0, (float) this.getSize().getWidth(), (float) this.getSize().getHeight() ); g2.fill( body ); //circulo google google_circle( g2 ); } /** * pinta el circulo utilizando java2d * @param g2 Graphics2D */ private void google_circle( Graphics2D g2 ) { //cuerpo circulo g2.setColor( new Color(232,232,232) ); Ellipse2D bcircle = new Ellipse2D.Float( posicionxy , posicionxy , alto_ancho ,alto_ancho ); g2.fill( bcircle ); //pinta borde blanco si es necesario if( alto_ancho > 251) { g2.setColor( new Color(255,255,255) ); g2.setStroke(new BasicStroke(15.0f)); Ellipse2D bcircle1 = new Ellipse2D.Float( posicionxy , posicionxy ,alto_ancho , alto_ancho); g2.draw( bcircle1 ); } //muestra botones circulares si es necesario if( alto_ancho >= 294 ) { for( int i=0; i<8 ; i++) { btn[i].setVisible(true); } } else if( alto_ancho < 288 ) //si el circulo es muy pequeño los oculta { for( int i=0; i<8 ; i++) { btn[i].setVisible(false); } } //pinta borde oscuro g2.setColor( new Color(155,155,155) ); g2.setStroke(new BasicStroke( 3.0f) ); Ellipse2D bcircle2 = new Ellipse2D.Float(posicionxy ,posicionxy ,alto_ancho , alto_ancho ); g2.draw( bcircle2 ); //-------------------------------------------------------------------// //pinta el circulo interior azul g2.setColor( new Color(71,151,207) ); Ellipse2D circle_int = new Ellipse2D.Float(125.0f ,125.0f ,150.0f ,150.0f); g2.fill( circle_int ); //borde g2.setColor( new Color(61,129,177) ); g2.setStroke(new BasicStroke(2.0f)); Ellipse2D bc2 = new Ellipse2D.Float(125.0f ,125.0f ,150.0f ,150.0f); g2.draw( bc2 ); //-------------------------------------------------------------------// } /** * Se hace uso de un Timerpara la animacion del google circle * cuando el raton esta dentro del JPanel se expande, si esta fuera decrece * la velocidad se mide en milisegundo, en este caso se hace uso de 5 milisegundos */ public void animacion() { TimerTask task = new TimerTask() { @Override public void run() { if( __in__ ) //Si raton esta dentro de JPCircle -> crece { if( alto_ancho <= 300 ) { alto_ancho = alto_ancho + 1; posicionxy = posicionxy - 0.5f ; } } else //Si raton esta fuera de JPCircle -> decrece { if( alto_ancho > 200 ) { alto_ancho = alto_ancho - 1; posicionxy = posicionxy + 0.5f ; } } repaint(); } }; timer = new Timer(); timer.schedule(task, 0, 5 ); } //-----------------------------------------------------------------------// // Eventos del raton @Override public void mouseClicked(MouseEvent e) { /*...*/ } @Override public void mousePressed(MouseEvent e) { /*...*/ } @Override public void mouseReleased(MouseEvent e) { /*...*/ } @Override public void mouseEntered(MouseEvent e) { __in__ = true; // si raton esta dentro del JPCircle if( e.getComponent() instanceof JPanelCircle ) { System.out.println ( " dentro el JPanelCircle " ); } // si esta dentro de algun boton else if(e.getComponent() instanceof JPanelCircle ) { System.out.println ( " dentro un boton " ); //tamaño fijo del google circle para evitar que este se colapse //mientras se esta dentro de un boton alto_ancho = 300; posicionxy = 50; } this.repaint(); } @Override public void mouseExited(MouseEvent e) { __in__ = false; if( e.getComponent() instanceof JPanelCircle ) { System.out.println ( " fuera del JPanelCircle " ); } this.repaint(); } /** * Aqui se deben colocar las acciones que se llevaran a cabo cuando se presione * algunos de los botones circulares * @param e ActionEvent */ @Override public void actionPerformed(ActionEvent e) { switch ( Accion.valueOf( e.getActionCommand() ) ) { case __1: JOptionPane.showMessageDialog(null,"Se presiono el boton 1" ); break; case __2: JOptionPane.showMessageDialog(null,"Se presiono el boton 2" ); break; case __3: JOptionPane.showMessageDialog(null,"Se presiono el boton 3" ); break; case __4: JOptionPane.showMessageDialog(null,"Se presiono el boton 4" ); break; case __5: JOptionPane.showMessageDialog(null,"Se presiono el boton 5" ); break; case __6: JOptionPane.showMessageDialog(null,"Se presiono el boton 6" ); break; case __7: JOptionPane.showMessageDialog(null,"Se presiono el boton 7" ); break; case __8: JOptionPane.showMessageDialog(null,"Se presiono el boton 8" ); break; } } }//--> fin
Importante: Ambas clases están debidamente comentadas y trate de ser lo mas explicito posible 🙂 si existe alguna duda solo pregunten.
Ya para terminar el tutorial, debemos implementar esta clase JPanelCircle.java en la interfaz, nada mas simple como modificar el constructor de la siguiente forma:
public Interfaz() { initComponents(); this.setTitle("Google Circle - [https://www.jc-mouse.net/]"); this.setLocationRelativeTo(null); JPanelCircle jpc = new JPanelCircle(); this.jPanel1.add( jpc ); }
Nuestro resultado final
Proyecto completo en este enlace pobre
F I N 🙂
Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.
Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye
Enjoy! :)
En este post, crearemos una aplicación java que nos permita arrastrar un archivo excel hacia la aplicación, abrirlo y ca...
Launch4j es un software OpenSource hecho en Java que permite crear ejecutables para programas escritos en ese mismo leng...
En este tutorial crearemos un lector de Feeds en Java/netbeans, pero antes debemosa saber que es un Feed, según Santa Wi...
SDKMAN! es una herramienta para la administración de versiones paralelas de varios programas de desarrollo de software c...
NetBeans es un entorno de desarrollo integrado libre, hecho principalmente para el lenguaje de programación Java. Sin em...
En esta oportunidad construiremos una aplicación android que nos permitirá consumir un servicio web utilizando la libre...
Los comentarios estan cerrados
Shutter Encoder es un software de conversión de video el cual tambien maneja audio e imagenes. Su interfaz de usuario ha...
Desde su lanzamiento Midjorney se posiciono como la inteligencia artificial (IA) número uno (junto a Dall-E) generativa...
Las herramientas con Inteligencia Artifical cada vez son mas comunes y en los usos mas variados. En esta oportunidad les...
¿Qué es un Patrón de Diseño? «Los patrones de diseño (design patterns) son soluciones habituales a problemas comunes en...
Buenos tutoriales. Gracias me han ayudado bastante en mis proyectos!! sigue asi
Muchas gracias por compartir tus conocimientos.
Excelente aporte, he utilizado tu código para un trabajo de la universidad (Debidamente documentado e indicando mi fuente), y lo modifique de forma que cada botón me lleve a una ventana diferente, mi pregunta es como detengo las clases y cierro con un disponse cuando se abra la otra ventana, muchas gracias por la ayuda.