I would like to know if theres a possibility to implement the resizing of a JFrame in that manner, that it's been resized like for example the standart windows in linux. To be more precise: If the user starts do drag, only the future size if the window will be previewed, while the original content is not resized. As soon as the user releases the mouse, the Frame resizes to that size. In images:
(1) state before resizing
(2) user starts to drage (at the red circle)
(3) user releases the mouse, the frame gets resized
Is it possible to realize that in Java Swing?
EDIT:
As this program one day should run also in lower Java RE as the 7, I tried to combine mKorbel suggestions with and the suggestion in the comment with the translucend Frame. The result is close to the goal, except that
I think the first point is resolvable by a combination of the code and a MouseListener, something like if mouseReleased(), then resize . Here is the code, feel free to try it. For further suggestions I'm still happy about any suggestions.
The code is a slightly modification of the GradientTranslucentWindowDemo.java from the Java Tutorials. I hope it's permitted to post it here, otherwise please indicate me any violation against copyright causas. The black JPanel is supposed to be the content of the application, where as the contentPane stays invisible.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
public class GroundFrame extends JFrame {
Timer timer;
JPanel panel2;
public GroundFrame() {
super("GradientTranslucentWindow");
setBackground(new Color(0,0,0,0));
setSize(new Dimension(300,200));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel() {
panel.setBackground(new Color(0,0,0,0));
setContentPane(panel);
setLayout(null);
panel2 = new JPanel();
panel2.setBackground(Color.black);
panel2.setBounds(0,0,getContentPane().getWidth(), getContentPane().getHeight());
getContentPane().add(panel2);
addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {}
@Override
public void componentResized(ComponentEvent e) {
timer = new Timer(50, new Action() {
@Override
public void actionPerformed(ActionEvent e) {
if(timer.isRunning()){
}else{
resizePanel(getContentPane().getSize());
}
}
@Override
public void setEnabled(boolean b) {}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {}
@Override
public void putValue(String key, Object value) {}
@Override
public boolean isEnabled() {return false;}
@Override
public Object getValue(String key) {return null;}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {}
});
timer.setRepeats(false);
timer.start();
}
@Override
public void componentMoved(ComponentEvent e) {}
@Override
public void componentHidden(ComponentEvent e) {}
});
}
public void resizePanel(Dimension dim){
panel2.setBounds(0,0,dim.width, dim.height);
repaint();
}
public static void main(String[] args) {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
boolean isPerPixelTranslucencySupported =
gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
if (!isPerPixelTranslucencySupported) {
System.out.println(
"Per-pixel translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GroundFrame gtw = new GroundFrame();
gtw.setVisible(true);
}
});
}
}
+1 to mKorbel and Denis Tulskiy's answers.
I did a sort of abstract solution which might be of help. It supports resizing (increasing and decreasing height and width) of JFrame
from all four sides of the JFrame
(NORTH, EAST, SOUTH and WEST) it also can be re-sized by width and height simultaneously when mouse is moved to one of the for corners.
Basically what I did was:
MouseMotionListener
and MouseListener
to JFrame
mouseDragged(..)
, mouseMoved(..)
, mousePressed(..)
and mouseReleased(..)
of Listener
s.JFrame
to be non resizable.mouseMoved(..)
listen for when mouse is 10px or less from bottom or right side. of JFrame
, it then sets the appropriate direction of resize (height or width), changes mouse Cursor
(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)
for far right/width resizing, Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)
for bottom/hieght resizing, Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)
for top of frame height resizing or Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)
for left side width resizing) accordingly and call canResize(true)
.mouseDragged(..)
update the width or height for new size as its dragged in directionmouseReleased(..)
set the JFrame
to the new size.mousePressed(..)
we check for user pressed co-ordinates (this allows us to see if frame size is decreasing/increasing).Check out this example I made:
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrameSizeAfterDrag extends JFrame {
//direction holds the position of drag
private int w = 0, h = 0, direction, startX = 0, startY = 0;
public JFrameSizeAfterDrag() {
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(new MouseAdapter() {
//so we can see if from where the user clikced is he increasing or decraesing size
@Override
public void mousePressed(MouseEvent me) {
super.mouseClicked(me);
startX = me.getX();
startY = me.getY();
System.out.println("Clicked: " + startX + "," + startY);
}
//when the mouse is relaeased set size
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
System.out.println("Mouse released");
if (direction == 1 || direction == 2 || direction == 5 || direction == 6) {
setSize(w, h);
} else {//this should move x and y by as much as the mouse moved then use setBounds(x,y,w,h);
setBounds(getX() - (startX - me.getX()), getY() - (startY - me.getY()), w, h);
}
validate();
}
});
addMouseMotionListener(new MouseAdapter() {
private boolean canResize;
//while dragging check direction of drag
@Override
public void mouseDragged(MouseEvent me) {
super.mouseDragged(me);
System.out.println("Dragging:" + me.getX() + "," + me.getY());
if (canResize && direction == 1) {//frame height change
if (startY > me.getY()) {//decrease in height
h -= 4;
} else {//increase in height
h += 4;
}
} else if (canResize && direction == 2) {//frame width change
if (startX > me.getX()) {//decrease in width
w -= 4;
} else {//increase in width
w += 4;
}
} else if (canResize && direction == 3) {//frame height change
if (startX > me.getX()) {//decrease in width
w += 4;
} else {//increase in width
w -= 4;
}
} else if (canResize && direction == 4) {//frame width change
if (startY > me.getY()) {//decrease in height
h += 4;
} else {//increase in height
h -= 4;
}
} else if (canResize && direction == 5) {//frame width and height change bottom right
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
} /* Windows dont usually support reszing from top but if you want :) uncomment code in mouseMoved(..) also
else if (canResize && direction == 6) {//frame width and height change top left
if (startY > me.getY() && startX > me.getX()) {//decrease in height and with
h += 4;
w += 4;
} else {//increase in height and width
h -= 4;
w -= 4;
}
} else if (canResize && direction == 8) {//frame width and height change top right
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
}
*/ else if (canResize && direction == 7) {//frame width and height change bottom left
if (startY > me.getY() && startX > me.getX()) {//increase in height and width
h -= 4;
w -= 4;
} else {//decrease in height and with
h += 4;
w += 4;
}
}
}
@Override
public void mouseMoved(MouseEvent me) {
super.mouseMoved(me);
if (me.getY() >= getHeight() - 10 && me.getX() >= getWidth() - 10) {//close to bottom and right side of frame show south east cursor and allow height witdh simaltneous increase/decrease
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
direction = 5;
} /*Windows dont usually support reszing from top but if you want :) uncomment code in mouseDragged(..) too
else if (me.getY() <= 28 && me.getX() <= 28) {//close to top side and left side of frame show north west cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
direction = 6;
} else if (me.getY() <= 28 && me.getX() >= getWidth() - 10) {//close to top and right side of frame show north east cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
direction = 8;
}
*/ else if (me.getY() >= getHeight() - 10 && me.getX() <= 10) {//close to bottom side and left side of frame show north west cursor and only allow increase/decrease in width and height simultaneosly
//System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
direction = 7;
} else if (me.getY() >= getHeight() - 10) {//close to bottom of frame show south resize cursor and only allow increase height
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
direction = 1;
} else if (me.getX() >= getWidth() - 10) {//close to right side of frame show east cursor and only allow increase width
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
direction = 2;
} else if (me.getX() <= 10) {//close to left side of frame show east cursor and only allow increase width
//System.out.println("resize allowed");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
direction = 3;
} else if (me.getY() <= 28) {//close to top side of frame show east cursor and only allow increase height
// System.out.println("resize allowed..");
canResize = true;
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
direction = 4;
} else {
canResize = false;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
// System.out.println("resize not allowed");
}
}
});
//just so GUI is visible and not small
add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
});
pack();
setVisible(true);
}
@Override
public void setVisible(boolean bln) {
super.setVisible(bln);
w = getWidth();
h = getHeight();
}
public static void main(String[] args) {
/**
* Create GUI and components on Event-Dispatch-Thread
*/
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JFrameSizeAfterDrag();
}
});
}
}
UPDATE:
Great example you made I fixed the code by adding MouseAdapter
which overrides mouseReleased(..)
which calls resizePanel(...)
when mouseReleased(..)
see here for the fixed code (also fixed a few minor things like added ComponentAdapter
instead of ComponentListener
and AbstractAction
instead of Action
):
import java.awt.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class JFrameSizeAfterDrag2 extends JFrame {
private Timer timer;
private JPanel panel2;
boolean canResize = true,firstTime = true;
public JFrameSizeAfterDrag2() {
super("GradientTranslucentWindow");
setBackground(new Color(0, 0, 0, 0));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(new JPanel(null) {//contentpane layout is null only
@Override
protected void paintComponent(Graphics g) {
Paint p = new GradientPaint(0.0f, 0.0f, new Color(0, 0, 0, 0), 0.0f, getHeight(), new Color(0, 0, 0, 0), true);
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
});
panel2 = new JPanel();
panel2.setBackground(Color.black);
getContentPane().add(panel2);
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
if (canResize) {
resizePanel(getContentPane().getSize());
}
}
});
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
timer = new Timer(50, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
canResize = false;
} else {
canResize = true;
if (firstTime == true) {
firstTime = false;
resizePanel(getContentPane().getSize());
}
}
}
});
timer.setRepeats(false);
timer.start();
}
});
pack();
}
public void resizePanel(Dimension dim) {
panel2.setBounds(0, 0, dim.width, dim.height);
revalidate();
}
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
boolean isPerPixelTranslucencySupported = gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
if (!isPerPixelTranslucencySupported) {
System.out.println("Per-pixel translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrameSizeAfterDrag2 gtw = new JFrameSizeAfterDrag2();
gtw.setVisible(true);
}
});
}
}