Drag JComponent within JPanel - java

I have a subclass of JPanel which contains an array of JComponent objects. I then use the paint(Graphics g) method to position the JComponent objects next to each other in the panel. All these JComponent Objects implement MouseMostionListener and I initialise the listener using addMouseMotionListener(this);, I also have the methods mouseMoved(MouseEvent m) and mouseDragged(MouseEvent m). All the components are being drawn correctly but the mouseMoved(MouseEvent m) and mouseDragged(MouseEvent m)are never called. Any ideas why?
Here is my code:
JPanel Subclass
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Image;
import javax.swing.ImageIcon;
import java.awt.Graphics;
import java.util.ArrayList;
public class ExamplePanel extends JPanel
{
ArrayList<ExampleComponent> components;
public ExamplePanel()
{
components = new ArrayList<ExampleComponent>();
}
public void paint(Graphics g)
{
for(ExampleComponent c : components)
g.drawImage(c.getImage(), 0, 30, 50, 75, null);
}
public void addComponent(ExampleComponent j)
{
components.add(j);
repaint();
}
public static void main(String[] args)
{
JFrame app = new JFrame("Staff Prototype");
app.setSize(700,200);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setResizable(false);
ExamplePanel s = new ExamplePanel();
app.getContentPane().add(s);
s.addComponent(new ExampleComponent());
app.setVisible(true);
}
}
JComponent Subclass:
import java.awt.Image;
import javax.swing.JComponent;
import javax.swing.ImageIcon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class ExampleComponent extends JComponent implements MouseMotionListener
{
Image image;
public ExampleComponent()
{
ImageIcon icon = new ImageIcon("image.png");
image = icon.getImage();
addMouseMotionListener(this);
}
public Image getImage()
{
return image;
}
public void mouseMoved(MouseEvent m)
{
System.out.println("Mouse Moved");
}
public void mouseDragged(MouseEvent m)
{
System.out.println("Mouse Dragged");
}
}

1)Add components like you do isn't proper way.
2)Instead of drawing Image use JLabel with icon, you get a lot of advantages with it from 'box'.
I have fixed your code, examine that:
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Example extends JPanel {
ArrayList<ExampleComponent> components;
public Example() {
components = new ArrayList<ExampleComponent>();
}
public void addComponent(ExampleComponent j) {
components.add(j);
add(j);
}
public static void main(String[] args) {
JFrame app = new JFrame("Staff Prototype");
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Example s = new Example();
s.setLayout(null);
app.getContentPane().add(s);
s.addComponent(s.new ExampleComponent(new Rectangle(0,0,25,25)));
s.addComponent(s.new ExampleComponent(new Rectangle(45,45,25,25)));
app.pack();
app.setVisible(true);
}
class ExampleComponent extends JPanel implements MouseMotionListener {
public ExampleComponent(Rectangle bounds) {
URL resource = getClass().getResource("3_disc.png");
ImageIcon icon = new ImageIcon(resource);
add(new JLabel(icon));
addMouseMotionListener(this);
setBounds(bounds);
}
public void mouseMoved(MouseEvent m) {
System.out.println("Mouse Moved");
}
public void mouseDragged(MouseEvent m) {
System.out.println("Mouse Dragged");
}
}
}

Related

How to display floating tool tip text on a polygon

