954,549 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Help Creating project with custom components or graphics

I want to create a java application where you can build simple logic circuits (just started learning java recently and it was just a random project idea I got off the net)

Ultimately I want the gates as icons on a pane that users can drag and drop onto a canvas but drag and drop is a bit too far ahead for now.

So I was thinking of a list next to a large white area (a panel or a canvas) and clicking on the canvas or panel should create a new instance of whatever is selected on the list. AND gate, OR gate, etc.

I made the gates by subclassing JLabel (each type of gate is a class) and setting a gif of the gate as the icon in the constructor. I also added code to handle two connections (to be used later when I connect gates on the canvas with lines) and to calculate the truth value of the connections through the gate.

The part I'm stuck on now
How can I add gates on click to a panel (or should I use a canvas) at the location of the click? Also how can I make the label movable after it's been created? If that involves drag and drop I can forget that for now, but the main problem is dynamically instantiating a class at the point of click on the panel. The class is a JLabel subclass.

Srin
Newbie Poster
16 posts since Aug 2011
Reputation Points: 10
Solved Threads: 0
 

In the mouse click handler just create a new AndGate() or whatever and add it to the "canvas" (an ordinary JPanel would do) at the mouse click coordinates (use absolute positioning and a null layout manager for the "canvas").
ps drag'n'drop really isn't that hard - certainly less hard than writing your own code to move things around.

JamesCherrill
Posting Genius
Moderator
6,373 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
 
how can I make the label movable after it's been created


The mouse motion listener will help you with that. It takes some playing with to get it to move smoothly but its possible.

NormR1
Posting Expert
Moderator
6,677 posts since Jun 2010
Reputation Points: 1,138
Solved Threads: 656
 
In the mouse click handler just create a new AndGate() or whatever and add it to the "canvas" (an ordinary JPanel would do) at the mouse click coordinates (use absolute positioning and a null layout manager for the "canvas").

how do I add at an exact position though?

andgate newgate = new andgate();
angate.setbounds(evt.getX,evt.getY,100,50);
jPanel1.add(andgate);
jPanel1.revalidate();

putting that in the mouseclick event would work? I don't have my laptop right now so I'll have to try it later, but, is that it?

Also, is there any way to keep the references to these dynamically created labels?
like, if I had a Vector and added the new andgate to the vector each click event, then even if the method variable newgate gets overridden by a new gate each time, could I still access the old ones for deletion and such through the vector indices?The mouse motion listener will help you with that. It takes some playing with to get it to move smoothly but its possible.

Ok, thanks, if i can get adding the components to a null layout, I can try this.

Srin
Newbie Poster
16 posts since Aug 2011
Reputation Points: 10
Solved Threads: 0
 
any way to keep the references to these dynamically created labels?


Keep them in a list, like Vector or ArrayList

NormR1
Posting Expert
Moderator
6,677 posts since Jun 2010
Reputation Points: 1,138
Solved Threads: 656
 

Here, just for fun, is runnable demo of just how easy it is to drag a JLabel around a container and log the final position. The trick is to remember that the mouse event coordinates are relative to the object being dragged, not the container, so you have to see how much the mouse has moved, and move the JLabel by the same amount.
I deliberately left out the comments to give everyone a learning opportunity ;-)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Demo implements MouseListener, MouseMotionListener {

   public static void main(String[] args) {
      new Demo();
   }

   JLabel sprite = new JLabel("drag me");

   Demo() {
      JFrame frame = new JFrame("drag demo");
      frame.setLayout(null);
      frame.setMinimumSize(new Dimension(400, 300));
      frame.setLocationRelativeTo(null);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      sprite.setBounds(10, 10, 80, 20);
      sprite.addMouseListener(this);
      sprite.addMouseMotionListener(this);
      frame.add(sprite);

      frame.setVisible(true);
   }

   int startDragX, startDragY;
   boolean inDrag = false;

   @Override
   public void mouseEntered(MouseEvent e) {
      // not interested
   }

   @Override
   public void mouseExited(MouseEvent e) {
      // not interested
   }

   @Override
   public void mousePressed(MouseEvent e) {
      startDragX = e.getX();
      startDragY = e.getY();
   }

   @Override
   public void mouseReleased(MouseEvent e) {
      if (inDrag) {
         System.out.println("Sprite dragged to " + sprite.getX() + ", " + sprite.getY());
         inDrag = false;
      }
   }

   @Override
   public void mouseClicked(MouseEvent e) {
      // not interested
   }

   @Override
   public void mouseDragged(MouseEvent e) {
      int newX = sprite.getX() + (e.getX() - startDragX);
      int newY = sprite.getY() + (e.getY() - startDragY);
      sprite.setLocation(newX, newY);
      inDrag = true;
   }

   @Override
   public void mouseMoved(MouseEvent arg0) {
      // not interested
   }

}
JamesCherrill
Posting Genius
Moderator
6,373 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
 
