I have a JPanel in a GridLayout that I add buttons to. I want to implement some kind of effect on buttons when the mouse is entered and when the mouse exits the button . The mouseEntered event is correctly fired when the mouse hovers over the button , however , when the mouse leaves the button the mouseExited event is not fired. How can I fix this issue?
Custom JButton
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class CustomButton extends JButton implements MouseListener{
Dimension scaled;
public CustomButton(String text){
super(text);
setContentAreaFilled(false);
setBorderPainted(false);
addMouseListener(this);
}
#Override
public void invalidate() {
super.invalidate();
scaled = getSize();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);
g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("entered the view");
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("exited the view");
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Don't use a MouseListener, rather add a ChangeListener to the JButton's model and react to changes in its rollover state,... isRollover()
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TestRollover extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
JButton button = new JButton("Button");
public TestRollover() {
add(button);
button.getModel().addChangeListener(new ChangeListener() {
private boolean rollover = false;
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = (ButtonModel) e.getSource();
if (model.isRollover() != rollover) {
System.out.println("Rollover: " + model.isRollover());
rollover = model.isRollover();
}
}
});
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("mouse entered");
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("mouse exited");
}
});
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
TestRollover mainPanel = new TestRollover();
JFrame frame = new JFrame("TestRollover");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Related
Well my English is not so good but i will try to explain.
I was make two class,First Class and Second Class(Second was named "Grafika").
I want that my rectangle move to position where i was clicked , but obviously he dont move and i cant understand why, please help .
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Grafika extends JPanel implements MouseListener{
static int x=0,y=0;
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 30);
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub``
x=arg0.getX();
y=arg0.getY();
this.repaint(x, y, 20, 30);
}
i will show you a full code, it was small .This was second class.And my(i think) only problem is repaint() method . Why i dont know :D .
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Grafika extends JPanel implements MouseListener{
static int x=0,y=0;
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 30);
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
x=arg0.getX();
y=arg0.getY();
this.repaint(x, y, 20, 30);
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
Now i will show you first class from where i was calling second class.
import java.awt.*;
import javax.swing.*;
public class Glavna extends Grafika {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Grafika g=new Grafika();
JFrame wi=new JFrame("Grafika");
wi.setBounds(50, 50, 500, 600);
wi.add(g);
wi.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wi.setVisible(true);
}
}
You've several problems in that code:
You're sort of creating a MouseListener (you're still missing several of the interface's methods), but I don't see anywhere that you've added it to your GUI. You must somewhere have addMouseListener(this); in your code for the listener to work.
Repaint by itself doesn't move the rectangle. Changing the X and Y does, but again, not without adding the MouseListener first.
You probably want to call repaint(); without parameters to paint the whole component. Otherwise the old rectangle might not get erased.
Your paintComponent method should call the super.paintComponent(g); as the first method call of your override method. Without this you won't erase the old rectangle, and you break the painting chain which could have painting side effects in child components.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class Grafika extends JPanel {
private static final int RECT_W = 20;
private static final int RECT_H = 30;
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final Color MY_COLOR = Color.RED;
private int myX = 0;
private int myY = 0;
public Grafika() {
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse); // add MouseListener
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // **MUST** call this
g.setColor(MY_COLOR);
g.fillRect(myX, myY, RECT_W, RECT_H);
}
private class MyMouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
myX = e.getX();
myY = e.getY();
repaint(); // repaint the whole JPanel
}
}
#Override // to make the GUI larger
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
Grafika mainPanel = new Grafika();
JFrame frame = new JFrame("Grafika");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
If you want to get fancier and start dragging the square around:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Grafika extends JPanel {
private static final int RECT_W = 20;
private static final int RECT_H = RECT_W;
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final Color MY_COLOR = Color.RED;
private int myX = 0;
private int myY = 0;
public Grafika() {
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(MY_COLOR);
g.fillRect(myX, myY, RECT_W, RECT_H);
}
private class MyMouse extends MouseAdapter {
public void mousePressed(MouseEvent e) {
moveRect(e);
}
#Override
public void mouseDragged(MouseEvent e) {
moveRect(e);
}
#Override
public void mouseReleased(MouseEvent e) {
moveRect(e);
}
private void moveRect(MouseEvent e) {
myX = e.getX() - RECT_W / 2;
myY = e.getY() - RECT_H / 2;
repaint();
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
Grafika mainPanel = new Grafika();
JFrame frame = new JFrame("Grafika");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
you have to add mouse listener to component porobably
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class Grafika extends JPanel implements MouseListener{
static int x=0,y=0;
public Grafika(){
super();
addMouseListener(this); // add to constructor
}
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, 20, 30);
}
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub``
x=arg0.getX();
y=arg0.getY();
this.repaint(x, y, 20, 30);
}
I recently made a MakeDots class in java that when you drag the mouse, it makes dots(yay!). I implemented a MouseMotionListener for that. It worked fine. Then I added some buttons to change the colors of the dots. I added ActionListeners for that. Once I did that, the color-changing worked, but I could only draw in the very tiny borders of the buttons! Why does this happen? How do I fix it? If you need me to post my code just say in the comments, and I will do so.
CODE:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
public class MakeDots extends Applet implements MouseMotionListener{
private Graphics graphics = null;
private Color dotColor = Color.red;
private Button setRed;
private Button setPink;
private Button setPurple;
private Button clrBtn;
public void init() {
setRed = new Button("Red");
setPink = new Button("Pink");
setPurple = new Button("Purple");
clrBtn = new Button("Clear");
this.addMouseMotionListener(this);
this.add(setRed);
this.add(setPink);
this.add(setPurple);
this.add(clrBtn);
setRed.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dotColor = Color.red;
}
});
setPink.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dotColor = Color.pink;
}
});
setPurple.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dotColor = new Color(80, 0, 80);
}
});
clrBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
clear();
}
});
}
public void paint(Graphics g) {
this.setSize(new Dimension(800, 600));
graphics = g.create();
clear();
}
public void drawDot(int x, int y) {
graphics.setColor(dotColor);
graphics.fillOval(x, y, 10, 10);
}
public void clear() {
Dimension d = this.getSize();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, d.width, d.height);
}
#Override
public void mouseDragged(MouseEvent e) {
int mouseX = e.getX();
int mouseY = e.getY();
drawDot(mouseX, mouseY);
}
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
There are few things you might want to do. Lose the practice of writing actionPerformed(...) everytime you add an actionListener(). Just use getActionCommand() to check which button triggered the event. Also,create a global object of Color() and update it in actionPerformed()
I am currently writing a small program where I'm supposed to use basic transformations. Right now, I'm working on being able to move the polygon by using the arrow keys. Right now I can move it to the right by pressing the mouse, but I'd rather be able to use the right arrow key. However, I haven't been able to no matter which method I tried.
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
class PolygonPanel extends JPanel implements MouseListener{
Polygon p;
public PolygonPanel(){
p = new Polygon();
p.addPoint(10, 10);
p.addPoint(100,50);
p.addPoint(50,100);
addMouseListener(this);
addKeyListener(new MKeyListener());
}
class MKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
if(keyCode==e.VK_RIGHT){
System.out.println("FFFFUUUUU");
}
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
setBackground(Color.white);
g.fillPolygon(p);
}
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("hei");
for (int i = 0; i < p.npoints; i++) {
p.xpoints[i] = p.xpoints[i]+10;
repaint();
}
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
class PolygonFrame extends JFrame{
public PolygonFrame(){
setTitle("Polygoner");
setSize(700, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.add(new PolygonPanel());
}
}
public class Polygonfun {
public static void main(String[] args) {
JFrame frame = new PolygonFrame();
frame.setVisible(true);
}
}
Nothing happens when I press the right arrow key. I also tried implementing it like this:
class PolygonPanel extends JPanel implements MouseListener,KeyAdapter
And then adding the unimplemented methods, but that didn't work either. I know i've probably overlooked something, but I cant seem to figure it out. Any advice?
Thanks
set this.setFocusable(true); for your panel.
Should be:
public PolygonPanel(){
p = new Polygon();
p.addPoint(10, 10);
p.addPoint(100,50);
p.addPoint(50,100);
addMouseListener(this);
this.setFocusable(true);
this.addKeyListener(new MKeyListener());
}
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.*;
import java.util.*;
public class test1 extends JFrame implements MouseListener {
private JPanel JP = new JPanel();
public test1() {
JP.setBorder(BorderFactory.createLineBorder(Color.black));
JP.addMouseListener(this);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.add(JP);
this.pack();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
test1 frame = new test1();
frame.setSize(400,400);
frame.setVisible(true);
}
});
}
public void mouseClicked(MouseEvent e) {
//drawCircle(e.getX(), e.getY());
//repaint();
ballball ball;
ball = new ballball();
//ball.paintComponent(Graphics g);
System.out.println("ballball");
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
//this.mouseX=e.getX();
//this.mouseY=e.getY();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
}
class ballball extends test1 implements Runnable {
private int squareX = 50;
private int squareY = 50;
private int squareW = 100;
private int squareH = 100;
public boolean draw;
private Vector<Object> v = new Vector<Object>();
public ballball() {
/*addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
draw = true;
//Thread thread1 = new Thread(this.moveSquare(50, 50));
repaint();
//moveSquare(e.getX(),e.getY());
}
});*/
/*addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});*/
System.out.println("ball created");
this.repaint();
}
public void run() {
}
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX!=x) || (squareY!=y)) {
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
squareX=x;
squareY=y;
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
}
}
public void paint(Graphics g) {
g.drawString("abcasdfasffasfas", 10, 10);
}
//#Override
public void paintComponent(Graphics g) {
//if (draw) {
// existing code
System.out.println("paint");
//super.paintComponent(g);
//g.drawString("This is my custom Panel!",10,20);
//g.setColor(Color.RED);
//g.fillRect(squareX,squareY,squareW,squareH);
//g.setColor(Color.BLACK);
//g.drawRect(squareX,squareY,squareW,squareH);
Shape circle = new Ellipse2D.Float(squareX,squareY,100f,100f);
Graphics2D ga = (Graphics2D)g;
ga.draw(circle);
//}
}
}
The aim of the program is to click to create the circle, the ballball class extends the test1, when test1 detect the mouse click, the ballball object created. But the paint/paintComponent method is never be executed. In my program structure, is it possible to paint the circle to the super class JPanel?
JFrame is not a JComponent, it doesn't have a paintComponent method you can override. Instead you could extend a JPanel and add it to the frame.
Can't seem to figure out how to only show one circle. Was trying to //g.clearRect(0, 0, 400, 400); but that clears the background too. Was also trying to just fill the background with yellow again but couldn't get that working either. Any suggestions?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JMouseFrame extends JFrame
implements MouseListener {
Container con = null;
int x, y;
int size;
public JMouseFrame() {
setTitle("JMouseFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
con = this.getContentPane();
addMouseListener(this);
}
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
public void mouseClicked(MouseEvent e) {
int whichButton = e.getButton();
if (whichButton == MouseEvent.BUTTON1) {
size = 15;
} else if (whichButton == MouseEvent.BUTTON3) {
size = 4;
}
repaint();
}
public void mouseEntered(MouseEvent e) {
con.setBackground(Color.yellow);
}
public void mouseExited(MouseEvent e) {
con.setBackground(Color.black);
}
public void paint(Graphics g) {
//g.clearRect(0, 0, 400, 400);
g.drawOval(x - size, y - size, size * 3, size * 3);
}
public static void main(String[] args) {
JMouseFrame mFrame = new JMouseFrame();
mFrame.setSize(400, 400);
mFrame.setVisible(true);
}
public void mouseReleased(MouseEvent e) {
}
}
It looks like you're mixing AWT and Swing painting. Instead, override paintComponent(), as suggested in the example below. See Painting in AWT and Swing for details.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** #see http://stackoverflow.com/questions/3898775 */
public class MousePanel extends JPanel {
private static final int SIZE = 20;
Point p = new Point(Short.MAX_VALUE, Short.MAX_VALUE);
public MousePanel() {
this.setPreferredSize(new Dimension(400, 400));
this.setBackground(Color.yellow);
this.addMouseListener(new MouseHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.drawOval(p.x - SIZE, p.y - SIZE, SIZE * 2, SIZE * 2);
}
private final class MouseHandler extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
p = e.getPoint();
repaint();
}
}
private void display() {
JFrame f = new JFrame("MousePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MousePanel().display();
}
});
}
}
Addendum:
I can't figure out how to make the code you posted work with what I have...
You can restore your mouse methods to the MouseHandler almost verbatim. The only difference is the need to qualify this, e.g.
#Override
public void mouseClicked(MouseEvent e) {
int whichButton = e.getButton();
if (whichButton == MouseEvent.BUTTON1) {
MousePanel.this.size = 15;
} else if (whichButton == MouseEvent.BUTTON3) {
MousePanel.this.size = 4;
}
repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
MousePanel.this.setBackground(Color.yellow);
}
#Override
public void mouseExited(MouseEvent e) {
MousePanel.this.setBackground(Color.black);
}