我有一个JFrame
withBorderLayout
作为布局管理器。
在南边,我有一个JPanel
,我希望JPanel
用户可以调整它的大小,即用户可以点击边框的边缘并将其向上拖动以使其变大。
你有什么办法知道我可以做到这一点吗?
我有一个JFrame
withBorderLayout
作为布局管理器。
在南边,我有一个JPanel
,我希望JPanel
用户可以调整它的大小,即用户可以点击边框的边缘并将其向上拖动以使其变大。
你有什么办法知道我可以做到这一点吗?
为了使框架中的面板可以单独调整大小,您需要将它们添加到JSplitPane
.
不要把它放在框架的南部,而是把它放在JSplitPane
中心。拆分窗格将使拆分中的底部面板看起来像是在南方,而拆分中的顶部面板将位于框架的中心。
确保使用 设置两个面板的方向setOrientation(JSplitPane.VERTICAL_SPLIT )
。
然后,您可以调整窗格中的面板的大小。
我想你的意思是说JPanel。您可以添加自定义 mouseListener 并处理鼠标单击、拖动和鼠标释放,然后以编程方式调整面板大小。
这将证明这一点。请注意,jframe 不会使用 JPanel 自动调整大小。为了使效果更明显,我将面板涂成红色并添加了斜角边框:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
@SuppressWarnings("serial")
public class ResizablePanel extends JPanel {
private boolean drag = false;
private Point dragLocation = new Point();
public ResizablePanel() {
setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
setPreferredSize(new Dimension(500, 500));
final JFrame f = new JFrame("Test");
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
drag = true;
dragLocation = e.getPoint();
}
@Override
public void mouseReleased(MouseEvent e) {
drag = false;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if (drag) {
if (dragLocation.getX()> getWidth()-10 && dragLocation.getY()>getHeight()-10) {
System.err.println("in");
setSize((int)(getWidth()+(e.getPoint().getX()-dragLocation.getX())),
(int)(getHeight()+(e.getPoint().getY()-dragLocation.getY())));
dragLocation = e.getPoint();
}
}
}
});
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(this,BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new ResizablePanel();
}
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
如果你想看看,我为此做了一个课程。它还没有完成。
package projetoSplitPainel;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.JSplitPane;
/**
* This Components is based on the JSplitPane. JSplitPane is used to divide two
* (and only two) Components. This class intend to manipulate the JSplitPane in
* a way that can be placed as many Component as wanted.
*
* @author Bode
*
*/
public class JSplitPaneMultiTabs extends JSplitPane {
private ArrayList<JSplitPane> ecanpsulationList = new ArrayList<JSplitPane>();
private int numberOfComponents = 1;
private int sizeOfDivision = 6;
/**
* Builds the Pane
*/
public JSplitPaneMultiTabs() {
super();
this.setLeftComponent(null);
this.setBorder(null);
ecanpsulationList.add(this);
setAllBorders(sizeOfDivision);
}
/**
*
* @param comp - adds a Component to the Pane
*/
public void addComponent(Component comp) {
JSplitPane capsule = new JSplitPane();
capsule.setRightComponent(null);
capsule.setLeftComponent(comp);
capsule.setDividerSize(sizeOfDivision);
capsule.setBorder(null);
ecanpsulationList.get(numberOfComponents - 1).setRightComponent(capsule);
ecanpsulationList.add(capsule);
numberOfComponents++;
this.fixWeights();
}
/**
*
* @param orientation
* JSplitPane.HORIZONTAL_SPLIT - sets the orientation of the
* Components to horizontal alignment
* @param orientation
* JSplitPane.VERTICAL_SPLIT - sets the orientation of the
* Components to vertical alignment
*/
public void setAlignment(int orientation) {
for (int i = 0; i < numberOfComponents; i++) {
ecanpsulationList.get(i).setOrientation(orientation);
}
}
/**
*
* @param newSize - resizes the borders of the all the Components of the Screen
*/
public void setAllBorders(int newSize) {
this.setDividerSize(newSize);
for (int i = 0; i < numberOfComponents; i++) {
ecanpsulationList.get(i).setDividerSize(newSize);
}
}
/**
* each Component added needs to be readapteded to the screen
*/
private void fixWeights() {
ecanpsulationList.get(0).setResizeWeight(1.0);
for (int i = 1; i < numberOfComponents; i++) {
double resize = (double) 1 / (double) (i + 1);
ecanpsulationList.get(numberOfComponents - i - 1).setResizeWeight(
resize);
}
ecanpsulationList.get(numberOfComponents - 1).setResizeWeight(0.0);
}
}
所以我做了一个类,它主要做 OP 想要的。基本上它是一个可以在单击边框时调整大小的面板。它还(尝试)调整其中包含的所有组件的大小以适应新的大小。它还尝试检测父框架中其他组件之间的冲突,以尽可能防止重叠。
无论如何,你去:
import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JDesktopPane;
@SuppressWarnings("serial")
public class ResizablePanel extends JDesktopPane {
private boolean drag = false;
private boolean top =false;
private boolean bottom =false;
private boolean left=false;
private boolean right =false;
private Point dragLocation = new Point();
public ResizablePanel() {
setMinimumSize(new Dimension(200, 200));
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
evaluateMousePress(e.getPoint());
}
@Override
public void mouseReleased(MouseEvent e) {
drag = false;
setCursor(Cursor.getDefaultCursor());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
evaluateMouseDrag(e.getPoint());
}
@Override
public void mouseMoved(MouseEvent e) {
evaluateMouseHover(e.getPoint());
}
});
}
@Override
public void setBounds(int x, int y, int width, int height) {
Rectangle oldBounds=getBounds();
Rectangle newBounds = new Rectangle(x, y, width, height);
super.setBounds(x, y, width, height);
resizeSingleComponent(this,oldBounds, newBounds);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Stroke stroke = g2.getStroke();
g2.setStroke(new BasicStroke(5));
g.drawRect(0, 0, getBounds().width, getBounds().height);
g2.setStroke(stroke);
}
private void resizeSingleComponent(Component component , Rectangle oldBounds , Rectangle newBounds) {
if(component instanceof Container) {
if(!component.equals(this)) {
Rectangle componentBounds = component.getBounds();
double x = getNew(componentBounds.getX(), oldBounds.getWidth(), newBounds.getWidth());
double y = getNew(componentBounds.getY(), oldBounds.getHeight(), newBounds.getHeight());
double width = getNew(componentBounds.getWidth(), oldBounds.getWidth(), newBounds.getWidth());
double height = getNew(componentBounds.getHeight(), oldBounds.getHeight(), newBounds.getHeight());
componentBounds.width = (int) Math.round(width);
componentBounds.height = (int) Math.round(height);
componentBounds.x = (int) Math.round(x);
componentBounds.y = (int) Math.round(y);
component.setBounds(componentBounds);
}
for(Component child:((Container) component).getComponents())
resizeSingleComponent(child, oldBounds, newBounds);
}
else {
Rectangle componentBounds = component.getBounds();
double x = getNew(componentBounds.getX(), oldBounds.getWidth(), newBounds.getWidth());
double y = getNew(componentBounds.getY(), oldBounds.getHeight(), newBounds.getHeight());
double width = getNew(componentBounds.getWidth(), oldBounds.getWidth(), newBounds.getWidth());
double height = getNew(componentBounds.getHeight(), oldBounds.getHeight(), newBounds.getHeight());
componentBounds.width = (int) Math.round(width);
componentBounds.height = (int) Math.round(height);
componentBounds.x = (int) Math.round(x);
componentBounds.y = (int) Math.round(y);
component.setBounds(componentBounds);
}
}
private void evaluateMouseDrag(Point point) {
if (drag) {
if (top || left || right || bottom) {
int heightIncrement=0;
int widthIncrement=0;
int posX = getBounds().x;
int posY = getBounds().y;
if(top || bottom)
heightIncrement = (int) (point.getY()-dragLocation.getY());
if(left || right)
widthIncrement = (int) (point.getX()-dragLocation.getX());
if(top) {
posY = posY+heightIncrement;
heightIncrement=-heightIncrement;
}
if(left) {
posX=posX+widthIncrement;
widthIncrement=-widthIncrement;
}
if(right)
dragLocation.x=(int) point.getX();
if(bottom)
dragLocation.y=(int) point.getY();
Rectangle bounds = new Rectangle(posX, posY, getWidth()+ widthIncrement,getHeight()+ heightIncrement);
justifyCollision(bounds,point);
}
}
}
private void evaluateMousePress(Point point) {
drag = true;
dragLocation = point;
top=dragLocation.getY() <=5;
left=dragLocation.getX() <=5;
bottom = dragLocation.getY() >=getHeight()-5;
right = dragLocation.getX() >=getWidth()-5;
setResizeCursor(point);
}
private void evaluateMouseHover(Point point) {
if(!drag) {
top=point.getY() <=5;
left=point.getX() <=5;
bottom = point.getY() >=getHeight()-5;
right = point.getX() >=getWidth()-5;
setResizeCursor(point);
}
}
private void justifyCollision(Rectangle bounds, Point point) {
//justify undersizing
if(bounds.width<getMinimumSize().width) {
if(left)
bounds.x= getBounds().x;
bounds.width=getWidth();
}
if(bounds.height<getMinimumSize().height) {
if(top)
bounds.y=getBounds().y;
bounds.height=getHeight();
}
Container parent = getParent();
//justify parent container bounds
if(bounds.x<0 ||bounds.width+bounds.x>parent.getWidth()) {
bounds.width = getWidth();
if(right &&!(bounds.width+bounds.x>parent.getWidth()))
dragLocation.x=(int) point.getX();
if(bounds.x<0)
bounds.x=0;
}
if(bounds.y<0 ||bounds.height+bounds.y>parent.getHeight()) {
bounds.height = getHeight();
if(bottom &&!(bounds.height+bounds.y>parent.getHeight()))
dragLocation.y=(int) point.getY();
if(bounds.y<0)
bounds.y=0;
}
//justify any other component in it's way
for(Component c:parent.getComponents()) {
if(!c.equals(this) &&c.getBounds().intersects(bounds)) {
evaluateOverlaps(bounds, c,point);
}
}
setBounds(bounds);
}
private Rectangle evaluateOverlaps(Rectangle bounds , Component component,Point point) {
if(bounds.intersects(component.getBounds())) {
if(component instanceof ResizablePanel) {
ResizablePanel panel=(ResizablePanel) component;
Rectangle panelBound=panel.getBounds();
if(top || bottom) {
panelBound.height = panelBound.height - bounds.intersection(panelBound).height;
if(panelBound.height<panel.getMinimumSize().height) {
panelBound.height=panel.getMinimumSize().height;
bounds.height = getHeight();
if(top) {
bounds.y = component.getBounds().y+component.getHeight();
}
}
else if(bottom) {
panelBound.y = panelBound.y + bounds.intersection(panelBound).height;
}
}
else if(left || right) {
panelBound.width = panelBound.width - bounds.intersection(panelBound).width;
if(panelBound.width<panel.getMinimumSize().width) {
panelBound.width=panel.getMinimumSize().width;
bounds.width = getWidth();
if(left) {
bounds.x = component.getBounds().x+component.getWidth();
}
}
else if(right) {
panelBound.x = panelBound.x + bounds.intersection(panelBound).width;
}
}
panel.setBounds(panelBound);
return bounds;
}
if(left || right) {
bounds.width = getWidth();
if(left) {
bounds.x = component.getBounds().x+component.getWidth();
}
}
if(top || bottom) {
bounds.height = getHeight();
if(top) {
bounds.y = component.getBounds().y+component.getHeight();
}
}
}
return bounds;
}
private void setResizeCursor(Point point) {
if(top) {
if(left)
setCursor(new Cursor(Cursor.NW_RESIZE_CURSOR));
else if(right)
setCursor(new Cursor(Cursor.NE_RESIZE_CURSOR));
else
setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
}
else if(bottom) {
if(left)
setCursor(new Cursor(Cursor.SW_RESIZE_CURSOR));
else if(right)
setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
else
setCursor(new Cursor(Cursor.S_RESIZE_CURSOR));
}
else if (left)
setCursor(new Cursor(Cursor.W_RESIZE_CURSOR));
else if (right)
setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
else
setCursor(Cursor.getDefaultCursor());
}
private long getNew(double size,double oldMax,double newMax) {
double value = ((size/oldMax)*newMax);
return Math.round(value);
}
}
您可能必须同时指定JFrame.setResizeable = true;
Parent JFrame
(具有边框布局的那个)和 child JFrame
。
您可能还想JPanel
在南部边界使用 a 。