Reputation: 596
I have a jFrame with no decoration only gui is drawn by graphics GD. I want users to resize this window but its impossible to do so without borders. So I made a mouse listener to resize when being dragged from a special position. It works a little bit but doesn't extend far until it stops. Is there a more simple way? are there other alternatives? has anyone ever done this with pure GD?
this.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
posX=e.getX();
posY=e.getY();
}
}});
this.addMouseMotionListener(new MouseAdapter()
{
public void mouseDragged(MouseEvent evt)
{
if (posX >= getWidth()-25 && posY >=getHeight()-45){
int nlx= evt.getXOnScreen()-(location().x-12);
int nly= evt.getYOnScreen()-(location().y-32);
setSize(nlx,nly);
setBackground(new Color(0, 0, 0, 0));
invalidate();
}else{
setLocation (evt.getXOnScreen()-posX,evt.getYOnScreen()-posY);
}
}
});
}
Upvotes: 2
Views: 4568
Reputation: 10153
Here is a full mouse adapter i am using for a long time now:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* @see http://stackoverflow.com/a/12456113/909085
*/
public class WindowResizeAdapter extends MouseAdapter implements SwingConstants
{
private boolean resizing = false;
private int prevX = -1;
private int prevY = -1;
private int resizeSide = 0;
public static void install ( Component component, int resizeSide )
{
WindowResizeAdapter wra = new WindowResizeAdapter ( resizeSide );
component.addMouseListener ( wra );
component.addMouseMotionListener ( wra );
}
public WindowResizeAdapter ( int resizeSide )
{
super ();
this.resizeSide = resizeSide;
}
public void mousePressed ( MouseEvent e )
{
if ( SwingUtilities.isLeftMouseButton ( e ) )
{
resizing = true;
}
prevX = e.getXOnScreen ();
prevY = e.getYOnScreen ();
}
public void mouseDragged ( MouseEvent e )
{
if ( prevX != -1 && prevY != -1 && resizing )
{
Window w = SwingUtilities.getWindowAncestor ( e.getComponent () );
Rectangle rect = w.getBounds ();
Dimension dim;
boolean undecorated;
if ( w instanceof JDialog )
{
dim = ( ( JDialog ) w ).getContentPane ().getPreferredSize ();
undecorated = ( ( JDialog ) w ).isUndecorated ();
}
else if ( w instanceof JFrame )
{
dim = ( ( JFrame ) w ).getContentPane ().getPreferredSize ();
undecorated = ( ( JFrame ) w ).isUndecorated ();
}
else
{
dim = w.getPreferredSize ();
undecorated = true;
}
// Checking for minimal width and height
int xInc = e.getXOnScreen () - prevX;
int yInc = e.getYOnScreen () - prevY;
if ( undecorated )
{
if ( resizeSide == SwingConstants.NORTH_WEST || resizeSide == SwingConstants.WEST ||
resizeSide == SwingConstants.SOUTH_WEST )
{
if ( rect.width - xInc < dim.width )
{
xInc = 0;
}
}
else if ( resizeSide == SwingConstants.NORTH_EAST ||
resizeSide == SwingConstants.EAST ||
resizeSide == SwingConstants.SOUTH_EAST )
{
if ( rect.width + xInc < dim.width )
{
xInc = 0;
}
}
if ( resizeSide == SwingConstants.NORTH_WEST ||
resizeSide == SwingConstants.NORTH ||
resizeSide == SwingConstants.NORTH_EAST )
{
if ( rect.height - yInc < dim.height )
{
yInc = 0;
}
}
else if ( resizeSide == SwingConstants.SOUTH_WEST ||
resizeSide == SwingConstants.SOUTH ||
resizeSide == SwingConstants.SOUTH_EAST )
{
if ( rect.height + yInc < dim.height )
{
yInc = 0;
}
}
}
// Resizing window if any changes are done
if ( xInc != 0 || yInc != 0 )
{
if ( resizeSide == SwingConstants.NORTH_WEST )
{
w.setBounds ( rect.x + xInc, rect.y + yInc, rect.width - xInc,
rect.height - yInc );
}
else if ( resizeSide == SwingConstants.NORTH )
{
w.setBounds ( rect.x, rect.y + yInc, rect.width, rect.height - yInc );
}
else if ( resizeSide == SwingConstants.NORTH_EAST )
{
w.setBounds ( rect.x, rect.y + yInc, rect.width + xInc, rect.height - yInc );
}
else if ( resizeSide == SwingConstants.WEST )
{
w.setBounds ( rect.x + xInc, rect.y, rect.width - xInc, rect.height );
}
else if ( resizeSide == SwingConstants.EAST )
{
w.setBounds ( rect.x, rect.y, rect.width + xInc, rect.height );
}
else if ( resizeSide == SwingConstants.SOUTH_WEST )
{
w.setBounds ( rect.x + xInc, rect.y, rect.width - xInc, rect.height + yInc );
}
else if ( resizeSide == SwingConstants.SOUTH )
{
w.setBounds ( rect.x, rect.y, rect.width, rect.height + yInc );
}
else if ( resizeSide == SwingConstants.SOUTH_EAST )
{
w.setBounds ( rect.x, rect.y, rect.width + xInc, rect.height + yInc );
}
prevX = e.getXOnScreen ();
prevY = e.getYOnScreen ();
}
}
}
public void mouseReleased ( MouseEvent e )
{
resizing = false;
}
}
Just use its "install" method to add the window resize behavior to any Component. The resizeSide variable is used to define which side of the window should be resized (for example SwingConstants.SOUTH_EAST will force the component to resize bottom right corner of the window).
Edit: You might also want to modify the code for your specific case so that drag (resize) will start only from some specific area on the component. Just modify the mousePressed method to do that.
Upvotes: 2
Reputation: 6307
I did a similar thing with a jFrame, I got around it by adding 4 very thin buttons around the outside of my jFrame, and used the mousepressed and mousedragged listener from the buttons to control jFrame resizing, it worked out pretty smoothly.
The mousePressed listener lets us get the starting location so I can calculate the distance that the frame is dragged/resized
If you want to save on resources you should resize all child components when the mouse is released not when it is dragged
Edit: Example of resizing the frame on the X axis.
public class NewJFrame extends javax.swing.JFrame
{
//demo locations
int X1 = 0;
int X2 = 0;
public NewJFrame()
{
initComponents();
}
@SuppressWarnings("unchecked")
private void initComponents() {
ResizeEast = new javax.swing.JButton();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setUndecorated(true);
ResizeEast.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
ResizeEastMousePressed(evt);
}
public void mouseReleased(java.awt.event.MouseEvent evt) {
ResizeEastMouseReleased(evt);
}
});
ResizeEast.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
ResizeEastMouseDragged(evt);
}
});
jButton1.setText("Close");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 320, Short.MAX_VALUE)
.addComponent(ResizeEast, javax.swing.GroupLayout.PREFERRED_SIZE, 11, javax.swing.GroupLayout.PREFERRED_SIZE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addContainerGap(266, Short.MAX_VALUE))
.addComponent(ResizeEast, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
);
pack();
}
private void ResizeEastMousePressed(java.awt.event.MouseEvent evt)
{
//set mosuepressed location to X1 and Y1
X1 = evt.getX();
}
private void ResizeEastMouseReleased(java.awt.event.MouseEvent evt)
{
//update the location and size of all child components
}
private void ResizeEastMouseDragged(java.awt.event.MouseEvent evt)
{
//resize jframe on the fly
X2 = evt.getX();
//set minimum size to 100 wide
if ((getWidth() - (X1 - X2)) < 100)
{
X2 = X1;
}
//resize east side only
this.setSize(getWidth() - (X1 - X2), getHeight());
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
System.exit(0);
}
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
new NewJFrame().setVisible(true);
}
});
}
// Variables
private javax.swing.JButton ResizeEast;
private javax.swing.JButton jButton1;
}
For re-sizing from the corners create small corner buttons that resize X and Y like so: YourFrame.setSize(getWidth() - (X1 - X2), getHeight() - (Y1 - Y2));
Upvotes: 2