Java resize layout by resizing element

84 Views Asked by At

I have a problem.

I have JFrame element. Inside this frame element there's PaintingPanel (extends swing JPanel class) with layout set to FlowLayout(FlowLayout.LEFT) and fixed width and height. Inside PaintingPanel there's CanvasPanel element (extends JPanel class aswell). CanvasPanel has layout set to GroupLayout (2x2). In the left top cell I have canvas element. In other 3 cells I have resizers for canvas. Resizer extends JPanel class aswell.

When resizing canvas I want to resize CanvasPanel aswell with the (canvas) resizers. I also want the resizers to be fit the canvas dimension:

  1. right, horizontal resizer should have width of 10px and height of canvas
  2. bottom, vertical resizer should have width of canvas and height of 10px
  3. bottom-right, (both horizontal and vertical) resizer should be 10px by 10px

I also don't want to resize PaintingPanel.

How can I acheive desired result?

This is the code of the layout in CanvasPanel:

private void setDefaultLayout()
{
    GroupLayout layout = new GroupLayout(this);
    setLayout(layout);
    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);
    layout.setHorizontalGroup(
        layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                .addComponent(canvas)
                .addComponent(resizers.get("middle-right")))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
                .addComponent(resizers.get("bottom-middle"))
                .addComponent(resizers.get("bottom-right")))
    );
    layout.setVerticalGroup(
        layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(canvas)
                .addComponent(resizers.get("bottom-middle")))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(resizers.get("middle-right"))
                .addComponent(resizers.get("bottom-right")))
    );
}

This is the current method for resizing the CanvasPanel

public void resizeCanvas(int width, int height)
{
    this.width = width + 40;
    this.height = height + 40;
    setSize(width, height);
    setPreferredSize(new Dimension(this.width, this.height));
    setMinimumSize(new Dimension(this.width, this.height));
    setMaximumSize(new Dimension(this.width, this.height));
    canvas.setSize(width, height);
}

May anyone help?

1

There are 1 best solutions below

0
Przemek Kro On

I've already found solution and I post it below. I've done it by using setLayout(null) and setBounds() method. Code isn't refactorized yet.

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;

public class Launcher
{
    private int offsetX = 10, offsetY = 10;
    private HashMap<String, Res> resizers = new HashMap<String, Res>();
    private JFrame frame;
    private JScrollPane pane;
    private Canvas canvas;

public static void main(String[] args)
{
    Launcher l = new Launcher();
    l.create();
}

public void create()
{
    initFrame();

    int canvasWidth = 200;
    int canvasHeight = 200;

    canvas = new Canvas();
    canvas.setSize(canvasWidth, canvasHeight);
    canvas.setPreferredSize(new Dimension(canvasWidth, canvasHeight));
    canvas.setMinimumSize(new Dimension(canvasWidth, canvasHeight));
    canvas.setMaximumSize(new Dimension(canvasWidth, canvasHeight));
    canvas.setBackground(Color.WHITE);
    canvas.setVisible(true);
    canvas.setBounds(offsetX, offsetY, canvasWidth, canvasHeight);
    canvas.repaint();

    resizers.put("horizontal", new Res(
            this,
            2*offsetX + canvasWidth,
            offsetY,
            Res.DEFAULT_WIDTH,
            canvasHeight
    ));
    resizers.put("vertical", new Res(
            this,
            offsetX,
            2*offsetY + canvasHeight,
            canvasWidth,
            Res.DEFAULT_WIDTH
    ));
    resizers.put("both", new Res(
            this,
            2*offsetX + canvasWidth,
            2*offsetY + canvasHeight,
            Res.DEFAULT_WIDTH,
            Res.DEFAULT_WIDTH
    ));

    pane = new JScrollPane();
    pane.setLayout(null);
    pane.setBackground(Color.LIGHT_GRAY);
    pane.add(canvas);
    pane.add(resizers.get("horizontal"));
    pane.add(resizers.get("vertical"));
    pane.add(resizers.get("both"));

    frame.add(pane, BorderLayout.CENTER);
    frame.pack();
}

public void resizeCanvasBy(int x, int y)
{
    int width = canvas.getWidth() + x;
    int height = canvas.getHeight() + y;
    canvas.setSize(width, height);
    canvas.setPreferredSize(new Dimension(width, height));
    canvas.setMinimumSize(new Dimension(width, height));
    canvas.setMaximumSize(new Dimension(width, height));

    resizers.get("horizontal").setBounds(
            2*offsetX + width, offsetY, Res.DEFAULT_WIDTH, height);
    resizers.get("vertical").setBounds(
            offsetX, 2*offsetY + height, width, Res.DEFAULT_WIDTH);
    resizers.get("both").setBounds(
            2*offsetX + width, 2*offsetY + height, Res.DEFAULT_WIDTH, Res.DEFAULT_WIDTH);
}

public void initFrame()
{
    frame = new JFrame();
    frame.setPreferredSize(new Dimension(400, 400));
    frame.setMinimumSize(new Dimension(400, 400));
    frame.setMaximumSize(new Dimension(400, 400));
    frame.setResizable(true);
    frame.setUndecorated(false);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public class Res extends JPanel implements MouseListener
{
    public static final int DEFAULT_WIDTH = 10;
    private Launcher launcher;
    private int pressedX, pressedY;

    public Res(Launcher launcher, int x, int y, int width, int height)
    {
        this.launcher = launcher;
        setPreferredSize(new Dimension(width, height));
        setMinimumSize(new Dimension(width, height));
        setMaximumSize(new Dimension(width, height));
        setVisible(true);
        addMouseListener(this);
        setBounds(x, y, width, height);
        repaint();
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mousePressed(MouseEvent e)
    {
        pressedX = e.getX();
        pressedY = e.getY();
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
        int deltaX = e.getX() - pressedX;
        int deltaY = e.getY() - pressedY;
        launcher.resizeCanvasBy(deltaX, deltaY);
    }

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}
}

}