简体   繁体   English

Java Swing及图纸问题

[英]Java Swing and drawing problem

I have a problem with drawing.我画画有问题。 I have a frame with one button.我有一个带有一个按钮的框架。 Using the mouse, I draw a transculent rectangle.使用鼠标,我画了一个半透明的矩形。 But I have a small problem, because when drawing this rectangle, it is drawing behind the button and I want this rectangle to be over the button.但我有一个小问题,因为在绘制这个矩形时,它在按钮后面绘制,我希望这个矩形在按钮上方。

This is a screenshot:这是一个截图:

And this is the code:这是代码:

package draw;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;


public class Selection extends JPanel
    implements  ChangeListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private static final int WIDE = 640;
    private static final int HIGH = 640;  
    private List<Node> nodes = new ArrayList<Node>();
    private Point mousePt = new Point(WIDE / 2, HIGH / 2);
    private Rectangle mouseRect = new Rectangle();
    private boolean selecting = false;

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

            public void run() {
                JFrame f = new JFrame("GraphPanel");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                Selection gp = new Selection(); 
                f.add(new JScrollPane(gp), BorderLayout.CENTER);                
                f.pack();
                f.setVisible(true);
            }
        });
    }

    Selection() {
        JButton but=new JButton("Button");
        add(but);

        this.setPreferredSize(new Dimension(WIDE, HIGH));      
        this.addMouseListener(new MouseHandler());
        this.addMouseMotionListener(new MouseMotionHandler());
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(new Color(0x00f0f0f0));
        g.fillRect(0, 0, getWidth(), getHeight());


            g.setColor(Color.BLACK);
            ((Graphics2D) g).setComposite(AlphaComposite.getInstance(rule, alpha));
            g.fillRect(mouseRect.x, mouseRect.y,
                    mouseRect.width, mouseRect.height);

            g.drawRect(mouseRect.x, mouseRect.y,
                mouseRect.width, mouseRect.height);

    }
    int rule = AlphaComposite.SRC_OVER;
    float alpha = 0.85F;


    private class MouseHandler extends MouseAdapter {

        @Override
        public void mouseReleased(MouseEvent e) {
            selecting = false;
            mouseRect.setBounds(0, 0, 0, 0);
            if (e.isPopupTrigger()) {

            }
            e.getComponent().repaint();
        }

        @Override
        public void mousePressed(MouseEvent e) {
            mousePt = e.getPoint();

                Node.selectNone(nodes);
                selecting = true;          
            e.getComponent().repaint();
        }      
    }

    private class MouseMotionHandler extends MouseMotionAdapter {


        @Override
        public void mouseDragged(MouseEvent e) {
            if (selecting) {
                mouseRect.setBounds(
                    Math.min(mousePt.x, e.getX()),
                    Math.min(mousePt.y, e.getY()),
                    Math.abs(mousePt.x - e.getX()),
                    Math.abs(mousePt.y - e.getY()));

            } 
            e.getComponent().repaint();
        }
    }



    /** A Node represents a node in a graph. */
    private static class Node {

        private Color color;

        private boolean selected = false;
        private Rectangle b = new Rectangle();

        /** Draw this node. */
        public void draw(Graphics g) {
            g.setColor(this.color);

            if (selected) {
                g.setColor(Color.darkGray);
                g.drawRect(b.x, b.y, b.width, b.height);
            }
        }




       /** Mark this node as slected. */
         public void setSelected(boolean selected) {
            this.selected = selected;
        }

        /** Select no nodes. */
        public static void selectNone(List<Node> list) {
            for (Node n : list) {
                n.setSelected(false);
            }
        }
  }



    @Override
    public void stateChanged(ChangeEvent arg0) {
        // TODO Auto-generated method stub

    }

}

How can I solve this problem?我怎么解决这个问题?

You draw the rectangle on the panel that is behind the button.您在按钮后面的面板上绘制矩形。 (There's no way to let an underlying component draw on top of a child component.) If the rectangle should be on top of the button, the component you're drawing on must be on top of the button. (没有办法让底层组件绘制在子组件的顶部。)如果矩形应该在按钮的顶部,那么您正在绘制的组件必须在按钮的顶部。 (Such component has to be non-opaque though, since if it was opaque, it would always cover the button and the button wouldn't be visible. (这样的组件必须是非透明的,因为如果它是不透明的,它总是会覆盖按钮并且按钮将不可见。

I'd suggest you draw the rectangle on some glass-pane or something, which lies on top of the whole frame.我建议你在一些玻璃板或其他东西上绘制矩形,它位于整个框架的顶部。

Why don't you do the drawing on the glass pane which you can get from a frame.您为什么不在可以从框架中获得的玻璃板上进行绘图。 For how to do it check out the tutorial.有关如何做到这一点,请查看教程。

You should have all your painting code in a class that extends JPanel.您应该将所有绘画代码放在扩展 JPanel 的 class 中。 Then create an object and set it as the glasspane of your frame.然后创建一个 object 并将其设置为框架的玻璃板。 Plus you must remember to set it to visible as it is hidden by default.另外,您必须记住将其设置为可见,因为默认情况下它是隐藏的。

Normally custom painting is done by overriding the paintComponent() method.通常自定义绘画是通过覆盖 paintComponent() 方法来完成的。 So the painting order is to paint the component and then the children are painted.所以绘制顺序是先绘制组件,然后绘制子项。 So the button is painted on top of the rectangle.所以按钮被绘制在矩形的顶部。

In this case you want the rectangle to be painted after the children so you can do this by overriding the paint() method.在这种情况下,您希望在孩子之后绘制矩形,因此您可以通过覆盖 paint() 方法来完成此操作。 Now the panel and its children will be painted.现在将绘制面板及其子项。 Then your rectangle will be painted so it gets painted on top of the button.然后你的矩形将被绘制,所以它被绘制在按钮的顶部。

So your basic code should be:所以你的基本代码应该是:

    @Override
    public void paint(Graphics g)
    {
        super.paint(g); // added this

        g.setColor(new Color(0x00f0f0f0));
//      g.fillRect(0, 0, getWidth(), getHeight());

        g.setColor(Color.BLACK);
        ((Graphics2D) g).setComposite(AlphaComposite.getInstance(rule, alpha));
        g.fillRect(mouseRect.x, mouseRect.y, mouseRect.width, mouseRect.height);
        g.drawRect(mouseRect.x, mouseRect.y, mouseRect.width, mouseRect.height);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM