I have got questions about my java code. My goal is to make a JFrame, in which I can have multiple draggable images which snap to a grid.
I can add only one draggable image. The dragging and snapping to grid works fine. As soon as I try to add more draggable images to the JFrame (Which i try to do near the bottom of the MainScreen.java file), it displays only the last one I added.
MainScreen.java
package systematics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class MainScreen extends JFrame {
private static Image img = Toolkit.getDefaultToolkit().getImage("C:/Users/lenar_000/Pictures/splitter skin.png");
public static JFrame main = new JFrame();
public static Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
public static JPanel content = new JPanel();
public static JMenuBar menubar = new JMenuBar();
public static ArrayList<JMenuItem> menuitem = new ArrayList<JMenuItem>();
public static ArrayList<JMenu> menu = new ArrayList<JMenu>(20);
public static ArrayList<JComponent> gates = new ArrayList<JComponent>();
public static componentGate gate = new componentGate(0, 1, 1, null);
public static int imageWidth = 60, imageHeight = 60, imageX, imageY, gridw = 10, gridh = 10;
public static DragImage componentimage = new DragImage(img, 300, 300, 200, 200);
public static DragImage componentimage1 = new DragImage(img, 50, 50, 50, 50);
public static JFrame createmain() {
//location and size of the window
main.setJMenuBar(createmenu());
main.setExtendedState(JFrame.MAXIMIZED_BOTH);
int w = (int) screensize.getWidth();
int h = (int) screensize.getHeight();
main.setSize((int) (w / 2), (int) (h / 2));
int w1 = (int) main.getSize().getWidth();
int h1 = (int) main.getSize().getHeight();
int x = (screensize.width-w1)/2;
int y = (screensize.height-h1)/2;
main.setLocation(x, y);
//other stuff
main.setVisible(true);
main.setTitle("systematic");
main.setDefaultCloseOperation(EXIT_ON_CLOSE);
return main;
}
//unused
public static JPanel createcontent() {
content.setBackground(Color.DARK_GRAY);
content.setVisible(true);
content.setOpaque(true);
return content ;
}
//to make the menubar
public static JMenuBar createmenu() {
//add the items to the arrays which hold the menu's and the menuitems
menu.add(0, new JMenu());
menu.add(1, new JMenu());
menu.add(2, new JMenu());
menuitem.add(0, new JMenuItem());
menuitem.add(1, new JMenuItem());
menuitem.add(2, new JMenuItem());
//some settings for the menubar
menubar.setOpaque(true);
menubar.setVisible(true);
menubar.setBackground(new Color(255, 255, 255));
//adding the first menu which contains a submenu
menu.get(0).setText("File");
menu.get(0).setOpaque(true);
menu.get(0).setBackground(new Color(255, 255, 255));
menubar.add(menu.get(0), 0);
menuitem.get(0).setText("new file");
menuitem.get(0).setToolTipText("creates and opens a new file");
menuitem.get(0).setOpaque(true);
menuitem.get(0).setBackground(new Color(255, 255, 255));
menu.get(0).add(menuitem.get(0), 0);
//adding the second menu which contains a submenu
menu.get(1).setText("Toolbars");
menu.get(1).setOpaque(true);
menu.get(1).setBackground(new Color(255, 255, 255));
menubar.add(menu.get(1), 1);
menuitem.get(1).setText("components");
menuitem.get(1).setToolTipText("toggle for the components toolbar");
menuitem.get(1).setOpaque(true);
menuitem.get(1).setBackground(new Color(255, 255, 255));
menu.get(1).add(menuitem.get(1), 0);
//adding the third menu which contains a submenu
menu.get(2).setText("Toolbars");
menu.get(2).setOpaque(true);
menu.get(2).setBackground(new Color(255, 255, 255));
menubar.add(menu.get(2), 2);
menuitem.get(2).setText("components");
menuitem.get(2).setToolTipText("toggle for the components toolbar");
menuitem.get(2).setOpaque(true);
menuitem.get(2).setBackground(new Color(255, 255, 255));
menu.get(2).add(menuitem.get(2), 0);
return menubar;
}
public static void main(String[] args) {
createmain();
//creategrid();
main.getContentPane().add(componentimage, 0);
main.getContentPane().add(componentimage1, 1);
}
//unused
private static void creategrid() {
DrawingLine line1 = new DrawingLine();
main.getContentPane().add(line1,-1);
}
private static final long serialVersionUID = 1L;
}
DragImage
package systematics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;
public class DragImage extends JComponent implements MouseMotionListener, MouseListener {
private static final long serialVersionUID = 1L;
private int imageWidth, imageHeight, gridw = 50, gridh = 50, imageX/* = gridw / 2 - imageWidth / 2*/, imageY/* = gridh / 2 - imageHeight / 2*/, onObject, checked;
private Image image;
DragImage(Image i, int imgX, int imgY, int imagewidth, int imageheight) {
this.imageWidth = imagewidth;
this.imageHeight = imageheight;
this.imageX = imgX;
this.imageY = imgY;
this.image = i.getScaledInstance(imageWidth, imageHeight, 0);
addMouseMotionListener(this);
addMouseListener(this);
}
public void mouseDragged(MouseEvent e) {
//first checking if "onObject" is 1 to make sure that the mouse is on the image when it started dragging
if(this.onObject == 1) {
if((int) (Math.floor(e.getX() / this.gridw) * this.gridw + (this.gridw / 2) - (this.imageWidth / 2)) != this.imageX || (int) (Math.floor(e.getY() / this.gridh) * this.gridh + (this.gridh / 2) - (this.imageHeight / 2)) != this.imageY) {
this.imageX = (int) (Math.floor(e.getX() / this.gridw) * this.gridw + (this.gridw / 2) - (this.imageWidth / 2));
this.imageY = (int) (Math.floor(e.getY() / this.gridh) * this.gridh + (this.gridh / 2) - (this.imageHeight / 2));
this.repaint();
}
}
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
//repainting the object that you are dragging at the new location, which is determined by the math in "mouseDragged"
g2.drawImage(this.image, this.imageX, this.imageY, this);
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
//this checks if the mouse is on the object when you start dragging, for the method mouseDragged runs when you drag, regardless of the mouse position
System.out.println("");
System.out.println("pressed, checked is now: " + this.checked);
if(this.checked == 0 && (e.getX() >= this.imageX) && (e.getY() >= this.imageY) && (e.getX() <= this.imageX + (this.imageWidth)) && (e.getY() <= this.imageY + (this.imageHeight))) {
this.onObject = 1;
System.out.println("onObject: " + this.onObject);
}
//checked is a parameter, which is used to make sure that this method doesn't run all the time, but only when the mouse started dragging
this.checked = 1;
System.out.println("checked: " + this.checked);
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("");
System.out.println("released, checked is now: " + this.checked);
this.onObject = 0;
System.out.println("onObject: " + this.onObject);
//setting checked to 0 when the mouse stops dragging, so when it starts dragging, it can check wether the mouse is on the image yes or no
checked = 0;
System.out.println("checked: " + this.checked);
}
//some unused implemented methods
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Btw, I'm quite proud of that math to do the snapping to grid :)
Any solution is highly appreciated
The default layout of JFrame's contentPane is BorderLayout. You are doing
main.getContentPane().add(componentimage, 0);
main.getContentPane().add(componentimage1, 1);
the second parameter should be one of BorderLayout.CENTER, BorderLayout.NORTH, etc.
But your other problem is that DragImage.getPreferredSize() is going to return (0,0) since you haven't added anything to it. You need to override getPreferredSize or use setPreferredSize on your DragImages for them to be allotted space in the ContentPane.