Here, just for fun, is runnable demo of just how easy it is to drag a JLabel around a container and log the final position. The trick is to remember that the mouse event coordinates are relative to the object being dragged, not the container, so you have to see how much the mouse has moved, and move the JLabel by the same amount. I deliberately left out the comments to give everyone a learning opportunity ;-)

Thanks! I tried the adding labels on click in the same code after I finished going through it:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class Test implements MouseListener, MouseMotionListener {
 
   public static void main(String[] args) {
      new Test();
   }
 
   JLabel sprite = new JLabel("drag me");
   JFrame frame = new JFrame("drag demo");
   JPanel panel = new JPanel();
 
   Test() {
      
      frame.setLayout(null);
      frame.setMinimumSize(new Dimension(500, 500));
      frame.setLocationRelativeTo(null);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      Dimension panelsize = new Dimension(400,400);
      panel.setPreferredSize(panelsize);
      panel.setBackground(Color.WHITE);
      panel.setBounds(30, 10, 400, 400);
      sprite.setBounds(10, 10, 80, 20);
      sprite.addMouseListener(this);
      sprite.addMouseMotionListener(this);
      panel.addMouseListener(this);
      panel.setLayout(null);
      frame.add(sprite);
      frame.add(panel);
 
      frame.setVisible(true);
   }
 
   int startDragX, startDragY;
   boolean inDrag = false;
 
   @Override
   public void mouseEntered(MouseEvent e) {
      // not interested
   }
 
   @Override
   public void mouseExited(MouseEvent e) {
      // not interested
   }
 
   @Override
   public void mousePressed(MouseEvent e) {
      startDragX = e.getX();
      startDragY = e.getY();
   }
 
   @Override
   public void mouseReleased(MouseEvent e) {
      if (inDrag) {
         System.out.println("Sprite dragged to " + sprite.getX() + ", " + sprite.getY());
         inDrag = false;
      }
   }
 
   @Override
   public void mouseClicked(MouseEvent e) {
       if (e.getSource()==panel){
       int clickx = e.getX();
       int clicky = e.getY();
       JLabel gate1 = new JLabel("testing");
       gate1.setBounds(clickx, clicky, 100, 50);

       panel.add(gate1);
       panel.revalidate();
       frame.validate();
       }
   }
 
   @Override
   public void mouseDragged(MouseEvent e) {
      int newX = sprite.getX() + (e.getX() - startDragX);
      int newY = sprite.getY() + (e.getY() - startDragY);
      sprite.setLocation(newX, newY);
      inDrag = true;
   }
 
   @Override
   public void mouseMoved(MouseEvent arg0) {
      // not interested
   }
 
}

now when I double click the white panel area, the label is created there, but it only shows up after I drag the "drag me" label over an area after clicking... (I thought it didnt work and just kinda waved the drag me label around in frustration and saw the clicks did create labels)

Since that seems like an odd issue and there are no exceptions, what exactly am I missing here?

Srin
Newbie Poster
16 posts since Aug 2011
Reputation Points: 10
Solved Threads: 0
 

Since you are NOT using a layout manager, I don't think there is a need to validate.
Try calling repaint();

NormR1
Posting Expert
Moderator
6,677 posts since Jun 2010
Reputation Points: 1,138
Solved Threads: 656
 

That works, thanks guys, problems solved.

Srin
Newbie Poster
16 posts since Aug 2011
Reputation Points: 10
Solved Threads: 0
 

cool code thanks

ceyezumma
Light Poster
30 posts since Sep 2009
Reputation Points: 7
Solved Threads: 1
 

I am in the same situation as OP(just started learning java recently and chose this as my project). All this information is very helpful. I would also like to know how to save the circuit into a file so that it can be loaded and used later

v3ga
Junior Poster in Training
95 posts since Oct 2011
Reputation Points: 14
Solved Threads: 4
 

Please start your own thread for your peoblem.

NormR1
Posting Expert
Moderator
6,677 posts since Jun 2010
Reputation Points: 1,138
Solved Threads: 656
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: