Reputation: 11493
I extended the toolbar on a mac using a JPanel (see image), but the part that is the actualy toolbar (not the JPanel) is the only part that you can click and drag. How do I allow the user to click and drag the JPanel to move the window, just like they would the toolbar
The top mm or so of the image is the actual toolbar (with the text), the rest is the JPanel (with buttons).
Here is the code for the UnifiedToolPanel, which is set to the north of the border layout in the JFrame:
package gui;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import com.jgoodies.forms.factories.Borders;
public class UnifiedToolbarPanel extends JPanel implements WindowFocusListener {
public static final Color OS_X_UNIFIED_TOOLBAR_FOCUSED_BOTTOM_COLOR =
new Color(64, 64, 64);
public static final Color OS_X_UNIFIED_TOOLBAR_UNFOCUSED_BORDER_COLOR =
new Color(135, 135, 135);
public static final Color OS_X_TOP_FOCUSED_GRADIENT = new Color(214+8, 214+8, 214+8);
public static final Color OS_X_BOTTOM_FOCUSED_GRADIENT = new Color(217, 217, 217);
public static final Color OS_X_TOP_UNFOCUSED_GRADIENT = new Color(240+3, 240+3, 240+3);
public static final Color OS_X_BOTTOM_UNFOCUSED_GRADIENT = new Color(219, 219, 219);
public UnifiedToolbarPanel() {
// make the component transparent
setOpaque(true);
Window window = SwingUtilities.getWindowAncestor(this);
// create an empty border around the panel
// note the border below is created using JGoodies Forms
setBorder(Borders.createEmptyBorder("3dlu, 3dlu, 1dlu, 3dlu"));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Window window = SwingUtilities.getWindowAncestor(this);
Color color1 = window.isFocused() ? OS_X_TOP_FOCUSED_GRADIENT
: OS_X_TOP_UNFOCUSED_GRADIENT;
Color color2 = window.isFocused() ? color1.darker()
: OS_X_BOTTOM_UNFOCUSED_GRADIENT;
int w = getWidth();
int h = getHeight();
GradientPaint gp = new GradientPaint(
0, 0, color1, 0, h, color2);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
}
@Override
public Border getBorder() {
Window window = SwingUtilities.getWindowAncestor(this);
return window != null && window.isFocused()
? BorderFactory.createMatteBorder(0,0,1,0,
OS_X_UNIFIED_TOOLBAR_FOCUSED_BOTTOM_COLOR)
: BorderFactory.createMatteBorder(0,0,1,0,
OS_X_UNIFIED_TOOLBAR_UNFOCUSED_BORDER_COLOR);
}
@Override
public void windowGainedFocus(WindowEvent e) {
repaint();
}
@Override
public void windowLostFocus(WindowEvent e) {
repaint();
}
}
Upvotes: 4
Views: 5217
Reputation: 3154
There wasn't really an answer with the Point
class so I will add my contribution. Instead of storing the x, y
cords of the MouseEvent, We store a Point
. Here is how you can do it:
Define 2 variables of type java.awt.Point
:
private Point initialMouseLocation;
private Point initialPanelLocation;
Once the mouse is pressed, we store its initial location and the relative location of the panel using a MouseListener
:
panel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
initialMouseLocation = e.getLocationOnScreen();
initialPanelLocation = panel.getLocation();
}
});
When the mouse is dragged we calculate its travel distance and use it to offset the relative location of the panel:
panel.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
Point finalMouseLocation = e.getLocationOnScreen();
int deltaX = finalMouseLocation.x - initialMouseLocation.x;
int deltaY = finalMouseLocation.y - initialMouseLocation.y;
Point newLocation = new Point(initialPanelLocation.x + deltaX,
initialPanelLocation.y + deltaY);
panel.setLocation(newLocation);
}
});
A complete code sample of a DraggableHelper class is below:
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DraggableHelper {
private Point initialMouseLocation;
private Point initialComponentLocation;
public DraggableHelper(Component component) {
component.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
initialMouseLocation = e.getLocationOnScreen();
initialComponentLocation = component.getLocation();
}
});
component.addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
Point finalMouseLocation = e.getLocationOnScreen();
int deltaX = finalMouseLocation.x - initialMouseLocation.x;
int deltaY = finalMouseLocation.y - initialMouseLocation.y;
Point newLocation = new Point(initialComponentLocation.x + deltaX, initialComponentLocation.y + deltaY);
component.setLocation(newLocation);
}
});
}
}
Upvotes: 2
Reputation: 5055
How do I allow the user to click and drag the JPanel to move the window
Here is the way :
private int x;
private int y;
//.....
//On mouse pressed:
jpanel.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent ev){
x = ev.getX ();
y = ev.getY();
}
});
//....
//on mouse dragged
jpanel.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent evt) {
int x = evt.getXOnScreen()-this.x;
int y = evt.getYOnScreen -this.y;
this.setLocation(x,y);
}
});
this.setLocation(x,y)
will moves the Frame not the panel, I thought that your class extended JFrame
.
However, you can create a method that returns a point (x,y) and set it to the window.
Upvotes: 3