I have written a Java code to draw a polygon on an image. When I put my cursor inside the polygon it prints "Inside" otherwise "Outside". So the detection of the points inside the polygon is working fine.
But I want to implement the effect of setToolTipText inside the polygon i.e. at the time of mouse hover inside the polygon, it will show the floating text "Inside".
Similar to the effect in this image:
http://www.java2s.com/Code/Java/Swing-JFC/WorkingwithTooltipText.htm
What are the minimal changes to be made in the following code to get the desired effect?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.image.*;
import java.awt.Graphics.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
class page1 extends JFrame implements MouseListener,MouseMotionListener ,ActionListener
{
JFrame f;
JLabel l;
JPanel p1;
ImageIcon ii;
Image img;
int height;
int width;
Container c;
int pixels[];
PixelGrabber pg;
JPanel panel;
Graphics2D gg;
Polygon pp1=new Polygon();
boolean startHovercurrent,startHoverprev=false;
page1()
{
f=new JFrame("Sample Page");
ii=new ImageIcon("sample.jpg");
img=ii.getImage();
height=ii.getIconHeight();
width=ii.getIconWidth();
pixels=new int[ii.getIconWidth()*ii.getIconHeight()];
pg=new PixelGrabber(img,0,0,ii.getIconWidth(),ii.getIconHeight(),pixels,0,ii.getIconWidth());
try
{
pg.grabPixels();
}
catch(InterruptedException k)
{
}
//add points of polygon
pp1.addPoint(300,300);
pp1.addPoint(380,300);
pp1.addPoint(380,220);
pp1.addPoint(300,220);
l=new JLabel(ii,JLabel.CENTER);
c=f.getContentPane();
JDesktopPane desk = new JDesktopPane();
JInternalFrame p = new JInternalFrame("Image Frame",false, false, true, false);
JScrollPane scroll = new JScrollPane(l);
p.setContentPane(scroll);
p.setBounds(0, 0, 740, 600);
desk.add(p);
p.setVisible(true);
l.addMouseListener(this);
l.addMouseMotionListener(this);
c.add(desk, BorderLayout.CENTER);
f.setSize(1024,738);
f.setVisible(true);
}
public static void main(String args[])
{
new page1();
}
public void mouseClicked(MouseEvent me)
{
}
public void mouseEntered(MouseEvent me)
{
}
public void mouseExited(MouseEvent me)
{
}
public void mousePressed(MouseEvent me)
{
}
public void mouseReleased(MouseEvent me)
{
}
public void mouseMoved(MouseEvent me)
{
boolean contain1;
int mx,my;
gg=(Graphics2D)l.getGraphics();
gg.setColor(new Color(255,0,0) );
gg.fillPolygon(pp1);
mx = me.getX();
my = me.getY();
//check if mouse cursor is inside polygon or not
// do not print anything if next cursor position is in same state
contain1=pp1.contains(mx,my);
if (contain1) {
startHovercurrent = true;
if(startHovercurrent!=startHoverprev)
System.out.println("Inside");
startHoverprev=startHovercurrent;
}
else {
startHovercurrent = false;
if(startHovercurrent!=startHoverprev)
System.out.println("Outside");
startHoverprev=startHovercurrent;
}
}
public void mouseDragged(MouseEvent me)
{
}
public void actionPerformed(ActionEvent ae)
{
}
}
For this usage, How to Use Tool Tips suggests overriding the getToolTipText() method of the enclosing JComponent. This answer outlines the approach for JMapViewer and ChartPanel. In the example below, getToolTipText() simply returns the name of any Shape that contains() the triggering mouse event. For comparison, the JLabel at window's bottom gets a conventional too tip via setToolTipText().
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
/**
* #see https://stackoverflow.com/a/53609066/230513
* #see https://stackoverflow.com/a/25944439/230513
*/
public class ShapeToolTip {
private static class ShapePanel extends JPanel {
private final List<Shape> list = new ArrayList<>();
public ShapePanel() {
Polygon p = new Polygon();
p.addPoint(500, 100);
p.addPoint(500, 400);
p.addPoint(200, 400);
list.add(p);
list.add(new Ellipse2D.Double(100, 100, 200, 200));
ToolTipManager.sharedInstance().registerComponent(this);
}
#Override
public String getToolTipText(MouseEvent e) {
for (Shape shape : list) {
if (shape.contains(e.getX(), e.getY())) {
return shape.getClass().getName();
}
}
return "Outside";
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.blue);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(2));
for (Shape shape : list) {
g2d.draw(shape);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
}
private void display() {
JFrame f = new JFrame("ShapeToolTip");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new ShapePanel());
JLabel title = new JLabel("Shape Tool Tip", JLabel.CENTER);
title.setToolTipText("Title");
title.setFont(title.getFont().deriveFont(Font.BOLD, 24));
f.add(title, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new ShapeToolTip()::display);
}
}

Is it possible to start drag on mousePressed using java Swing DnD api?

In the example below there is a standard way to trigger drag and drop, which is mousePress+mouseMove.
import javax.swing.*;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
public class DndExample extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new DndExample());
}
public DndExample() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel dragLabel = createDndLabel();
getContentPane().add(dragLabel);
pack();
setVisible(true);
}
private JLabel createDndLabel() {
JLabel label = new JLabel("Drag me, please");
DragGestureListener dragGestureListener = (dragTrigger) -> {
dragTrigger.startDrag(null, new StringSelection(label.getText()));
};
DragSource dragSource = DragSource.getDefaultDragSource();
dragSource.createDefaultDragGestureRecognizer(label, DnDConstants.ACTION_COPY, dragGestureListener);
return label;
}
}
Is it possible to trigger startDrag on mousePressed without mouseMove? The desired behaviour is something like that: I press the mouse button then cursor changes indicating that drag has started, if mouse is moved than drag is continued. I obviously know that I may add MouseListener and change cursor manually but there is much more code needed to restore previous cursor.
Because you're asking for non-standard behaviour, you're going to need to do the "extra" lifting yourself, this requires you to have a MouseListener with mousePressed setting the cursor and mouseReleased resting it (so if the user just clicks and doesn't drag the component, you don't end up with a stupid cursor state) and the DragGestureListener#dragDropEnd also resetting the cursor.
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
public class DragAndDropTest {
public static void main(String[] args) {
new DragAndDropTest();
}
public DragAndDropTest() {
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 {
public TestPane() {
setLayout(new GridLayout(1, 2));
add(new DropPane());
add(new DragPane());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class DragPane extends JPanel {
private DragSource ds;
private Transferable transferable;
public DragPane() {
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
#Override
public void mouseReleased(MouseEvent e) {
setCursor(Cursor.getDefaultCursor());
}
});
ds = new DragSource();
transferable = new Transferable() {
#Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.stringFlavor};
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.stringFlavor.equals(flavor);
}
#Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
return "This is a test";
}
};
ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() {
#Override
public void dragGestureRecognized(DragGestureEvent dge) {
// This is where you would export the data you want
// to transfer
ds.startDrag(dge, Cursor.getPredefinedCursor(Cursor.HAND_CURSOR), transferable, new DragSourceListener() {
#Override
public void dragEnter(DragSourceDragEvent dsde) {
}
#Override
public void dragOver(DragSourceDragEvent dsde) {
}
#Override
public void dropActionChanged(DragSourceDragEvent dsde) {
}
#Override
public void dragExit(DragSourceEvent dse) {
}
#Override
public void dragDropEnd(DragSourceDropEvent dsde) {
setCursor(Cursor.getDefaultCursor());
}
});
}
});
setLayout(new GridBagLayout());
add(new JLabel("Drag from here"));
setBorder(new LineBorder(Color.RED));
}
}
public class DropPane extends JPanel {
private List<Point> dropPoints;
public DropPane() {
dropPoints = new ArrayList<>(25);
setDropTarget(new DropTarget(this, new DropTargetListener() {
#Override
public void dragEnter(DropTargetDragEvent dtde) {
}
#Override
public void dragOver(DropTargetDragEvent dtde) {
}
#Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
#Override
public void dragExit(DropTargetEvent dte) {
}
#Override
public void drop(DropTargetDropEvent dtde) {
// Normally here, I'd inspect the Transferable and make sure
// what is been dropped and can be imported, I'd then go through
// the process of unwrapping the data from the Transferable and
// processing it appropriatly, but in this example, I really don't
// care, I just care about WHERE the event occured
dropPoints.add(dtde.getLocation());
dtde.dropComplete(true);
repaint();
}
}));
setLayout(new GridBagLayout());
add(new JLabel("Drop to here"));
setBorder(new MatteBorder(1, 1, 1, 0, Color.RED));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
for (Point p : dropPoints) {
g.fillOval(p.x - 2, p.y - 2, 5, 5);
}
}
}
}
Now, remember, you're doing something the system doesn't want you to do, so it might turn around and byte you any way
I might consider writing a factory method which took a reference to Component, Transferable (and probably a Cursor) and build and registered the MouseListener and DragSource

Java : Draw Rectangles on mouse click

