Swing, glassPanel

0

W programie korzystam z "szyby" - obiektu zwracanego przez getGlassPane(). Wysunięta szyba zasłania JFrame. Kliknięcie w przycisk "Szyba" wysuwa szybę, PPM chowa szybę. Jak szyba jest wysunięta, to LPM rysuje na niej czerwone koło. Program działa dobrze, z jednym wyjątkiem Źle działa pierwszy LPM po pierwszym wysunięciu szyby. Co jest źle w programie?

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

public class Szyba extends JFrame implements ActionListener
{
    private Component szyba = null;
    private boolean jestSzyba = false;
    //------------------------
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new Szyba().createAndShowGUI();
            }
        });     
    }
    //------------------------
    private void createAndShowGUI()
    {
        setTitle("Nie ma szyby");
        szyba = getGlassPane();

        szyba.addMouseListener(zakraplacz);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600,600);
        setLayout(new FlowLayout(FlowLayout.CENTER));
        JButton b = new JButton("Szyba");
        b.addActionListener(this);
        add(b);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    //------------------------
    public void actionPerformed(ActionEvent ae)
    {
        szyba.setVisible(true);
        setTitle("Szyba wszystko zasłoniła");       
    }
    //------------------------
    MouseListener zakraplacz = new MouseAdapter()
    {
        public void mousePressed(MouseEvent me)
        {
            Graphics g = szyba.getGraphics();
            g.setColor(Color.RED);
            g.fillOval(me.getX()-25,me.getY()-25,50,50);
            jestSzyba = true;
            System.out.println("1");            
        }
        //--------------------
        public void mouseReleased(MouseEvent me)
        {
            System.out.println("2");
            
            if(me.isPopupTrigger() && jestSzyba)
            {
                System.out.println("3");            
                szyba.setVisible(false);
                jestSzyba = false;
                setTitle("Nie ma szyby");
                repaint();
            }
        }
    };
}
0

U mnie działa zupełnie inaczej niż u Ciebie ;) Od początku można rysować po szybie zarówno LPM jak i PPM (działa od pierwszego kliknięcia), natomiast nie działa chowanie szyby. Dzieje się tak ponieważ isPopupTrigger() jest zależne od platformy, jak dla mnie powinno jednak być getButton()

0

Zmieniłem warunek

if(me.isPopupTrigger() && jestSzyba)

na

if(me.getButton() > MouseEvent.BUTTON1 && jestSzyba)

Pierwsze LPM po pierwszym wysunięciu szyby nadal nie działa. Dokładniej, pseudo-debugging pokazuje, że metody mousePressed i mouse Released są wykonywane, tylko czerwonego kółka nie widać.

0

Nadal nie wiem dlaczego poprzednie rozwiązanie nie działa całkiem dobrze. Napisałem trochę inne - z malowaniem kółek w metodzie paint szyby - i działa bez zarzutu.

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

public class SzybaDemo extends JFrame implements ActionListener
{
    private Component szyba = null;
    private ArrayList<Point> points = new ArrayList<Point>();
    //------------------------
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new SzybaDemo().createAndShowGUI();
            }
        });     
    }
    //------------------------
    private void createAndShowGUI()
    {
        setTitle("Nie ma szyby");
        szyba = new Szyba();
        setGlassPane(szyba);
        szyba.addMouseListener(zakraplacz);     
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600,600);
        setLayout(new FlowLayout(FlowLayout.CENTER));
        JButton b = new JButton("Szyba");
        b.addActionListener(this);
        add(b);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    //------------------------
    public void actionPerformed(ActionEvent ae)
    {   
        szyba.setVisible(true);
        setTitle("Szyba wszystko zasłoniła");   
    }
    //------------------------
    MouseListener zakraplacz = new MouseAdapter()
    {
        public void mousePressed(MouseEvent me)
        {
            if(me.getButton() == MouseEvent.BUTTON1)
            {
                points.add(new Point(me.getX()-25,me.getY()-25));
                repaint();
            }
        }
        //--------------------
        public void mouseReleased(MouseEvent me)
        {
            if(me.getButton() > MouseEvent.BUTTON1)
            {
                szyba.setVisible(false);
                setTitle("Nie ma szyby");
                repaint();
            }
        }
    };
    //------------------------
    class Szyba extends JComponent
    {
        public void paintComponent(Graphics g)
        {
            g.setColor(Color.RED);
            for(Point p: points)
            {
                g.fillOval(p.x-25,p.y-25,50,50);
            }
        }
    }   
}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.