java - 单击 GlassPane 时在 GlassPane 后面的 JPanel 上绘图

标签 java swing glasspane

好吧,我浏览了多个论坛和谷歌,但找不到我的具体问题的答案。所以我有两个面板堆叠在一起,上面的一个是玻璃面板。当您在 glassPane 周围拖动鼠标时,它会在光标处绘制一条垂直的红线,这是有效的,但是当我单击 glassPane 时,我希望它在 glassPane 下面的面板上的光标位置绘制一条黑线。我可以让它将 mouseClick 重定向到底部面板,但它不会画线。它只会使红线消失,直到您再次移动鼠标。另外,如果我将 glassPane 设置为不可见并单击底部面板,则会绘制线条,因此绘图代码可以正常工作。提前致谢。

主类

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
public class LiveField extends JPanel {

/**
 * Create the panel.
 */
static JFrame frame;
static JPanel ContentPane;
private JPanel panel;
private MyGlassPane glassPane;
public static void main(String[] args) throws AWTException
{
    LiveField live = new LiveField();
    frame.setVisible(true);
}
public LiveField() throws AWTException {
    frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(1000, 433);
    setLayout(new BorderLayout(0, 0));

    ContentPane = new JPanel();
    frame.setContentPane(ContentPane);
    ContentPane.setLayout(new BorderLayout(0, 0));

    panel = new JPanel()
    {
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            panel.setBackground(new Color(50,160,55));
        }
    };
    glassPane = new MyGlassPane(panel);
    frame.setGlassPane(glassPane);
    glassPane.setVisible(true);
    panel.addMouseListener(new MouseAdapter() {
        int[] pos = new int[2];
        @Override
        public void mouseClicked(MouseEvent e) {
            System.out.println("Handles click event");
            Graphics g = panel.getGraphics();
            g.setColor(new Color(50,165,55));
            g.drawLine(pos[0], pos[1], 0+pos[0], 0);//to top
            g.drawLine(pos[0], pos[1], 0+pos[0], panel.getHeight());//to bottom
            int y = e.getYOnScreen();
            int x = e.getXOnScreen();
            pos[0]= x;
            pos[1] = y;
            g.setColor(new Color(0,0,0));
            g.drawLine(x, y, 0+x, 0);//to top
            g.drawLine(x, y, 0+x, panel.getHeight());//to bottom
            g.dispose();


        }
    });

    ContentPane.add(panel, BorderLayout.CENTER);
}

GlassPane 类

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JComponent;

class MyGlassPane extends JComponent implements ItemListener {
  Point point;



protected void paintComponent(Graphics g) {
}

public void setPoint(Point p) {
    point = p;
}

public MyGlassPane(final Container contentPane) throws AWTException {
    final Component glass = this;
    addMouseMotionListener(new MouseMotionListener()

    {
        ArrayList<Integer> line = new ArrayList<Integer>();
        Robot rb = new java.awt.Robot();
        @Override
        public void mouseMoved(MouseEvent e) {
            //System.out.println("Moving");
            Graphics g = glass.getGraphics();
            if(!line.isEmpty())
            {
                //System.out.println("line is not empty");
                g.setColor(new Color(50,160,55));
                g.drawLine(line.get(0), line.get(1), 0+line.get(0), 0);//to top
                g.drawLine(line.get(0), line.get(1), 0+line.get(0), contentPane.getHeight());//to bottom
            }

                //System.out.println("draw line");
                int x = e.getXOnScreen();
                int y = e.getYOnScreen();
                Color col = rb.getPixelColor(x, y);

                //System.out.println(col.toString() + " : " + Color.white.toString());
                //System.out.println(col.equals(new Color(255,255,255)));
                if(!col.equals(new Color(255,255,255)) && !inEndZone(x))
                {
                    g.setColor(new Color(255,0,0));
                    line = new ArrayList<Integer>();
                    line.add(x);line.add(y);
                    g.drawLine(x, y, 0+line.get(0), 0);//to top
                    g.drawLine(x, y, 0+line.get(0), contentPane.getHeight());//to bottom
                }

                g.dispose();
        }
        private boolean inEndZone(int x) {
            int ends = contentPane.getWidth()/10;
            //System.out.println(x + " : " + ends);
            if(x<ends)
            {
                //System.out.println("In endzone");
                return true;
            }
            else if(x>contentPane.getWidth()-ends)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub

        }
    });
    addMouseListener(new CBListener(this,contentPane));
}

@Override
public void itemStateChanged(ItemEvent e) {
    // TODO Auto-generated method stub
    setVisible(e.getStateChange() == ItemEvent.SELECTED);
}

}