I want to draw a rectangle every time user clicks on the "Rectangle" button and then clicks on the JFrame based on the event x and y coordinates. I have a component class the draws the rectangle and I have another class that has JFrame mouse press listener.
My Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JComponent;
public class RectangleComponent extends JComponent
{
Rectangle box;
RectangleComponent()
{
box = new Rectangle(5, 10, 20, 30);
repaint();
}
RectangleComponent(int x, int y)
{
box = new Rectangle(x, y, 20, 30);
}
public void paintComponent(Graphics g)
{
// Recover Graphics2D
Graphics2D g2 = (Graphics2D) g;
// Change the color
Color c = new Color(1.0F,0.0F,1.0F);
g2.setColor(c);
// Draw a rectangle
g2.draw(box);
}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Test2
{
static boolean isPressed = false;
public static void main(String[] args)
{
final JFrame frame = new JFrame();
final int FRAME_WIDTH = 400;
final int FRAME_HEIGHT = 400;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Test 2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
JPanel panel = new JPanel();
frame.add(panel,BorderLayout.NORTH);
final JButton btnRectangle = new JButton("Rectangle");
panel.add(btnRectangle);
class RectangleButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
isPressed = true;
}
}
ActionListener rectButtonListener = new RectangleButtonListener();
btnRectangle.addActionListener(rectButtonListener);
class MousePressListener implements MouseListener
{
public void mousePressed(MouseEvent event)
{
int x = event.getX() ;
int y = event.getY() ;
if(isPressed)
{
RectangleComponent rc = new RectangleComponent(x, y);
frame.add(rc);
}
}
public void mouseReleased(MouseEvent event){}
public void mouseClicked(MouseEvent event){}
public void mouseEntered(MouseEvent event){}
public void mouseExited(MouseEvent event){}
}
MousePressListener mListener = new MousePressListener();
frame.addMouseListener(mListener);
frame.setVisible(true);
}
}
Now it seems to be doing what I want, but in very strange way. If I click rectangle and click on the frame I see nothing but then if I maximize the frame the rectangle appears where I click. Why is this happening and what is the fix?
To start off with, when using paintComponent() you need to Override it and call it's super method like so:
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
}
Secondly, Here is your RectangleComponent Class with some slight modifications:
public class RectangleComponent extends JComponent
{
int x, y;
RectangleComponent(int x, int y)
{
this.x = x;
this.y = y;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Color c = new Color(1.0F,0.0F,1.0F);
g.setColor(c);
g.drawRect(x, y, 50, 50);
}
}
I took the x and y variables and made them member variables so we can access them in the paintComponent() method. I also removed the whole "box" idea and did all the drawing and such in the paintCompnent()
There's also some slight modifications that you should make to your Test2 Class;
Personal recommendation, I suggest switching your drawing code to the mouseReleased event. Along with calling revalidate() and repaint() on your JFrame.
public void mouseReleased(MouseEvent event)
{
int x = event.getXOnScreen();
int y = event.getYOnScreen();
if(isPressed)
{
RectangleComponent rc = new RectangleComponent(x, y);
frame.add(rc);
frame.revalidate();
frame.repaint();
}
}
My results:
Maximizing your frame calls repaint() automatically. It would probably be easiest to call repaint() after adding the RectangleComponent to the frame.
if(isPressed)
{
RectangleComponent rc = new RectangleComponent(x, y);
frame.add(rc);
rc.repaint();
}
I figured instead of adding new component upon click, why not just update a component that already exist by adding more content to it and then repainting it.
Here how this was fixed:
import javax.swing.JComponent ;
import java.awt.event.MouseListener ;
import java.awt.event.MouseEvent ;
import java.awt.Component;
import java.awt.Graphics2D ;
import java.awt.Graphics ;
import java.awt.Shape ;
import java.util.ArrayList ;
public class ShapeComponent extends JComponent
{
private ArrayList<Shape> shapes ;
public ShapeComponent(ArrayList<Shape> shapes1)
{
shapes = shapes1;
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
for (Shape shape : shapes)
{
g2.draw(shape);
}
}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Test3
{
static boolean isPressed = false;
static ArrayList<Shape> shapes = new ArrayList<Shape>() ;
public static void main(String[] args)
{
final JFrame frame = new JFrame();
final int FRAME_WIDTH = 400;
final int FRAME_HEIGHT = 400;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Test 2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
JPanel panel = new JPanel();
frame.add(panel,BorderLayout.NORTH);
final JButton btnRectangle = new JButton("Rectangle");
panel.add(btnRectangle);
class RectangleButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
isPressed = true;
}
}
ActionListener rectButtonListener = new RectangleButtonListener();
btnRectangle.addActionListener(rectButtonListener);
final JComponent component = new ShapeComponent(shapes) ;
frame.add(component);
class MousePressListener implements MouseListener
{
public void mousePressed(MouseEvent event)
{
int x = event.getX() ;
int y = event.getY() ;
System.out.println("you have press the mouse at X : " + x + " and Y : " + y);
if(isPressed)
{
Rectangle rnew = new Rectangle(x, y, 20, 30);
shapes.add(rnew);
component.repaint();
System.out.println("the button is pressed");
}
else
{
System.out.println("the button is NOT pressed");
}
}
public void mouseReleased(MouseEvent event){}
public void mouseClicked(MouseEvent event){}
public void mouseEntered(MouseEvent event){}
public void mouseExited(MouseEvent event){}
}
MousePressListener mListener = new MousePressListener();
frame.addMouseListener(mListener);
frame.setVisible(true);
}
}

Moving images in Java

