I'm making a desktop app (a Markdown editor) in Java, and I'm having problems on frame resizing. The frame I'm working on is undecorated. On the left side of the frame is a title bar. The content pane uses a FlowLayout(FlowLayout.LEFT, 0, 0) as the
default layout. My problem is when I use the following code to achive resizing function, I can only resize my frame on X and Y axis but not both sides at the same time (when you put your cursor on a vertex of the frame), and the layout isn't working. My goal is to complete a full-functioned resizing system which you can drag and drop the edges of the frame to adjust the size of it.
My Code:
package xmark.ui;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MyFrame extends JFrame {
private final TitleBar titleBar = new TitleBar(); // public class TitleBar extends JPanel
/**
* The original content pane on the frame. Is a holder of the title bar.
*/
public JPanel contentPane = (JPanel) getContentPane();
/**
* The default constructor. No needs to manually pass in any arguments
* because it automatically decorates the frame and sets up the title
* bar. There are two private methods used in the constructor: {@code setUI()}
* and {@code titleBar()}.
*/
public MyFrame() {
setUI();
titleBar();
}
private void setUI() {
// Basic method settings
setSize(new Dimension(1200, 750));
setMinimumSize(new Dimension(120, 75));
setLocationRelativeTo(null);
setUndecorated(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
contentPane.setBackground(UIUtilities.BASE_COLOR); // UIUtilities is a ui utility class for this app
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
// Sizing function
contentPane.addMouseMotionListener(new MouseAdapter() {
boolean top = false;
boolean down = false;
boolean left = false;
boolean right = false;
Point draggingAnchor = null;
@Override
public void mouseMoved(MouseEvent e) {
double mouseY = e.getPoint().getY();
double mouseX = e.getPoint().getX();
if (mouseY > 1 && mouseY < 6) {
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
top = true;
} else if (Math.abs(mouseY - getSize().getHeight()) <= 5) {
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
down = true;
} else if (mouseX > 1 && mouseX < 6) {
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
left = true;
} else if (Math.abs(mouseX - getSize().getWidth()) <= 5) {
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
right = true;
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
draggingAnchor = new Point(e.getX() + contentPane.getX(), e.getY() + contentPane.getY());
top = false;
down = false;
left = false;
right = false;
}
}
@Override
public void mouseDragged(MouseEvent e) {
Dimension dimension = getSize();
if (top) {
dimension.setSize(dimension.getWidth(), dimension.getHeight() - e.getY());
setSize(dimension);
setLocation(getLocationOnScreen().x, getLocationOnScreen().y + e.getY());
} else if (down) {
dimension.setSize(dimension.getWidth(), e.getY());
setSize(dimension);
} else if (left) {
dimension.setSize(dimension.getWidth() - e.getX(), dimension.getHeight());
setSize(dimension);
setLocation(getLocationOnScreen().x + e.getX(), getLocationOnScreen().y);
} else if (right) {
dimension.setSize(e.getX(), dimension.getHeight());
setSize(dimension);
} else {
setLocation(e.getLocationOnScreen().x - draggingAnchor.x, e.getLocationOnScreen().y - draggingAnchor.y);
}
}
});
}
private void titleBar() {
contentPane.add(titleBar);
}
public static void main(String[] args) {
new MyFrame().setVisible(true);
}
}