JPanel有时无法响应鼠标单击

时间:2019-05-14 09:59:09

标签: java swing mouselistener

我有一些自定义的JPanels用作按钮。这在90%的时间内效果很好,但是,有时GUI不会响应鼠标单击-mouseClicked事件不会触发,您必须再次单击(有时甚至多次单击)才能实际触发它。

此行为似乎是随机的,尽管我感觉在将框架移动到另一台显示器后更经常发生。

代码如下:

public class EatingMouse extends JFrame implements MouseListener {
    JPanel contentPane;
    int contentPanelWidth, contentPanelHeight;
    int mainTabMarginHeight, mainTabMarginWidth;
    int subTabMarginHeight, subTabMarginWidth;

    Color fontColor = Color.WHITE;
    Color tabBackgroundColor = Color.BLACK;
    Color tabBackgroundHighlightColor = Color.GRAY;
    Color tabBackgroundSelectedColor = Color.LIGHT_GRAY;

    TabPanel firstMainTab;
    TabPanel secondMainTab;
    ArrayList<TabPanel> firstSubTabs;
    ArrayList<TabPanel> secondSubTabs;
    ArrayList<TabPanel> currentSubTabs;

    int clickCounter;


    public EatingMouse() {
        super("Why do you eat mouse clicks?");

        JLayeredPane layeredPane = new JLayeredPane();
        firstMainTab = new TabPanel("First Tab", 18);
        firstMainTab.addMouseListener(this);
        layeredPane.add(firstMainTab, new Integer(100));
        secondMainTab = new TabPanel("Second Tab", 18);
        secondMainTab.addMouseListener(this);
        layeredPane.add(secondMainTab, new Integer(100));
        firstSubTabs = new ArrayList<>();
        secondSubTabs = new ArrayList<>();
        currentSubTabs = new ArrayList<>();

        TabPanel tp = new TabPanel("First First Subtab", 14);
        tp.addMouseListener(this);
        layeredPane.add(tp, new Integer(100));
        firstSubTabs.add(tp);
        tp = new TabPanel("Second First Subtab", 14);
        tp.addMouseListener(this);
        layeredPane.add(tp, new Integer(100));
        firstSubTabs.add(tp);

        tp = new TabPanel("First Second Subtab", 14);
        tp.addMouseListener(this);
        layeredPane.add(tp, new Integer(100));
        secondSubTabs.add(tp);
        tp = new TabPanel("Second Second Subtab", 14);
        tp.addMouseListener(this);
        layeredPane.add(tp, new Integer(100));
        secondSubTabs.add(tp);


        contentPane = new JPanel(new BorderLayout());
        setContentPane(contentPane);
        contentPane.add(layeredPane);

        mainTabMarginWidth = 40;
        mainTabMarginHeight = 8;
        subTabMarginWidth = 20;
        subTabMarginHeight = 10;
        selectTabs(0, 1);

        clickCounter = 0;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(800, 600));
        setVisible(true);
    }

    public void selectTabs(int mainTab, int subTab) {
        boolean hasChanged = false;

        if((mainTab == 0) && !firstMainTab.isSelected) {
            hasChanged = true;
            firstMainTab.setSelected(true);
            secondMainTab.setSelected(false);
            for(TabPanel tp : currentSubTabs) {
                tp.setSelected(false);
                tp.setVisible(false);
            }
            currentSubTabs = firstSubTabs;
            for(TabPanel tp : currentSubTabs) {
                tp.setVisible(true);
            }
            currentSubTabs.get(subTab).setSelected(true);
        }
        else if((mainTab == 1) && !secondMainTab.isSelected) {
            hasChanged = true;
            firstMainTab.setSelected(false);
            secondMainTab.setSelected(true);
            for(TabPanel tp : currentSubTabs) {
                tp.setSelected(false);
                tp.setVisible(false);
            }
            currentSubTabs = secondSubTabs;
            for(TabPanel tp : currentSubTabs) {
                tp.setVisible(true);
            }
            currentSubTabs.get(subTab).setSelected(true);
        }
        else if((mainTab == 0) && firstMainTab.isSelected) {
            hasChanged = true;
            for(TabPanel tp : currentSubTabs) {
                if(tp != currentSubTabs.get(subTab)) { tp.setSelected(false); }
                else { tp.setSelected(true); }
            }
        }
        else if((mainTab == 1) && secondMainTab.isSelected) {
            hasChanged = true;
            for(TabPanel tp : currentSubTabs) {
                if(tp != currentSubTabs.get(subTab)) { tp.setSelected(false); }
                else { tp.setSelected(true); }
            }
        }
        if(hasChanged) {
            revalidate();
            repaint();
        }
    }


    @Override
    public void paint(Graphics graphics) {
        super.paint(graphics);
        contentPanelWidth = getContentPane().getWidth();
        contentPanelHeight = getContentPane().getHeight();

        int xOffset = 100;
        int yOffset = 100;
        FontMetrics mainTabMetrics = graphics.getFontMetrics(firstMainTab.label.getFont());
        firstMainTab.setBounds(xOffset, yOffset, (mainTabMetrics.stringWidth(firstMainTab.text) + mainTabMarginWidth), (mainTabMetrics.getHeight() + mainTabMarginHeight));
        xOffset += firstMainTab.getBounds().width;
        secondMainTab.setBounds(xOffset, yOffset, (mainTabMetrics.stringWidth(secondMainTab.text) + mainTabMarginWidth), (mainTabMetrics.getHeight() + mainTabMarginHeight));
        FontMetrics subTabMetrics = graphics.getFontMetrics(currentSubTabs.get(0).label.getFont());
        xOffset  = 100;
        yOffset += firstMainTab.getBounds().height;
        for(TabPanel tp : currentSubTabs) {
            tp.setBounds(xOffset, yOffset, (subTabMetrics.stringWidth(tp.text) + subTabMarginWidth), (subTabMetrics.getHeight() + subTabMarginHeight));
            tp.revalidate();
            tp.repaint();
            xOffset += tp.getBounds().width;
        }
    }


    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("click " + clickCounter++);
        Object source = e.getSource();
        if(source == firstMainTab && !firstMainTab.isSelected) {
            secondMainTab.setSelected(false);
            if(currentSubTabs.get(1).isSelected) { selectTabs(0, 1); }
            else { selectTabs(0, 0); }
        }
        else if(source == secondMainTab && !secondMainTab.isSelected) {
            if(currentSubTabs.get(1).isSelected) { selectTabs(1, 1); }
            else { selectTabs(1, 0); }
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        Object source = e.getSource();
        if(source == firstMainTab && !firstMainTab.isSelected) { firstMainTab.setBackground(tabBackgroundHighlightColor); }
        else if(source == secondMainTab && !secondMainTab.isSelected) { secondMainTab.setBackground(tabBackgroundHighlightColor); }
        else if(currentSubTabs.contains(source) && !((TabPanel) source).isSelected) {
            ((TabPanel)source).setBackground(tabBackgroundHighlightColor);
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        Object source = e.getSource();
        if(source == firstMainTab && !firstMainTab.isSelected) { firstMainTab.setBackground(tabBackgroundColor); }
        else if(source == secondMainTab && !secondMainTab.isSelected) { secondMainTab.setBackground(tabBackgroundColor); }
        else if(currentSubTabs.contains(source) && !((TabPanel) source).isSelected) {
            ((TabPanel)source).setBackground(tabBackgroundColor);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    public class TabPanel extends JPanel {
        JLabel label;
        String text;
        boolean isSelected;

        public TabPanel(String labelText, int fontSize) {
            super();
            text = labelText;
            isSelected = false;
            setLayout(new GridBagLayout());
            setBackground(tabBackgroundColor);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.PAGE_START;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weighty = 0.1;
            gbc.weightx = 0.1;
            gbc.insets = new Insets(0,0,0,0);
            label = new JLabel("<html><div style=\"text-align:center\"> " + text + "</div></html>", SwingConstants.CENTER);
            label.setAlignmentX(JLabel.CENTER_ALIGNMENT);
            label.setForeground(fontColor);
            label.setFont(new Font("Arial", Font.BOLD, fontSize));
            add(label, gbc);
        }


        public void setSelected(boolean selected) {
            isSelected = selected;
            if(selected) { setBackground(tabBackgroundSelectedColor); }
            else { setBackground(tabBackgroundColor); }
        }
        public boolean isSelected() { return isSelected; }

        @Override
        public String toString() {
            return text + " - " + label.getFont().getSize();
        }
    }

    public static void main(String[] args) {
        new EatingMouse();
    }
}

请注意,我选择JPanels作为按钮是因为我以后想大量定制它们,而我并没有扩展JButton

感谢您的阅读时间,当然,对于导致这种情况发生的原因以及我可以做些什么来改进此代码,我将不胜感激。

0 个答案:

没有答案