I want to make an image that I drew in the paint class move left across my JFrame as a timer ticks. But I don't know how to do that. Also, I am trying to get my program to make the image disappear when the image is clicked upon.
movingball class
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
import javax.swing.Timer;
public class movingball extends JPanel{
private int move=50;
private Timer timer = new Timer(move, new TimerListener());
private int radius = 10;
private int x = 300;
private int y = 0;
public movingball() {
timer.start();
}
private class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e){
x=x-20;
repaint(); }//trying to get the oval to move left 20
}
protected void paintComponent(Graphics2D g){
super.paintComponent(g);
g.fillOval(x, 100 , radius * 2, radius * 2); }
}
movingControl class
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
public class movingControl extends JPanel {
private movingball ball= new movingball();
public movingControl(){
JPanel panel = new JPanel();
ball.setBorder(new javax.swing.border.LineBorder(Color.red));
panel.addMouseListener(new movingballListener());
setLayout(new BorderLayout());
add(ball, BorderLayout.CENTER);
add(panel, BorderLayout.SOUTH);
}
}
SnniperGameApp class
I know I spelled sniper wrong
import javax.swing.JApplet;
public class SnniperGameApp extends JApplet {
static final long serialVersionUID = 2777718668465204446L;
//i dont know what this serial thing is. But my program wont start without it
public SnniperGameApp(){
add(new movingControl());
}
}
ClickingEvent class
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
class movingballListener extends MouseAdapter{
public void mouseReleased(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_DOWN_MASK) != 0) {
System.out.println( (e.getPoint()));}}
}
You haven't over-ridden paintComponent() properly.
From the javadoc, the signature of paintComponent() is:
protected void paintComponent(Graphics g)
but you have:
protected void paintComponent(Graphics2D g)
The method signatures must match - you can safely cast the Graphics to a Graphics2D inside the method if needed.
Adding the #Override annotation to a method is a good way to get the compiler to check that you really are over-riding a method, not just writing a method that looks the same!
Here's a working SSCCE (I have inlined some of the constants to save space, don't take that as good practice for real code!):
public class MovingBall extends JPanel
{
private Timer timer = new Timer(50, new TimerListener());
private int x = 300;
public MovingBall()
{
timer.start();
}
private class TimerListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
x -= 20;
repaint();
}
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.fillOval(x, 100, 20, 20);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new MovingBall());
frame.setSize(500, 500);
frame.setVisible(true);
}
}

Displaying image on clicking JButton

Im trying to display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import java.awt.*;
public class new2 extends JFrame implements ActionListener
{
private boolean b1,b2;
Container contentPane= getContentPane();
JButton awar=new JButton("#war");
JButton arrow=new JButton("arrow");
private Image image1,image2;
public new2()
{
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.setLayout(new FlowLayout());
awar.addActionListener(this);
contentPane.add(awar).setVisible(true);
arrow.addActionListener(this);
contentPane.add(arrow).setVisible(true);
}
public void init()
{
image1=Toolkit.getDefaultToolkit().getImage("#war.jpeg");
image2=Toolkit.getDefaultToolkit().getImage("arrow.gif");
}
public void paint(Graphics g)
{
if(b1==true)
{
g.drawImage(image1,0,0,this);
}
else if(b2==true)
{
g.drawImage(image2,0,0,this);
}
}
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
if(actionCommand.equals("#war"))
{
b1=true;
}
else if(actionCommand.equals("arrow"))
{
b2=true;
}
}
public static void main(String args[])
{
new2 m=new new2();
m.setVisible(true);
}
}
..display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
Use a JToggleButton as shown here.
The buttons should set the boolean variables, but your paint2 is never called after the action preformed method. Secondly, it doesn't really even paint anything, it never gets graphics and will cause NPEs.
You should override the JFrame.paint(Graphics g) method.
Whenever you want to refresh the content of the JFrame instance call the JFrame.repaint() method.
/**
*
*/
package com.samples;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
/**
* #author
*
*/
public class MyFrame extends JFrame implements ActionListener {
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
private Image image = null;
private boolean showImage = false;
public MyFrame(String filename) {
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
this.image = new ImageIcon(filename).getImage();
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(createControls(), BorderLayout.SOUTH);
}
private JPanel createControls() {
JButton showButton = new JButton("Show");
showButton.addActionListener(this);
showButton.setActionCommand(SHOW_ACTION);
JButton hideButton = new JButton("Hide");
hideButton.addActionListener(this);
hideButton.setActionCommand(HIDE_ACTION);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add(showButton);
panel.add(hideButton);
return panel;
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (showImage) {
g.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), null);
}
}
#Override
public void actionPerformed(ActionEvent event) {
String actionCommand = event.getActionCommand();
if (SHOW_ACTION.equals(actionCommand)) {
showImage = true;
} else if (HIDE_ACTION.equals(actionCommand)) {
showImage = false;
}
repaint();
}
/**
* #param args
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MyFrame frame = new MyFrame("resources/image.jpg");
frame.setVisible(true);
}
});
}
}

Categories

Resources