volt
volt

Reputation: 473

java statusbar resize corner (handle)

I try to make a window with a resize handle at the bottom right. So far I managed to detect the mouse hover and dragging.

The mouse cursor is changing to resize cursor successfully.

But the actually resize operation I'm unsure how to solve. The Idea I testet at first place is to just setsize on parent when dragging on resize handle. It works, but then the window get's resize immediately, that's not how the standard resize looks. The standard resize is a transparent window with white border (may be different on different systems and look and feel).

Is it possible to trigger/use the built in resize mechanism? Below you have a sample code.

Thanks!

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class main extends JFrame {

private JPanel contentPane;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                main frame = new main();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public class StatusBar extends JPanel implements MouseListener, MouseMotionListener {

    private Polygon resizeCorner = new Polygon();
    private int offsetX;
    private int offsetY;
    private Dimension offsetSize;
    private Cursor resizeCursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
    private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);

    public StatusBar() {
        super();
        setPreferredSize(new Dimension(200,40));
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
    }

    private void createResizeHandle() {
        resizeCorner.reset();
        resizeCorner.addPoint(getWidth()-2, getHeight()-2);
        resizeCorner.addPoint(getWidth()-40, getHeight()-2);
        resizeCorner.addPoint(getWidth()-2, getHeight()-40);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2;
        g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        g2.setColor(Color.red);
        createResizeHandle();
        g2.drawPolygon(resizeCorner);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
            int width = (int) (this.offsetSize.getWidth() - this.offsetX + e.getXOnScreen());
            int height = (int) (this.offsetSize.getHeight() - this.offsetY + e.getYOnScreen());
            this.getRootPane().getParent().setSize(width, height);
            createResizeHandle();
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        if (resizeCorner.contains(e.getX(), e.getY())) {
            setCursor(resizeCursor);
        } else {
            setCursor(defaultCursor);
        }
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {
    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
    }

    @Override
    public void mouseExited(MouseEvent arg0) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (resizeCorner.contains(e.getX(), e.getY())) {
            this.offsetX = e.getXOnScreen();
            this.offsetY = e.getYOnScreen();
            this.offsetSize = this.getRootPane().getParent().getSize();
        }
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
    }
}


public main() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JLabel lblNewLabel = new JLabel("New label");
    StatusBar bar = new StatusBar();
    contentPane.add(lblNewLabel, BorderLayout.NORTH);
    contentPane.add(bar, BorderLayout.SOUTH);
}
}

Upvotes: 5

Views: 1725

Answers (2)

camickr
camickr

Reputation: 324157

The standard resize is a transparent window with white border (may be different on different systems and look and feel).

When using Windows XP the standard is to resize top level components (frame, dialog etc) immediately. It doesn't matter what the LAF is.

In general other components don't have resizing functionality built in. The only exception to this that I can think of is JInternalFrame. In this case is does support the "outline" resizing of a component.

So if you want to add this type of functionality to your component then you would need to look at the internal frame UI to find the resizing code.

I would guess that the code would display a Glass Pane when dragging starts and then do the outline custom painting on the Glass Plane. Then on mouseReleased the frame size would be changed.

In case you are interested, Component Resizing shows how I do resizing for any component. It does immediate resizing, not outline resizing.

Upvotes: 3

mKorbel
mKorbel

Reputation: 109823

lots of small mistakes, starts with correct naming for ClassName ... end with usage java reserved words for class/void/method's name(s)

enter image description here

minor changes (now it works for me), with one my mistake against Swing rules, I set there setPreferredSize(new Dimension(400, 300));, lets childrens returns PreferredSize for Container

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class MyToolBar extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;

    public class StatusBarX extends JPanel implements MouseListener, MouseMotionListener {

        private static final long serialVersionUID = 1L;
        private Polygon resizeCorner = new Polygon();
        private int offsetX;
        private int offsetY;
        private Dimension offsetSize;
        private Cursor resizeCursor = new Cursor(Cursor.SE_RESIZE_CURSOR);
        private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);

        public StatusBarX() {
            super();
            setPreferredSize(new Dimension(200, 40));
            this.addMouseListener(this);
            this.addMouseMotionListener(this);
        }

        private void createResizeHandle() {
            resizeCorner.reset();
            resizeCorner.addPoint(getWidth() - 2, getHeight() - 2);
            resizeCorner.addPoint(getWidth() - 40, getHeight() - 2);
            resizeCorner.addPoint(getWidth() - 2, getHeight() - 40);
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            Graphics2D g2;
            g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2.setColor(Color.red);
            createResizeHandle();
            g2.drawPolygon(resizeCorner);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
                int width = (int) (this.offsetSize.getWidth() - this.offsetX + e.getXOnScreen());
                int height = (int) (this.offsetSize.getHeight() - this.offsetY + e.getYOnScreen());
                this.getRootPane().getParent().setSize(width, height);
                createResizeHandle();
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            if (resizeCorner.contains(e.getX(), e.getY())) {
                setCursor(resizeCursor);
            } else {
                setCursor(defaultCursor);
            }
        }

        @Override
        public void mouseClicked(MouseEvent arg0) {
        }

        @Override
        public void mouseEntered(MouseEvent arg0) {
        }

        @Override
        public void mouseExited(MouseEvent arg0) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
            if (resizeCorner.contains(e.getX(), e.getY())) {
                this.offsetX = e.getXOnScreen();
                this.offsetY = e.getYOnScreen();
                this.offsetSize = this.getRootPane().getParent().getSize();
            }
        }

        @Override
        public void mouseReleased(MouseEvent arg0) {
        }
    }

    public MyToolBar() {
        JLabel lblNewLabel = new JLabel("New label");
        StatusBarX bar = new StatusBarX();
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        contentPane.add(lblNewLabel, BorderLayout.NORTH);
        contentPane.add(bar, BorderLayout.SOUTH);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocation(100, 100);
        setPreferredSize(new Dimension(400, 300));
        add(contentPane);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    MyToolBar frame = new MyToolBar();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Upvotes: 4

Related Questions