Рисование на JPanel за GlassPane при нажатии на GlassPane

Итак, я просмотрел несколько форумов и Google и не смог найти ответ на мою конкретную проблему. Таким образом, у меня есть две панели, наложенные друг на друга, а одна сверху - это стеклянная панель. Когда вы перетаскиваете мышь вокруг стеклянной панели, она рисует вертикальную красную линию на курсоре, что работает, но когда я нажимаю на стеклянную панель, я хочу, чтобы она рисовала черную линию в позиции курсора на панели под стеклянной панелью. Я могу заставить его перенаправить mouseClick на нижнюю панель, но он не будет рисовать линию. Это просто заставляет красную линию исчезать, пока вы снова не переместите мышь. Кроме того, если я установил стеклянную панель невидимой и щелкнул на нижней панели, линия будет нарисована, чтобы код рисования работал просто отлично. Заранее спасибо.

Основной класс

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

Класс стеклопакетов

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();
    }
}

}

2 ответа

Решение

Я могу заставить его перенаправить mouseClick на нижнюю панель, но он не будет рисовать линию. Это просто заставляет красную линию исчезать, пока вы снова не переместите мышь

Нет, это действительно черная линия. Но линия рисуется над красной линией, которая заставляет красную линию исчезать, пока мышь не будет снова перемещена. Думаю, вы ищете что-то вроде этого:

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();
            }
        });
    }
}

Вам нужно вызвать нижнюю панель repaint(),

Другие вопросы по тегам