Here,is something I wanted to show for the use of MouseEvents of one class in another ...by creating an object of the former class...
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.*;
public class MyPagalpanti extends JPanel implements MouseListener
{Point a,b;
boolean drawLin,drawOvl,drawOvl2;
MyPagalpanti(){a=new Point(0,0);b=new Point(0,0);drawLin=false;drawOvl=false,drawOvl2=false;;setSize(300,300);addMouseListener(this);}
public void mouseClicked(MouseEvent m)
{if(!drawOvl){a=new Point(m.getX(),m.getY());drawOvl=true;drawOvl2=false;}
else {b=new Point(m.getX(),m.getY());drawOvl=true;drawOvl2=true;repaint();}//record("clicked",m);}
}
public void mouseEntered(MouseEvent m)
{
}
public void mousePressed(MouseEvent m)
{a=new Point(m.getX(),m.getY());repaint();}
public void mouseReleased(MouseEvent m)
{b=new Point(m.getX(),m.getY());}
public void mouseExited(MouseEvent m)
{}
public void paintComponent(Graphics g)
{if(drawLin){g.setColor(Color.yellow);g.drawLine((int)a.getX(),(int)a.getY(),(int)b.getX(),(int)b.getY());}//d=0;}
else if(drawOvl&&drawOvl2){g.setColor(Color.red);int width=(int)Math.abs(b.getX()-a.getX());
int h=(int)Math.abs(b.getY()-a.getY());
g.drawOval((int)a.getX(),(int)a.getY(),width,h);
}}
}
the class in which an object of MyPagalpanti is formed:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
//import java.swing.JPanel.*;
public class Mithu extends JFrame// implements MouseListener
{JTextArea jta1,jta2;
Mithu(String title)
{
super(title);
MyPagalpanti p1=new MyPagalpanti();
jta1=new JTextArea();
jta2=new JTextArea();
p1.setOpaque(true);
jta1.setEditable(false);
jta2.setEditable(false);
setForeground(Color.blue);
p1.setPreferredSize(new Dimension(600,600));
p1.setLayout(new GridLayout(3,1,0,0));
getContentPane().add(p1);
pack();
setVisible(true);
}
void record(String s,MouseEvent e)
{jta1.setText(jta1.getText()+"\n"+s+""+e.toString());}
public void mouseClicked(MouseEvent m)
{record("clicked",m);}
public void mouseEntered(MouseEvent m)
{record("entered",m);}
public void mousePressed(MouseEvent m)
{record("pressed",m);}
public void mouseReleased(MouseEvent m)
{ record("released",m);}
public void mouseExited(MouseEvent m)
{record("exited",m);}
public static void main(String args[])
{Mithu m=new Mithu("HI ! Karamvir");
m.setVisible(true);}
}
please don't go word by word...I know my code has many other bugs...coz I am still working on it...but for those who have say that "the MouseEvents will only be delivered to the MouseListener from the component it registered to " ,I guess you are talking correctly but if we see closely, I have used this concept only...in this code..
To add it JBNizet's answer...
MouseListeners will only be delivered to components that are displayable and have registered for notification. Creating a component that is listening for mouse events and adding it you component won't magically make those events delivered to your component.
Then, in top of that, you are adding two components to the default (CENTER) position of a component managed by BorderLayout...
getContentPane().add(panelTop);
//...
getContentPane().add(p1);
This effectively makes the first component invisible, meaning it's not displayable...
You shouldn't be calling show as it's deprecated, use setVisible instead.
You should be calling super.paintComponent in your paintComponent method before doing any custom painting, otherwise you'll end up with no end of painting problems
There is no need for paintComponent to be public as you never want anybody to be able to call it directly...
Updated
Unless you register interest in been notified about events, you will never receive notification, regardless of what objects you create or interfaces you implement.
It's like saying "I'm interested in this movie", but unless you go to the cinemas, you'll never see it...
In order for your Mithu class to receive mouse event notification, it must register a MouseListener against the component that it's interested in monitoring.
The following example registers a a MouseListener in the Mithu class against the instance of MyPagalpanti, which allows it to receive mouse events that are generated by the instance of MyPagalpanti
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMouseListener {
public static void main(String[] args) {
new TestMouseListener();
}
public TestMouseListener() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Mithu m = new Mithu("HI ! Karamvir");
m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
m.pack();
m.setLocationRelativeTo(null);
m.setVisible(true);
}
});
}
public class Mithu extends JFrame implements MouseListener
{
JTextArea jta1;
Mithu(String title) {
super(title);
MyPagalpanti p1 = new MyPagalpanti();
p1.addMouseListener(this);
jta1 = new JTextArea();
p1.setOpaque(true);
jta1.setEditable(false);
setForeground(Color.blue);
setLayout(new GridLayout(2, 1));
getContentPane().add(jta1);
getContentPane().add(p1);
pack();
setVisible(true);
}
void record(String s, MouseEvent e) {
jta1.append("\n" + s + "" + e.toString());
}
public void mouseClicked(MouseEvent m) {
record("clicked", m);
}
public void mouseEntered(MouseEvent m) {
record("entered", m);
}
public void mousePressed(MouseEvent m) {
record("pressed", m);
}
public void mouseReleased(MouseEvent m) {
record("released", m);
}
public void mouseExited(MouseEvent m) {
record("exited", m);
}
}
public class MyPagalpanti extends JPanel implements MouseListener {
Point a, b;
boolean drawLin, drawOvl, drawOvl2;
MyPagalpanti() {
a = new Point(0, 0);
b = new Point(0, 0);
drawLin = false;
drawOvl = false;
drawOvl2 = false;
setSize(300, 300);
addMouseListener(this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public void mouseClicked(MouseEvent m) {
if (!drawOvl) {
a = new Point(m.getX(), m.getY());
drawOvl = true;
drawOvl2 = false;
} else {
b = new Point(m.getX(), m.getY());
drawOvl = true;
drawOvl2 = true;
repaint();
}//record("clicked",m);}
}
public void mouseEntered(MouseEvent m) {
}
public void mousePressed(MouseEvent m) {
a = new Point(m.getX(), m.getY());
repaint();
}
public void mouseReleased(MouseEvent m) {
b = new Point(m.getX(), m.getY());
}
public void mouseExited(MouseEvent m) {
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
FontMetrics fm = g.getFontMetrics();
if (a != null && b != null) {
g.drawString(a + "-" + b, 0, fm.getHeight());
}
if (drawLin) {
g.setColor(Color.yellow);
g.drawLine((int) a.getX(), (int) a.getY(), (int) b.getX(), (int) b.getY());
}//d=0;}
else if (drawOvl && drawOvl2) {
g.setColor(Color.red);
int width = (int) Math.abs(b.getX() - a.getX());
int h = (int) Math.abs(b.getY() - a.getY());
g.drawOval((int) a.getX(), (int) a.getY(), width, h);
}
}
}
}
Before you go to much further, you really should read through...
Performing Custom Painting
Painting in AWT and Swing
As you are going to have some very nasty suprises if you keep following your current approach.
Also, it wouldn't hurt to read through How to Write a Mouse Listener
Your class has mouseClicked(), mouseReleased() etc. methods, but it doesn't implement MouseListener. And even if it was, it's never added as a MouseListener to any component.
So, make your class implement MouseListener:
public class MouseEvtEx2 extends JFrame implements MouseListener {
and add itself as mouse listener to the component you want to listen to:
panelTop.addMouseListener(this);
And of course, to help yourself read and understand your own code, indent it properly.
I made couple of changes to make it work. you need to implement MouseListener on your MouseEvtEx2 Frame and also you need to add it as the MouseListener to your panel p1
public class MouseEvtEx2 extends JFrame implements MouseListener {
private JTextArea txtArea;
public MouseEvtEx2(String title) {
super(title);
Panel p1 = new Panel();
MyPanel panelTop = new MyPanel();
panelTop.setBackground(new Color(0.98f, 0.97f, 0.85f));
panelTop.setOpaque(true);
panelTop.setPreferredSize(new Dimension(400, 200));
panelTop.setBorder(BorderFactory.createRaisedBevelBorder());
getContentPane().add(panelTop);
txtArea = new JTextArea();
txtArea.setEditable(false);
JScrollPane pane = new JScrollPane(txtArea);
pane.setPreferredSize(new Dimension(400, 200));
p1.setLayout(new GridLayout(2, 1, 0, 0));
getContentPane().add(p1);
p1.addMouseListener(this);
p1.add(pane);
// txtArea.setText
// revalidate();
setSize(600, 600);
show();
}
public void record(String st, MouseEvent et) {
txtArea.setText("" + st + "" + et.toString());
}// setVisible(true);}
public void mouseClicked(MouseEvent evt) {
record("Mouse clicked # of mouse clicks: " + evt.getClickCount(), evt);// +
// " "
// +
}
public void mouseEntered(MouseEvent evt) {
record("Mouse entered ", evt);// .toString());
}
public void mouseExited(MouseEvent evt) {
record("Mouse exited ", evt);// .toString());
}
public void mousePressed(MouseEvent evt) {
record("Mouse pressed # of mouse clicks: ", evt);// .getClickCount() +
// " " +
}
public void mouseReleased(MouseEvent evt) {
record("Mouse released ", evt);
}
public static void main(String[] args) {
new MouseEvtEx2("Mouse events");
}
}
Hope this helps.
Related
Im having some trouble using repaint.The code is supposed to draw a line behind your cursor.
package javaapplication6;
import java.awt.*;
import javax.swing.JFrame;
import java.awt.event.*;
class Test extends Canvas implements MouseListener, MouseMotionListener {
int x[]=new int[1024];
int y[]=new int[1024];
int size=0;
public void MouseDemo(){
addMouseListener(this);
addMouseMotionListener(this);
}
public void paint (Graphics g){
g.setColor(Color.red);
for (int i=1;i<size;i++) g.drawLine(x[i],y[i],x[i-1],y[i-1]);
}
public void mousePressed(MouseEvent e){
x[size]=e.getX();
y[size]=e.getY();
size++;
}
public void mouseDragged(MouseEvent e){
y[size]=e.getY();
x[size]=e.getX();
size++;
repaint();
}
public void mouseEntered(MouseEvent e){
size=0;
y[size]=e.getY();
x[size]=e.getX();
repaint();
}
public void mouseExited (MouseEvent e){
size=0;
repaint();
}
public void mouseReleased (MouseEvent e){}
public void mouseClicked (MouseEvent e){
}
public void mouseMoved (MouseEvent e){}
}
public class JavaApplication6 {
public static void main(String[] args) {
JFrame win= new JFrame ("Target");
win.setSize(600,500);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.add(new Test());
win.setVisible(true);
}}
This same code worked at the school computer but when I got home and tried to do another example and it didn't really work so I decided to test this one and it doesn't work either.I would really appreciate some help and an explanation as to why repaint doesn't trigger.
Your primary problem is here...
public void MouseDemo() {
addMouseListener(this);
addMouseMotionListener(this);
}
This is a method, not a constructor, so it will never register your listeners. Instead, change it to...
public MouseDemo() {
addMouseListener(this);
addMouseMotionListener(this);
}
Or, based on you actually example code...
public Test() {
addMouseListener(this);
addMouseMotionListener(this);
}
java.awt.Canvas is a heavy weight component, AWT components don't always play nice with Swing, as they have no concept of z-ordering in the way that Swing implements it.
You'd be better off starting with a JPanel.
By convention, you should then override the paintComponent method and perform your custom painting within it, remembering to call super.paintComponent first
Because frame borders are inserted into the visible area of the frame, you "useable" area will be less then that specified by setSize, instead, you should override the getPreferredSize method of the JPanel and specify the "usable" area you prefer. From there, you can pack the frame around it.
To avoid any possible issues with threads, you should use EventQueue.invokeLater to start you UI in
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test extends JPanel implements MouseListener, MouseMotionListener {
int x[] = new int[1024];
int y[] = new int[1024];
int size = 0;
public Test() {
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 500);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
for (int i = 1; i < size; i++) {
g.drawLine(x[i], y[i], x[i - 1], y[i - 1]);
}
}
#Override
public void mousePressed(MouseEvent e) {
x[size] = e.getX();
y[size] = e.getY();
size++;
}
public void mouseDragged(MouseEvent e) {
y[size] = e.getY();
x[size] = e.getX();
size++;
repaint();
}
public void mouseEntered(MouseEvent e) {
System.out.println("Entered");
size = 0;
y[size] = e.getY();
x[size] = e.getX();
repaint();
}
public void mouseExited(MouseEvent e) {
size = 0;
repaint();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Test());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I have tried a ton of different things to try to get the JLabel to show but I don't understand why it is not working. I have tried resizing it, though that is not what i want to do, I have tried other classes, but I would prefer to stick with this one, and it is starting to get really frustrating. If you have any ideas please help. But please try to keep them simple and explain very clearly as I am still quite new to java. I have only been going for about three or four months. Here is my code:
package com.thefallenpaladin;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Created by darkp_000 on 11/4/2015.
*/
#SuppressWarnings("serial")
public class Game extends JPanel implements KeyListener,MouseListener {
public boolean mainMenu = true;
public int winWidth = 700; //Window Stats
public int winHeight = 600;
public int buttonOneX = 60; // Button Stats
public int buttonOneY = 240;
public int buttonOneW = 100;
public int buttonOneH = 75;
public boolean buttonOne = false;
public int mouseX; // not set because it is set in mouseClicked
public int mouseY;
public static void main(String[] args) {
Game game = new Game();
JFrame window = new JFrame("I hate this");
JLabel onePlayer = new JLabel();
onePlayer.setLocation(0,0/*game.buttonOneX + game.buttonOneX/2,game.buttonOneY + game.buttonOneY/2*/);
window.add(game);
window.setFocusable(true);
window.setResizable(false);
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setSize(700,600); //TODO
window.setVisible(true);
game.requestFocusInWindow();
game.add(onePlayer);
game.addKeyListener(game);
game.addMouseListener(game);
window.setLocationRelativeTo(null);
while(true) { // Main Game loop
onePlayer.setText("One Player");
game.repaint();
game.customUpdate();
}
}
public void customUpdate() {
if(mouseX > buttonOneX && mouseX < buttonOneX+buttonOneX && mouseY > buttonOneY && mouseY < buttonOneY+buttonOneY && mainMenu) {
buttonOne = true;
System.out.print("Starting Game");
}
}
public void paint(Graphics g) {
if(mainMenu) {
g.setColor(Color.CYAN); // Set main menu
g.fillRect(0,0,winWidth,winHeight);
g.setColor(Color.GREEN);
g.fillRect(buttonOneX,buttonOneY,buttonOneW,buttonOneH);
}
if(buttonOne) {
mainMenu = false;
g.setColor(Color.GREEN);
g.fillRect(0,0,winWidth,winHeight);
}
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
System.out.println(e);
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
// System.out.println(e);
mouseX = e.getX();
mouseY = e.getY();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
Okay so you've made a couple of basic mistakes...
First, JLabel onePlayer = new JLabel(); creates an empty label, with no size (0x0) and since labels are transparent by default, you'd not see it
Next, you've overridden paint of a top level container (JFrame), but failed to honor the paint chain effectively preventing any of the child components from ever getting painted
public void paint(Graphics g) {
if (mainMenu) {
g.setColor(Color.CYAN); // Set main menu
g.fillRect(0, 0, winWidth, winHeight);
g.setColor(Color.GREEN);
g.fillRect(buttonOneX, buttonOneY, buttonOneW, buttonOneH);
}
if (buttonOne) {
mainMenu = false;
g.setColor(Color.GREEN);
g.fillRect(0, 0, winWidth, winHeight);
}
}
So, if I remove your paint method and change JLabel onePlayer = new JLabel(); to JLabel onePlayer = new JLabel("I'm a label"); I get this output...
Also...
while (true) { // Main Game loop
onePlayer.setText("One Player");
game.repaint();
game.customUpdate();
}
has the potential to try screw up your program, you have no guarantee's in what thread your main method is been called and you should not make assumptions.
Start by creating a custom component, extending from something like JPanel and override it's paintComponent method, place your custom painting there. In fact, you should have a panel for each state of your game (menu, running, settings, etc).
Add these to your frame (probably using a CardLayout to enable you to easily switch between them)
Use either a Thread or Swing Timer as a main game loop, one which you create explicitly.
Have a look at Painting in AWT and Swing, Performing Custom Painting, How to Use CardLayout and How to use Swing Timers for some more details
As a "conceptual" example...
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class AwesomeGame {
public static void main(String[] args) {
new AwesomeGame();
}
public AwesomeGame() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface NavigationController {
public void letsPlay();
}
public class ContentPane extends JPanel implements NavigationController {
private CardLayout cardLayout;
private GamePane gamePane;
public ContentPane() {
cardLayout = new CardLayout();
setLayout(cardLayout);
add(new MenuPane(this), "TheMenu");
add((gamePane = new GamePane()), "TheGame");
cardLayout.show(this, "TheMenu");
}
#Override
public void letsPlay() {
cardLayout.show(this, "TheGame");
gamePane.play();
}
}
public class MenuPane extends JPanel {
public MenuPane(NavigationController navigationController) {
JLabel label = new JLabel("My Super Dupa Awesome Game!");
label.setFont(label.getFont().deriveFont(Font.BOLD, 48));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(label, gbc);
JButton play = new JButton("Play Now!");
play.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
navigationController.letsPlay();
}
});
add(play, gbc);
setBackground(Color.GREEN);
}
}
public class GamePane extends JPanel {
public GamePane() {
setBackground(Color.BLUE);
}
public void play() {
Timer timer = new Timer(500, new ActionListener() {
int count;
#Override
public void actionPerformed(ActionEvent e) {
count++;
if (count % 2 == 0) {
setForeground(Color.BLACK);
} else {
setForeground(Color.RED);
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
String text = "I bet you're blowen away by it's awesomness!";
FontMetrics fm = g2d.getFontMetrics();
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(text, x, y);
g2d.dispose();
}
}
}
i have an application containing a jframe, this jframe then adds a jpanel which constains an image. the jpanel is displayed for a given time, then removed from the jframe and another jpanel is added.
I want to fade in and out between the images, and ive done this using a timer
private void fadeOut() {
ActionListener fadeOutAc = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
opacity += 10;
if (opacity >= 255) {
opacity = 255;
fadeOutT.stop();
}
repaint();
}
};
fadeOutT = new Timer(20, fadeOutAc);
fadeOutT.start();
}
private void fadeIn() {
ActionListener fadeInAc = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
opacity -= 10;
if (opacity <= 0) {
opacity = 0;
fadeInT.stop();
}
repaint();
}
};
fadeInT = new Timer(10, fadeInAc);
fadeInT.setInitialDelay(200);
fadeInT.start();
}
public void paint(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(picColor.getRed(), picColor.getGreen(), picColor.getBlue(), opacity));
g.fillRect(0, 0, presWin.getWidth(), presWin.getHeight());
}
i recently moved the fading in/out from the jpanel to the jframe instead. The problem is, that in the jpanel, the repaint only had to draw an image, now it has to repaint the entire jpanel each time. Is there a way to call repaint without having the paint the components, only the rectangel?
To me, it seems a bit silly to put the functionality in the JFrame when what you seem to want is a container which can fade it's content in and out. This way you can isolate the responsibility to a single container/class which can be placed or used in what ever way you want in isolation to the rest of the UI.
Basically, this example uses a FadingPane (based on a JPanel) to control the fading process, but onto which I place JLabel which holds the actual images.
Fading is controlled through the use of a AlphaComposite, meaning that this panel will actually physically fade in and out, not just change fill color ;)
There is also a FadingListener which provides additional notifications about the fading process, really only interested in fadeOutDidComplete, so you can switch the images and fade the panel back in, but you never know...
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
private FadingPane fadingPane;
private File[] pictures;
private int index;
public TestPane() {
// Just for show
setBackground(Color.RED);
fadingPane = new FadingPane(new FadeListener() {
#Override
public void fadeDidStart(FadingPane panel) {
}
#Override
public void fadeDidStop(FadingPane panel) {
}
#Override
public void fadeOutDidComplete(FadingPane panel) {
nextPicture();
fadingPane.fadeIn();
}
#Override
public void fadeInDidComplete(FadingPane panel) {
}
});
setLayout(new BorderLayout());
fadingPane.setLayout(new BorderLayout());
label = new JLabel();
fadingPane.add(label);
add(fadingPane);
JButton next = new JButton("Next");
add(next, BorderLayout.SOUTH);
next.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fadingPane.fadeOut();
}
});
pictures = new File("/Volumes/Disk02/Dropbox/MegaTokyo/thumnails").listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".png");
}
});
nextPicture();
}
protected void nextPicture() {
index++;
if (index >= pictures.length) {
index = 0;
}
try {
BufferedImage img = ImageIO.read(pictures[index]);
label.setIcon(new ImageIcon(img));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public interface FadeListener {
public void fadeDidStart(FadingPane panel);
public void fadeDidStop(FadingPane panel);
public void fadeOutDidComplete(FadingPane panel);
public void fadeInDidComplete(FadingPane panel);
}
public class FadingPane extends JPanel {
private float delta;
private float alpha = 1f;
private Timer timer;
private FadeListener fadeListener;
public FadingPane(FadeListener fadeListener) {
this.fadeListener = fadeListener;
// This is important, as we may not always be opaque
// and we don't want to stuff up the painting process
setOpaque(false);
timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
float alpha = getAlpha() + delta;
if (alpha < 0.001f) {
alpha = 0f;
timer.stop();
fadeListener.fadeOutDidComplete(FadingPane.this);
} else if (alpha >= 1.0f) {
alpha = 1.0f;
timer.stop();
fadeListener.fadeInDidComplete(FadingPane.this);
}
setAlpha(alpha);
}
});
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float value) {
if (alpha != value) {
this.alpha = Math.min(1.0f, Math.max(0.0f, value));
repaint();
}
}
#Override
public void paint(Graphics g) {
// I don't normally recomamned overriding paint, but in this case,
// I want to affect EVERYTHING that might be added to this panel
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(getAlpha()));
super.paint(g2d);
g2d.dispose();
}
public void fadeIn() {
timer.stop();
fadeListener.fadeDidStop(FadingPane.this);
delta = 0.05f;
timer.restart();
fadeListener.fadeDidStart(FadingPane.this);
}
public void fadeOut() {
timer.stop();
fadeListener.fadeDidStop(FadingPane.this);
delta = -0.05f;
timer.restart();
fadeListener.fadeDidStart(FadingPane.this);
}
}
}
Thats totaly normal, moving your function to the JFrame and calling repaint function would actualy call repaint of your JFrame.
I think the best solution would be to pass panel as an argument to your fadeIn and fadeOut function and call its repaint methode for example fadeIn :
private void fadeIn(JPanel panelParam) {
ActionListener fadeInAc = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
opacity -= 10;
if (opacity <= 0) {
opacity = 0;
fadeInT.stop();
}
panelParam.repaint(); // here call repaint of the panel.
}
};
fadeInT = new Timer(10, fadeInAc);
fadeInT.setInitialDelay(200);
fadeInT.start();
}
With that you can apply your effect on any other panel.
Hope it helped.
this is my code
I want to draw the rectangle at the position that I clicked but it is not drawing any thing :( , I don't know how I giving the action to "MouseListener"
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Transparenttxom extends JPanel implements MouseListener {
Graphics g=null;
public void init(){
Transparenttxom panel=new Transparenttxom();
panel.addMouseListener(this);
}//end init
//********************************************************************
public void paint(Graphics g){
}
//********************************************************************
public void mouseClicked(MouseEvent e){
int mousex=e.getX();
int mousey=e.getY();
g.drawRect(20,20,mousex,mousey);
}//end mouseclicked method
//********************************************************************
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
public void mouseReleased(MouseEvent e){
}
//********************************************************************
public static void main(String[] args) {
Transparenttxom panel=new Transparenttxom();
JFrame frame = new JFrame("java lover");
frame.add(panel);
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
thanks for helping.
I would start with the fact the Graphics g=null; and since you've never assigned it anything, it's likely to remain null.
Then I'd move onto the point where init is never called, but your init method scares me...
public void init(){
Transparenttxom panel=new Transparenttxom();
panel.addMouseListener(this);
}//end init
Why are you creating a new instance of Transparenttxom? Simple call addMouseListener(this)...
But even then, this...
public void paint(Graphics g){
}
Means nothing will ever get painting...
Start by taking a look at Performing Custom Painting for more details
Instead overriding paint, you should override paintComponent, making sure you call super.paintComponent before you do any painting of your own.
In your mouseClicked event you should define what you want painted and simply call repaint which will trigger a paint event which will, eventually, call your paintComponent where in which you paint stuff.
Updated with a basic example
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Transparenttxom extends JPanel implements MouseListener {
private Point mousePoint;
public Transparenttxom() {
addMouseListener(this);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (mousePoint != null) {
g.drawRect(20, 20, mousePoint.x - 20, mousePoint.y - 20);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void mouseClicked(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}//end mouseclicked method
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
//********************************************************************
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new Transparenttxom());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Add listener like this:
public Transparenttxom() {
// TODO Auto-generated constructor stub
super();
this.addMouseListener(this);
}
Your init method never gets called.
and g is null!
and try this:
public void mouseClicked(MouseEvent e){
int mousex=e.getX();
int mousey=e.getY();
Graphics g = this.getGraphics();
g.drawRect(20,20,mousex,mousey);
}//end mouseclicked method
The whole code :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Transparenttxom extends JPanel implements MouseListener {
Graphics g=null;
public Transparenttxom() {
// TODO Auto-generated constructor stub
super();
this.addMouseListener(this);
}
public void init(){
Transparenttxom panel=new Transparenttxom();
System.out.println("no");
panel.addMouseListener(this);
}//end init
//********************************************************************
public void paint(Graphics g){
}
//********************************************************************
public void mouseClicked(MouseEvent e){
int mousex=e.getX();
int mousey=e.getY();
Graphics g = this.getGraphics();
g.drawRect(20,20,mousex,mousey);
}//end mouseclicked method
//********************************************************************
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
public void mouseReleased(MouseEvent e){
}
//********************************************************************
public static void main(String[] args) {
Transparenttxom panel=new Transparenttxom();
JFrame frame = new JFrame("java lover");
frame.add(panel);
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Check out Custom Painting Approaches for two common methods to do custom painting:
Keep an ArrayList of objects to paint
Paint onto a BufferedImage
In both examples the mouseReleased code actually saves the object to be painted. In your case you want to add the Rectangle on mousePressed.
I want to enable the drag and drop feature over a JLabel by overriding mouse events over it , but when I define the drag and drop in mousePressed event ,the mouseReleased does not take effect on that JLabel. Am I doing something wrong ?
Thumbnails[I_Loop].setText("1");
Thumbnails[I_Loop].setTransferHandler(new TransferHandler("text"));
Thumbnails[I_Loop].addMouseListener( new MouseAdapter() {
public void mouseReleased(MouseEvent me) {
System.out.println("here mouse released");
}
public void mousePressed(MouseEvent me) {
System.out.println("here mouse pressed");
JComponent comp = (JComponent) me.getSource();
TransferHandler handler = comp.getTransferHandler();
handler.exportAsDrag(comp, me, TransferHandler.COPY);
});
*Thumbnails is array of JLabel
When running the program , the drag and drop works but the statement "here mouse released" does not get printed. However, When I remove the code responsible for DND from the mousePressed() method, "here mouse released" is printed.
What is the wrong in this code?
#Thomas is correct, but two alternatives are worth noting:
This example shows how to drag a component using JLayeredPane; this variation expands on the concept; this more recent example uses a similar approach.
The code below shows how to use a MouseMotionListener; this more complex example uses the same principle.
Code:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** #see https://stackoverflow.com/a/5312702/230513 */
public class MouseDragTest extends JPanel {
private static final String TITLE = "Drag me!";
private static final int W = 640;
private static final int H = 480;
private Point textPt = new Point(W / 2, H / 2);
private Point mousePt;
public MouseDragTest() {
this.setFont(new Font("Serif", Font.ITALIC + Font.BOLD, 32));
this.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mousePt = e.getPoint();
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
int dx = e.getX() - mousePt.x;
int dy = e.getY() - mousePt.y;
textPt.setLocation(textPt.x + dx, textPt.y + dy);
mousePt = e.getPoint();
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int w2 = g.getFontMetrics().stringWidth(TITLE) / 2;
g.drawString(TITLE, textPt.x - w2, textPt.y);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame(TITLE);
f.add(new MouseDragTest());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
Well, if I remember correctly, the drag and drop machinery catches all mouse events and processes them itself. Thus, the normal MouseEvents are not thrown anymore. You'd need to register a DropTargetListener on the JLabel's DropTarget.
Does it have to be a JLabel? I made a class with a string that might get you started..
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class mainProgram extends JPanel implements Runnable
{
private static final long serialVersionUID = 1L;
public static boolean MOUSE_DOWN = false;
public static String str;
public mainProgram()
{
JFrame win = new JFrame("Window");
win.add(this);
win.setSize(700,500);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
str = "Drag me!";
new Thread(this).start();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(MOUSE_DOWN)
{
g.drawString(str, MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y);
}
}
#Override
public void run()
{
Thread t = Thread.currentThread();
this.addMouseListener(new MouseListener()
{
#Override
public void mouseClicked(MouseEvent arg0)
{
}
#Override
public void mouseEntered(MouseEvent arg0)
{
}
#Override
public void mouseExited(MouseEvent arg0)
{
}
#Override
public void mousePressed(MouseEvent arg0)
{
MOUSE_DOWN = true;
}
#Override
public void mouseReleased(MouseEvent arg0)
{
MOUSE_DOWN = false;
}
});
while(t==Thread.currentThread())
{
if(MOUSE_DOWN)
repaint();
try {Thread.sleep(10);}
catch (InterruptedException e) {e.printStackTrace();}
}
}
}