move image from one panel to another - java

I have Code where I can move image.
Everything works well.
here I have only one ImagePanel (children of JPanel) on the frame.
Questions:
I need to drag and drop image from one JPanel to another JPanel.
Then I need to move dragged image to current panel.
Can you give me an example code, please?
class ImagePanel extends JPanel {
int x, y;
BufferedImage image;
ImagePanel() {
setBackground(Color.white);
setSize(450, 400);
addMouseMotionListener(new MouseMotionHandler());
Image img = getToolkit().getImage("C:\\2.png");
MediaTracker mt = new MediaTracker(this);
mt.addImage(img, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Image not found.");
}
image = new BufferedImage(img.getWidth(this), img.getHeight(this),BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.drawImage(img, 0, 0, this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(image, x, y, this);
}
class MouseMotionHandler extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e) {
}
}
}
I need to do that code, with this following design. I need to add image with some layout (I don't need to done this with Point pixels). or how to add image with some layout? for example Grid bag layout. I don't need Points (x,y). because I need to add another components too.
public class DragAndDrop {
private JFrame frame;
/* .. another component here .. */
private JPanel leftPanel; // here is my image
public JPanel rightContentPanel; // destination of dragable image
public static void main(String[] args) {
DragAndDrop window = new DragAndDrop();
}
public DragAndDrop() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.getContentPane().setLayout(new BorderLayout(0, 0));
leftPanel = new leftPanel();
/* add components to left panel */
rightContentPanel = new rightPanel();
/* add component to right panel */
frame.getContentPane().add(rightContentPanel, BorderLayout.CENTER);
frame.getContentPane().add(leftPanel, BorderLayout.WEST);
frame.setVisible(true);
frame.setResizable(false);
}
}
class leftPanel extends JPanel {
/ ... /
}
class rightPanel extends JPanel{
/ ... /
}

There's probably any number of ways to achieve what you want. You could use the glass pane or JXLayer or you could stop treating the two panels as separate elements and more like they were just windows into a large virtual space.
This example basically treats the parent component as the "virtual space" into which the two image panes are windows.
They both share the same image and image location details. They, individual, convert the image location (which is in virtual coordinates) to local coordinates and draw as much of the image as would appear on them...
Mouse control is maintained by the parent. This greatly simplifies the process, as it can notify both the panels simultaneously
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class CrossImage {
public static void main(String[] args) {
new CrossImage();
}
public CrossImage() {
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
private ImagePane left;
private ImagePane right;
private Point imagePoint;
public TestPane() {
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridLayout(0, 2, 10, 10));
left = new ImagePane();
right = new ImagePane();
imagePoint = new Point(10, 10);
left.setImageLocation(imagePoint);
right.setImageLocation(imagePoint);
try {
img = ImageIO.read(new File("Background.jpg"));
left.setImage(img);
right.setImage(img);
} catch (IOException ex) {
ex.printStackTrace();
}
add(left);
add(right);
MouseAdapter mouseHandler = new MouseAdapter() {
private Point delta;
#Override
public void mousePressed(MouseEvent e) {
Point origin = e.getPoint();
Rectangle bounds = new Rectangle(imagePoint, new Dimension(img.getWidth(), img.getHeight()));
if (bounds.contains(origin)) {
delta = new Point(origin.x - imagePoint.x, origin.y - imagePoint.y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (delta != null) {
imagePoint = e.getPoint();
imagePoint.translate(-delta.x, -delta.y);
left.setImageLocation(imagePoint);
right.setImageLocation(imagePoint);
}
}
#Override
public void mouseReleased(MouseEvent e) {
delta = null;
}
};
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);
}
}
public class ImagePane extends JPanel {
private Image image;
private Point imageLocation;
public ImagePane() {
setBorder(new LineBorder(Color.DARK_GRAY));
}
#Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(this), image.getHeight(this));
}
public void setImage(Image image) {
this.image = image;
repaint();
}
public void setImageLocation(Point imageLocation) {
this.imageLocation = imageLocation;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null && imageLocation != null) {
Point p = SwingUtilities.convertPoint(getParent(), imageLocation, this);
g.drawImage(image, p.x, p.y, this);
}
}
}
}