监听器类(用于调度鼠标点击)

import java.awt.Component;
import java.awt.Container;
import java.awt.Point;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;

class CBListener extends MouseInputAdapter {
Toolkit toolkit;
Robot rb;
MyGlassPane glassPane;
Container contentPane;

public CBListener(MyGlassPane glassPane, Container contentPane) {
    toolkit = Toolkit.getDefaultToolkit();
    this.glassPane = glassPane;
    this.contentPane = contentPane;
}


    @Override
public void mouseClicked(MouseEvent e) {
    redispatchMouseEvent(e, false);
}

// A basic implementation of redispatching events.
private void redispatchMouseEvent(MouseEvent e, boolean repaint) {
    Point glassPanePoint = e.getPoint();
    Container container = contentPane;
    Point containerPoint = SwingUtilities.convertPoint(glassPane,
            glassPanePoint, contentPane);
    if (containerPoint.y < 0) { // we're not in the content pane
    } else {
        // The mouse event is probably over the content pane.
        // Find out exactly which component it's over.
        Component component = SwingUtilities.getDeepestComponentAt(
                container, containerPoint.x, containerPoint.y);

        if ((component != null) && (component.equals(contentPane))) {
            System.out.println("contentPane");
            // Forward events over the check box.
            Point componentPoint = SwingUtilities.convertPoint(glassPane,
                    glassPanePoint, component);
            component.dispatchEvent(new MouseEvent(component, e.getID(), e
                            .getWhen(), e.getModifiers(), componentPoint.x,
                            componentPoint.y, e.getClickCount(), e
                                    .isPopupTrigger()));
        }
    }

    // Update the glass pane if requested.
    if (repaint) {
        glassPane.setPoint(glassPanePoint);
        glassPane.repaint();
    }
}

}

最佳答案

I can get it to redirect the mouseClick to the bottom panel but it wont draw the line. It just makes the redline disappear until you move the mouse again

不,它确实在画黑线。但这条线画在红线上方,使得红线消失,直到鼠标再次移动。我猜你正在寻找这样的东西:

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

class  DoublePanel extends JFrame
{
    JPanel mainPanel;
    int x1;
    public void prepareAndShowGUI()
    {
        setTitle("DoublePanel");
        mainPanel = new JPanel()
        {
            @Override
            public void paintComponent(Graphics g)
            {
                super.paintComponent(g);
                g.setColor(Color.BLACK);
                g.drawLine(x1,0,x1,this.getHeight());
            }
        };
        mainPanel.setBackground(new Color(50,160,55));
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(new upperPanel(this));
        setContentPane(mainPanel);
        setSize(500,600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);
    }
    public void setXValue(int x)
    {
        this.x1 = x;
        mainPanel.repaint();
    }
    class upperPanel extends JPanel
    {
        int x; int y;
        DoublePanel dp;
        upperPanel(DoublePanel d)
        {
            this.dp = d;
            setOpaque(false);
            addMouseMotionListener(new MouseAdapter()
            {
                @Override
                public void mouseMoved(MouseEvent evt)
                {
                    x = evt.getX();
                    y = evt.getY();
                    repaint();
                }
            });
            addMouseListener(new MouseAdapter()
            {
                @Override
                public void mouseClicked(MouseEvent evt)
                {
                    dp.setXValue(evt.getX());
                }
            });
        }
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.drawLine(x,0,x,this.getHeight());
        }
    }
    public static void main(String st[])
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            public void run()
            {
                DoublePanel dp = new DoublePanel();
                dp.prepareAndShowGUI();
            }
        });
    }
}

关于java - 单击 GlassPane 时在 GlassPane 后面的 JPanel 上绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15367232/

相关文章:

java - 属性 [region] 标有相互矛盾的注释 + Apache Beam 2.23

java - 将语句括在 try catch block 中; eclipse和netbeans的区别

java - Swing:GlassPane 防止鼠标指针改变

java - Swing : font color & strike color in JTextPane

java - javax.swing.* 中的默认 JButton

swing - 创建玻璃板

java - 我可以将玻璃面板分成两部分,并为每个面板添加一个单独的鼠标监听器吗?

java - 其余高级客户端 : Request timeout is not working

java - 当单元测试覆盖率低于多模块项目中预先配置的限制时,maven 构建失败

Java Swing 动画