15

我有一个JFramewithBorderLayout作为布局管理器。

在南边,我有一个JPanel,我希望JPanel用户可以调整它的大小,即用户可以点击边框的边缘并将其向上拖动以使其变大。

你有什么办法知道我可以做到这一点吗?

4

5 回答 5

25

为了使框架中的面板可以单独调整大小,您需要将它们添加到JSplitPane.

不要把它放在框架的南部,而是把它放在JSplitPane中心。拆分窗格将使拆分中的底部面板看起来像是在南方,而拆分中的顶部面板将位于框架的中心。

确保使用 设置两个面板的方向setOrientation(JSplitPane.VERTICAL_SPLIT )

然后,您可以调整窗格中的面板的大小。

于 2009-07-13T15:15:24.437 回答
13

我想你的意思是说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());
    }

}
于 2009-07-13T15:07:05.307 回答
0

如果你想看看,我为此做了一个课程。它还没有完成。

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);
    }

}
于 2015-04-18T19:44:23.840 回答
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);
    }
}
于 2021-09-03T13:28:10.863 回答
-4

您可能必须同时指定JFrame.setResizeable = true;Parent JFrame(具有边框布局的那个)和 child JFrame

您可能还想JPanel在南部边界使用 a 。

于 2009-07-13T15:08:02.483 回答