Related

Can I change the location of the ImageIcon that I put on a JLabel in my code?

I tried using, "label.setBounds(100,100,250,250)" and "label.setLocation(100,100)" but the image does not move from the top and center of the JLabel.
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Machine extends JPanel
{
public Machine()
{
ImageIcon imageIcon = new ImageIcon("res/robot.png");
JLabel label = new JLabel(imageIcon);
add(label);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new Machine());
frame.setVisible(true);
frame.setSize(new Dimension(1080, 720));
}
}
What are you trying to do?
The default layout of a JPanel is a FlowLayout with center alignment and the label is displayed at its preferred size. So the label is displayed in the center.
You have a couple of options:
Change the alignment of the FlowLayout to be either LEFT or RIGHT
Don't add the label to the panel. Just add it directly to the frame which uses a BorderLayout.
Then you can do something like:
label.setHorizontalAlignment(JLabel.LEFT);
label.setVerticalAlignment(JLabel.CENTER);
Edit:
was just trying to get the image to be in the middle of the frame
Then post your actual requirement when you ask a question. We don't know what "can I change the location" means to you.
So you would either use the BorderLayout and adjust the horizontal/vertical alignment as already demonstrated.
Or, you could set the layout manager of the frame to be a GridBagLayout and then add the label directly to the frame and use:
frame.add(label, new GridBagConstraints());
Now the label will move dynamically as the frame is resized.
If you want to place an image in a certain location, perhaps best is to draw it directly in your JPanel in a paintComponent method override, using one of Graphics drawImage(...) methods, one that allows placement of the image.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/f/f2/Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Version 2: MouseListener / MouseMotionListener so that the image can be moved
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/thumb/f/f2/"
+ "Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
MyMouse mouse = new MyMouse();
addMouseListener(mouse);
addMouseMotionListener(mouse);
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
private class MyMouse extends MouseAdapter {
private Point offset;
#Override
public void mousePressed(MouseEvent e) {
// check if left mouse button pushed
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// get bounds of the image and see if mouse press within bounds
Rectangle r = new Rectangle(x, y, img.getWidth(), img.getHeight());
if (r.contains(e.getPoint())) {
// set the offset of the mouse from the left upper
// edge of the image
offset = new Point(e.getX() - x, e.getY() - y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
offset = null;
}
private void moveImg(MouseEvent e) {
x = e.getX() - offset.x;
y = e.getY() - offset.y;
repaint();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

How do you make text in a frame change dependent on cursor position?

I have a program that is basically just supposed to change the text of a label when your cursor enters a polygon that is shown on the JPanel. I have tried a few different things with nothing working. Currently I am trying an if statement to make it choose which button to add but it still doesn't change if i move my cursor into the polygon. when the cursor is outside of the polygon the label should say "point is not in the polygon" and when inside it should say "point is in the polygon". Any help would be greatly appreciated.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Chapter3Lab1 extends JFrame{
private RegularPolygonPanel canvas = new RegularPolygonPanel();
public Chapter3Lab1()
{
JPanel panel = new JPanel();
add(canvas, BorderLayout.CENTER);
add(panel, BorderLayout.SOUTH);
canvas.setFocusable(true);
canvas.requestFocusInWindow();
}
public static void main (String[] args)
{
String isInside = "The point is in the polygon";
String notInside = "The point is not in the polygon";
//Create a Polygon object
Polygon polygon = new Polygon();
polygon.addPoint(40,20);
polygon.addPoint(70,40);
polygon.addPoint(60,80);
polygon.addPoint(45,45);
polygon.addPoint(20,60);
JLabel label = new JLabel(isInside, JLabel.CENTER);
JLabel notlabel = new JLabel(notInside, JLabel.CENTER);
Chapter3Lab1 frame = new Chapter3Lab1();;
frame.setTitle("Chapter 3 Lab 1");
frame.setLayout(new FlowLayout());
frame.setLocationRelativeTo(null);// Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200,200);
while (true)
{
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int x = (int) b.getX();
int y = (int) b.getY();
if(polygon.contains(x, y) == false)
{
frame.remove(label);
frame.add(notlabel);
}
else
{
frame.remove(notlabel);
frame.add(label);
}
frame.setVisible(true);
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class RegularPolygonPanel extends JPanel
{
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
//Create a Polygon object
Polygon polygon = new Polygon();
polygon.addPoint(40,20);
polygon.addPoint(70,40);
polygon.addPoint(60,80);
polygon.addPoint(45,45);
polygon.addPoint(20,60);
//Draw the polygon
g.drawPolygon(polygon);
}
public Dimension getPreferredSize()
{
return new Dimension(200,200);
}
}
}
Start by taking a look at How to Write a Mouse Listener
You will need to maintain a reference to the Polygon object and make use of it's contains method to determine if the mouse is within the Polygon itself...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
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 RegularPolygonPanel polyPanel;
private JLabel label;
public TestPane() {
polyPanel = new RegularPolygonPanel();
polyPanel.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
if (polyPanel.isWithinPolygon(e.getPoint())) {
label.setText("Is inside");
} else {
label.setText("Is outside");
}
}
});
label = new JLabel("...");
setLayout(new BorderLayout());
add(polyPanel);
add(label, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
class RegularPolygonPanel extends JPanel {
private Polygon polygon;
public RegularPolygonPanel() {
//Create a Polygon object
polygon = new Polygon();
polygon.addPoint(40, 20);
polygon.addPoint(70, 40);
polygon.addPoint(60, 80);
polygon.addPoint(45, 45);
polygon.addPoint(20, 60);
}
public boolean isWithinPolygon(Point p) {
return polygon.contains(p);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//Draw the polygon
g.drawPolygon(polygon);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}

JPanel with a background image which has some part transparent

My image is like a frame which is transparent in the middle. I want to make it as background image of a JPanel. I have done this but for the transparent part of image, white color is coming. I want to remove this white color so that the components below this Jpanel become visible.
My code for custom JPanel is
public class JPanelWithBackground extends JPanel {
private static final long serialVersionUID = 1L;
Image imageOrg = null;
Image image = null;
{
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
int w = JPanelWithBackground.this.getWidth();
int h = JPanelWithBackground.this.getHeight();
image = w>0&&h>0?imageOrg.getScaledInstance(w,h,
java.awt.Image.SCALE_SMOOTH):imageOrg;
JPanelWithBackground.this.repaint();
});
}
public JPanelWithBackground(Image image2) {
imageOrg=image2;
image=image2;
setOpaque(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (image!=null)
g.drawImage(image, 0, 0, null);
}
}
I don't have any particular problem with your code. The problem is probably that your image is not transparent as you expect.
Here is an example that seems to work perfectly (I only took the liberty to fix minor issues in your code):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JPanelWithBackground extends JPanel {
private static final long serialVersionUID = 1L;
Image imageOrg = null;
public JPanelWithBackground(Image image2) {
imageOrg = image2;
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageOrg.getWidth(this), imageOrg.getHeight(this));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (imageOrg != null) {
System.err.println("painting");
g.drawImage(imageOrg, 0, 0, getWidth(), getHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanelWithBackground panel = new JPanelWithBackground(new ImageIcon(new URL(
"http://www.lemondedemario.fr/images/dossier/bowser/bowser.png")).getImage());
JPanel greenPanel = new JPanel(new BorderLayout());
greenPanel.setBackground(Color.GREEN);
greenPanel.add(panel);
frame.add(greenPanel);
frame.pack();
frame.setVisible(true);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}

Im not sure how to get the data from my text field

My text field is local to main so I cannot access it from actionPerformed, I believe I need to make it a instance variable but I'm not sure how to because my frame is also in main so I'm not sure how I would then add it to the frame.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
import java.net.*;
import java.sql.*;
import java.lang.Object;
import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* This class demonstrates how to load an Image from an external file
*/
public class Test extends JPanel {
int x=77, y=441, w=23, h=10;
BufferedImage img =
new BufferedImage(100, 50,
BufferedImage.TYPE_INT_ARGB);
// BufferedImage img;
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
// g.fillRect(10,10,10,10);
}
public Test() {
try {
img = ImageIO.read(new File("sales-goal.png"));
} catch (IOException e) {}
Graphics2D g = img.createGraphics();
Color myColor = Color.decode("#32004b");
g.setColor(myColor);
g.fillRect(x,y,w,h);
//77,441,23,10
}
public Dimension getPreferredSize() {
if (img == null) {
return new Dimension(100,100);
} else {
//return new Dimension(img.getWidth(null), img.getHeight(null));
return new Dimension(300,600);
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Load Image Sample");
JTextField textField=new JTextField();
f.add(textField);
textField.setBounds(10,10,40,30);
textField.setVisible(true);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(new Test());
f.pack();
f.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
//if (e.getSource() == textField) {}
}
}
I think that you should not set up your swing application this way. Instead of creating everything in the main method you should create a subclass of JFrame and do the initialization in its constructor (or something like that). This class can then hold references to the components it contains. Example:
public class TestFrame extends JFrame {
private JTextField textField;
public TestFrame() {
super("Load Image Sample");
textField = new JTextField();
this.add(textField);
textField.setBounds(10,10,40,30);
textField.setVisible(true);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.add(new Test());
this.pack();
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == textField) {
// ...
}
}
}
create your frame and initialize it inside constructor.
public static void main(String[] args) {
new Test();
}
The event handling method actionPerformed must be registered by an ActionListener interface. As both textField and Test are components of the JFrame a logical place would be the JFrame, or a separate controller class that wires everything together.
I have rewritten your code with a more conventional approach on some details. For that I introduced a new class MyFrame.
public class MyFrame extends JFrame implements ActionListener {
JTextField textField = new JTextField();
public MyFrame(String title) {
super(title); // Or constructor without parameters and:
setTitle("Load Image Sample");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setLayout(...); for instance with null for absolute positioning
add(textField);
textField.setBounds(10, 10, 40, 30);
textField.setVisible(true);
Test panel = new Test();
add(panel);
pack();
}
public static void main(String[] args) {
JFrame f = new MyFrame("Load Image Sample");
f.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Text: " + textField.getText());
}
}
And then your JPanel
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
/**
* This class demonstrates how to load an Image from an external file
*/
class Test extends JPanel {
int x = 77, y = 441, w = 23, h = 10;
BufferedImage img;
Color myColor = Color.decode("#32004b");
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(myColor);
g.fillRect(x, y, w, h);
g.drawImage(img, 0, 0, null);
// g.fillRect(10,10,10,10);
}
public Test() {
setBackground(Color.red);
try {
img = ImageIO.read(new File("sales-goal.png"));
} catch (IOException e) {
img = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
}
setPreferredSize(new Dimension(300, 600));
}
}

java statusbar resize corner (handle)

I try to make a window with a resize handle at the bottom right.
So far I managed to detect the mouse hover and dragging.
The mouse cursor is changing to resize cursor successfully.
But the actually resize operation I'm unsure how to solve.
The Idea I testet at first place is to just setsize on parent when dragging on resize handle.
It works, but then the window get's resize immediately, that's not how the standard resize looks.
The standard resize is a transparent window with white border (may be different on different systems and look and feel).
Is it possible to trigger/use the built in resize mechanism?
Below you have a sample code.
Thanks!
import java.awt.BorderLayout;
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.Polygon;
import java.awt.RenderingHints;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class main extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
main frame = new main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public class StatusBar extends JPanel implements MouseListener, MouseMotionListener {
private Polygon resizeCorner = new Polygon();
private int offsetX;
private int offsetY;
private Dimension offsetSize;
private Cursor resizeCursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
public StatusBar() {
super();
setPreferredSize(new Dimension(200,40));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void createResizeHandle() {
resizeCorner.reset();
resizeCorner.addPoint(getWidth()-2, getHeight()-2);
resizeCorner.addPoint(getWidth()-40, getHeight()-2);
resizeCorner.addPoint(getWidth()-2, getHeight()-40);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2;
g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.setColor(Color.red);
createResizeHandle();
g2.drawPolygon(resizeCorner);
}
#Override
public void mouseDragged(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
int width = (int) (this.offsetSize.getWidth() - this.offsetX + e.getXOnScreen());
int height = (int) (this.offsetSize.getHeight() - this.offsetY + e.getYOnScreen());
this.getRootPane().getParent().setSize(width, height);
createResizeHandle();
}
}
#Override
public void mouseMoved(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
setCursor(resizeCursor);
} else {
setCursor(defaultCursor);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
this.offsetX = e.getXOnScreen();
this.offsetY = e.getYOnScreen();
this.offsetSize = this.getRootPane().getParent().getSize();
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
public main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JLabel lblNewLabel = new JLabel("New label");
StatusBar bar = new StatusBar();
contentPane.add(lblNewLabel, BorderLayout.NORTH);
contentPane.add(bar, BorderLayout.SOUTH);
}
}
lots of small mistakes, starts with correct naming for ClassName ... end with usage java reserved words for class/void/method's name(s)
minor changes (now it works for me), with one my mistake against Swing rules, I set there setPreferredSize(new Dimension(400, 300));, lets childrens returns PreferredSize for Container
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class MyToolBar extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public class StatusBarX extends JPanel implements MouseListener, MouseMotionListener {
private static final long serialVersionUID = 1L;
private Polygon resizeCorner = new Polygon();
private int offsetX;
private int offsetY;
private Dimension offsetSize;
private Cursor resizeCursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
public StatusBarX() {
super();
setPreferredSize(new Dimension(200, 40));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void createResizeHandle() {
resizeCorner.reset();
resizeCorner.addPoint(getWidth() - 2, getHeight() - 2);
resizeCorner.addPoint(getWidth() - 40, getHeight() - 2);
resizeCorner.addPoint(getWidth() - 2, getHeight() - 40);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2;
g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setColor(Color.red);
createResizeHandle();
g2.drawPolygon(resizeCorner);
}
#Override
public void mouseDragged(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
int width = (int) (this.offsetSize.getWidth() - this.offsetX + e.getXOnScreen());
int height = (int) (this.offsetSize.getHeight() - this.offsetY + e.getYOnScreen());
this.getRootPane().getParent().setSize(width, height);
createResizeHandle();
}
}
#Override
public void mouseMoved(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
setCursor(resizeCursor);
} else {
setCursor(defaultCursor);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
if (resizeCorner.contains(e.getX(), e.getY())) {
this.offsetX = e.getXOnScreen();
this.offsetY = e.getYOnScreen();
this.offsetSize = this.getRootPane().getParent().getSize();
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
public MyToolBar() {
JLabel lblNewLabel = new JLabel("New label");
StatusBarX bar = new StatusBarX();
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
contentPane.add(lblNewLabel, BorderLayout.NORTH);
contentPane.add(bar, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(100, 100);
setPreferredSize(new Dimension(400, 300));
add(contentPane);
pack();
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
MyToolBar frame = new MyToolBar();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
The standard resize is a transparent window with white border (may be different on different systems and look and feel).
When using Windows XP the standard is to resize top level components (frame, dialog etc) immediately. It doesn't matter what the LAF is.
In general other components don't have resizing functionality built in. The only exception to this that I can think of is JInternalFrame. In this case is does support the "outline" resizing of a component.
So if you want to add this type of functionality to your component then you would need to look at the internal frame UI to find the resizing code.
I would guess that the code would display a Glass Pane when dragging starts and then do the outline custom painting on the Glass Plane. Then on mouseReleased the frame size would be changed.
In case you are interested, Component Resizing shows how I do resizing for any component. It does immediate resizing, not outline resizing.

Categories