Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
482 views
in Technique[技术] by (71.8m points)

swing - Java - Custom Shape Panels?

I am working on an application that involves the user requiring to hover over several moving dots on the screen in order to launch specific popups. At the moment, i am listening for mouseMoved events on the JPanel onto which the dots are rendered, and then launching the required pop ups whenever the cursor is within a specific distance of a dot.

When i have hundreds of dots - this probably becomes quite expensive.

Wouldnt the ideal solution be to represent my 'dots' as small components and register a mouse listener with each dot?

Does anyone know how i might represent a small ellipse with a JComponent?

Many thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is some old code which shows how to create a "round" JButton. I would extend JComponent instead and the important methods to override are paintComponent() and contains():

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

public class RoundButton extends JButton {
    public RoundButton(String label) {
        super(label);

        // These statements enlarge the button so that it
        // becomes a circle rather than an oval.
        Dimension size = getPreferredSize();
        size.width = size.height = Math.max(size.width, size.height);
        setPreferredSize(size);

        // This call causes the JButton not to paint the background.
        // This allows us to paint a round background.
        setContentAreaFilled(false);
    }

    // Paint the round background and label.
    protected void paintComponent(Graphics g) {
    if (getModel().isArmed()) {
            // You might want to make the highlight color
            // a property of the RoundButton class.
            g.setColor(Color.lightGray);
        } else {
            g.setColor(getBackground());
        }
    g.fillOval(0, 0, getSize().width-1, getSize().height-1);

        // This call will paint the label and the focus rectangle.
    super.paintComponent(g);
    }

    // Paint the border of the button using a simple stroke.
    protected void paintBorder(Graphics g) {
        g.setColor(getForeground());
        g.drawOval(0, 0, getSize().width-1, getSize().height-1);
    }

    // Hit detection.
    Shape shape;
    public boolean contains(int x, int y) {
        // If the button has changed size, make a new shape object.
        if (shape == null || !shape.getBounds().equals(getBounds())) {
            shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
        }
        return shape.contains(x, y);
    }

    // Test routine.
    public static void main(String[] args) {
        // Create a button with the label "Jackpot".
        JButton button = new RoundButton("Jackpot");
        button.setBackground(Color.green);
        button.setBounds(0, 0, 100, 100);

        JButton button2 = new RoundButton("Jackpot2");
        button2.setBackground(Color.red);
        button2.setBounds(50, 50, 100, 100);

        // Create a frame in which to show the button.
        JFrame frame = new JFrame();
        frame.getContentPane().setBackground(Color.yellow);
        frame.getContentPane().setLayout(null);
        frame.getContentPane().add(button);
        frame.getContentPane().add(button2);
//        frame.getContentPane().setLayout(new FlowLayout());
        frame.setSize(200, 200);
        frame.setVisible(true);

        MouseListener mouseListener = new MouseAdapter() {
            public void mouseEntered( MouseEvent e )
            {}

            public void mouseExited( MouseEvent e )
            {}

            public void mouseClicked( MouseEvent e )
            {
                System.out.println( "clicked " );
            }

            public void mousePressed( MouseEvent e )
            {
                System.out.println( "pressed " );
            }

            public void mouseReleased( MouseEvent e )
            {
                System.out.println( "released " );
            }
        };
        button.addMouseListener( mouseListener );

    }
}

This simplifies the hit detection easily since there is no custom code. Also it allows you to control overlapping of compnents easily since you can control the Z-Order of each component.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...