Olá pessoal,
Estou a tentar pintar a stroke de uma shape sempre que passo com o rato por cima dela, mas não tou a conseguir.
Segue o código da classe que extende a JFrame:
package dblauncher;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public class DBLauncher extends JFrame
{
public static void main(String args[]) throws IOException
{
DBLauncher dbLauncher = new DBLauncher();
dbLauncher.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dbLauncher.setVisible(true);
}
//Construtor: serve apenas para inicializar o objeto e não para executar quaisquer ações sobre ele
public DBLauncher() throws IOException
{
super("Database Launcher v1.0");
setSize(500, 500);
setLocation(430, 150);
setResizable(false);
DBPanel panel = new DBPanel();
Container container = getContentPane();
container.setLayout(new BorderLayout()); //Usar BorderLayout
container.add(panel, BorderLayout.CENTER); //Inserir o panel no centro do BorderLayout
}
}
final class DBPanel extends JPanel implements MouseListener, MouseMotionListener
{
private final float musicShapePosX = 85.0f;
private float musicShapePosY = 100.0f;
private final float tvShapePosX = 184.0f;
private final float tvShapePosY = 164.0f;
private final float gamesShapePosX = 283.0f;
private final float gamesShapePosY = 100.0f;
private final float booksShapePosX = 283.0f;
private final float booksShapePosY = 228.0f;
private final float techShapePosX = 184.0f;
private final float techShapePosY = 293.0f;
private final float SEGMENT_SHAPE_LENGTH = 50.0f;
private final float SHAPE_HEIGHT = 10.0f;
private float SHAPE_SPEED = 7.5f;
private final CustomShapeButton musicShapeButton;
private final CustomShapeButton tvShapeButton;
private final CustomShapeButton gamesShapeButton;
private final CustomShapeButton booksShapeButton;
private final CustomShapeButton techShapeButton;
private final ArrayList<CustomShapeButton> shapeButtons;
private boolean musicButtonPressed = false;
private boolean tvButtonPressed = false;
private boolean gamesButtonPressed = false;
private boolean booksButtonPressed = false;
private boolean techButtonPressed = false;
private boolean buttonStop = true;
public DBPanel() throws IOException
{
BufferedImage musicShapeImage = ImageIO.read(getClass().getResource("/images/imageWoodMusic.png"));
BufferedImage tvShapeImage = ImageIO.read(getClass().getResource("/images/imageWoodTv.png"));
BufferedImage gamesShapeImage = ImageIO.read(getClass().getResource("/images/imageWoodGames.png"));
BufferedImage booksShapeImage = ImageIO.read(getClass().getResource("/images/imageWoodBooks.png"));
BufferedImage techShapeImage = ImageIO.read(getClass().getResource("/images/imageWoodTech.png"));
shapeButtons = new ArrayList();
musicShapeButton = new CustomShapeButton(musicShapePosX, musicShapePosY, SEGMENT_SHAPE_LENGTH, SHAPE_HEIGHT, musicShapeImage);
musicShapeButton.setBackground(Color.LIGHT_GRAY);
musicShapeButton.setForeground(Color.WHITE);
shapeButtons.add(musicShapeButton);
tvShapeButton = new CustomShapeButton(tvShapePosX, tvShapePosY, SEGMENT_SHAPE_LENGTH, SHAPE_HEIGHT, tvShapeImage);
tvShapeButton.setBackground(Color.LIGHT_GRAY);
tvShapeButton.setForeground(Color.WHITE);
shapeButtons.add(tvShapeButton);
gamesShapeButton = new CustomShapeButton(gamesShapePosX, gamesShapePosY, SEGMENT_SHAPE_LENGTH, SHAPE_HEIGHT, gamesShapeImage);
gamesShapeButton.setBackground(Color.LIGHT_GRAY);
gamesShapeButton.setForeground(Color.WHITE);
shapeButtons.add(gamesShapeButton);
booksShapeButton = new CustomShapeButton(booksShapePosX, booksShapePosY, SEGMENT_SHAPE_LENGTH, SHAPE_HEIGHT, booksShapeImage);
booksShapeButton.setBackground(Color.LIGHT_GRAY);
booksShapeButton.setForeground(Color.WHITE);
shapeButtons.add(booksShapeButton);
techShapeButton = new CustomShapeButton(techShapePosX, techShapePosY, SEGMENT_SHAPE_LENGTH, SHAPE_HEIGHT, techShapeImage);
techShapeButton.setBackground(Color.LIGHT_GRAY);
techShapeButton.setForeground(Color.WHITE);
shapeButtons.add(techShapeButton);
this.setOpaque(false);
this.setFocusable(true);
this.addMouseListener(this);
this.addMouseMotionListener(this);
Thread thread = new Thread(() -> animate());
thread.start();
}
public void delay(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException e)
{
}
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(getBackground().darker());
g2.fillRect(0, 0, getWidth(), getHeight());
for (CustomShapeButton shapeButton : shapeButtons)
{
shapeButton.paintComponent(g2);
}
}
@SuppressWarnings({"SleepWhileInLoop", "empty-statement"})
public synchronized void animate()
{
while (true)
{
if (musicButtonPressed == true)
{
animateButtonShapeMusic();
}
else if (tvButtonPressed == true)
{
animateButtonShapeTv();
}
else if (gamesButtonPressed == true)
{
animateButtonShapeGames();
}
else if (booksButtonPressed == true)
{
animateButtonShapeBooks();
}
else if (techButtonPressed == true)
{
animateButtonShapeTech();
}
delay(35);
repaint();
}
}
@Override
public void mouseClicked(MouseEvent me)
{
for (int i = 0; i < shapeButtons.size(); i++)
{
Shape shape = shapeButtons.get(i);
//Mostrar os icones respetivos, consoante o botão seleccionado (if's)
if (shape.contains(me.getPoint()))
{
switch (i)
{
case 0:
{
buttonStop = false;
musicButtonPressed = true;
System.out.println("Clicked on shape number " + i + " that represents the music button!");
break;
}
case 1:
{
tvButtonPressed = true;
System.out.println("Clicked on shape number " + i + " that represents the tv button!");
break;
}
case 2:
{
gamesButtonPressed = true;
System.out.println("Clicked on shape number " + i + " that represents the games button!");
break;
}
case 3:
{
booksButtonPressed = true;
System.out.println("Clicked on shape number " + i + " that represents the books button!");
break;
}
case 4:
{
techButtonPressed = true;
System.out.println("Clicked on shape number " + i + " that represents the tech button!");
break;
}
default: break;
}
}
}
}
@Override
public void mouseEntered(MouseEvent me)
{
}
@Override
public void mousePressed(MouseEvent me)
{
}
@Override
public void mouseReleased(MouseEvent me)
{
}
@Override
public void mouseExited(MouseEvent me)
{
}
@Override
public void mouseDragged(MouseEvent me)
{
}
@Override
public void mouseMoved(MouseEvent me)
{
for (int i = 0; i < shapeButtons.size(); i++)
{
Shape shape = shapeButtons.get(i);
//Mostrar os icones respetivos, consoante o botão seleccionado (if's)
if (shape.contains(me.getPoint()))
{
switch (i)
{
case 0:
{
musicShapeButton.setBorder(BorderFactory.createLineBorder(Color.red, 4));
musicShapeButton.revalidate();
musicShapeButton.repaint();
System.out.println("Entered on shape number " + i + " that represents the music button!");
break;
}
case 1:
{
tvShapeButton.setBorder(BorderFactory.createLineBorder(Color.red, 4));
tvShapeButton.revalidate();
tvShapeButton.repaint();
System.out.println("Entered on shape number " + i + " that represents the tv button!");
break;
}
case 2:
{
System.out.println("Entered on shape number " + i + " that represents the games button!");
break;
}
case 3:
{
System.out.println("Entered on shape number " + i + " that represents the books button!");
break;
}
case 4:
{
System.out.println("Entered on shape number " + i + " that represents the tech button!");
break;
}
default: break;
}
}
}
}
public void animateButtonShapeMusic()
{
if ((musicShapePosY <= 227.5f) && (buttonStop == false))
{
musicShapePosY = musicShapePosY + SHAPE_SPEED;
SHAPE_SPEED = SHAPE_SPEED * (-1);
if ((musicShapePosY == 227.5f) || (musicShapePosY == 100.0f))
{
buttonStop = true;
}
}
if ((musicShapePosY >= 100.0f) && (buttonStop == false))
{
musicShapePosY = musicShapePosY - SHAPE_SPEED;
SHAPE_SPEED = SHAPE_SPEED * (-1);
if ((musicShapePosY == 100.0f) || (musicShapePosY == 227.5f))
{
buttonStop = true;
}
}
musicShapeButton.setShapePosition(musicShapePosX, musicShapePosY);
}
public void animateButtonShapeTv()
{
}
public void animateButtonShapeGames()
{
}
public void animateButtonShapeBooks()
{
}
public void animateButtonShapeTech()
{
}
}
E o código da classe que implementa a Shape:
package dblauncher;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
public final class CustomShapeButton extends JButton implements Shape
{
private float segmentLength;
private float shapeHeight;
private GeneralPath path;
private BufferedImage image;
public CustomShapeButton(float posX, float posY, float segmentLength, float shapeHeight)
{
this(posX, posY, segmentLength, shapeHeight, null);
}
CustomShapeButton(float posX, float posY, float segmentLength, float shapeHeight, BufferedImage image)
{
this.segmentLength = segmentLength;
this.shapeHeight = shapeHeight;
this.image = image;
setShapePosition(posX, posY);
}
public void setShapePosition(float posX, float posY)
{
float x0 = posX;
float y0 = posY + shapeHeight;
float x1 = posX - 3.0f + (segmentLength * 0.65f);
float y1 = posY - segmentLength;
float x2 = x1 - 6.0f + segmentLength * 1.35f;
float y2 = y1;
float x3 = x2 - 3.0f + (segmentLength * 0.65f);
float y3 = y2 + shapeHeight + segmentLength;
float x4 = x3 + 3.0f - (segmentLength * 0.65f);
float y4 = y3 + shapeHeight + segmentLength;
float x5 = x4 + 6.0f - (segmentLength * 1.35f);
float y5 = y4;
path = new GeneralPath();
path.moveTo(x0, y0);
path.lineTo(x1, y1);
path.lineTo(x2, y2);
path.lineTo(x3, y3);
path.lineTo(x4, y4);
path.lineTo(x5, y5);
path.closePath();
}
@Override
public Rectangle2D getBounds2D()
{
return path.getBounds2D();
}
@Override
public boolean contains(double d, double d1)
{
return path.contains(d, d1);
}
@Override
public boolean contains(Point2D pd)
{
return path.contains(pd);
}
@Override
public boolean intersects(double d, double d1, double d2, double d3)
{
return path.intersects(d, d1, d2, d3);
}
@Override
public boolean intersects(Rectangle2D rd)
{
return path.intersects(rd);
}
@Override
public boolean contains(double d, double d1, double d2, double d3)
{
return path.contains(d, d1, d2, d3);
}
@Override
public boolean contains(Rectangle2D rd)
{
return path.contains(rd);
}
@Override
public PathIterator getPathIterator(AffineTransform at)
{
return path.getPathIterator(at);
}
@Override
public PathIterator getPathIterator(AffineTransform at, double d)
{
return path.getPathIterator(at, d);
}
public void translate(float distanceX, float distanceY)
{
AffineTransform translation = new AffineTransform();
translation.translate(distanceX, distanceY);
path = (GeneralPath) path.createTransformedShape(translation);
}
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
BasicStroke stroke = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL);
g2.setStroke(stroke);
g2.setColor(getBackground());
g2.fill(path);
g2.setColor(getForeground());
g2.draw(path);
if (image != null)
{
Rectangle imageBounds = getBounds2D().getBounds();
g2.drawImage(image, imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height, this);
}
}
}
O que estarei fazendo de errado dentro do método mouseMoved()??
Obrigado,
J Amorim