-1

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?

Przemek Kro
  • 321
  • 1
  • 2
  • 7
  • Calling `pack()` on the top level container should do it. – Andrew Thompson Apr 06 '21 at 16:00
  • Do you mean JFrame element? What if CanvasPanel is inserted inside other JPanel? – Przemek Kro Apr 06 '21 at 16:37
  • 1
    What's a `CanvasPanel`? What's a _canvas element_? What's a _resizer_? Maybe you could [edit] your question and post a [mcve]? – Abra Apr 06 '21 at 16:44
  • *"Do you mean JFrame element?"* Is there another component / window in the app. that has a `pack()` method? *"What if CanvasPanel is inserted inside other JPanel?"* .. what happened when you tried it? – Andrew Thompson Apr 07 '21 at 03:13
  • I tried the scenario of nested JPanels, calling JFrame's `pack()` method (yes, it's the only elemnt 'above' the CanvasPanel which has `pack()` method). It hasn't done anything important. Now I try a different approach to solve this problem using layout null in CanvasPanel. Even PaintingPanel (level above CanvasPanel) may be not necessary. If I'd acheive desired result, I'll post it here. – Przemek Kro Apr 07 '21 at 14:19
  • *"It hasn't done anything important."* It typically works just fine. Post an MRE (as linked in the comment of @Abra) of your attempt, so we can see what's going wrong. – Andrew Thompson Apr 07 '21 at 14:24
  • The code has changed and I haven't commited that one related to the problem, so I may have problem reproducing it 1:1. Now I'm working on different code using different approach. I'd just try to do some research and experiments by myself, because I feel that could be done much easier. If I'd solve this, I'll post the answer. If not, I'd post MRE of what I'd acheive. – Przemek Kro Apr 07 '21 at 17:02

1 Answers1

-1

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

}
Przemek Kro
  • 321
  • 1
  • 2
  • 7