У меня есть несколько пользовательских JPanels, которые используются в качестве кнопок.Это работает хорошо в 90% случаев, однако, иногда графический интерфейс не реагирует на щелчок мыши - событие 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
.
Спасибо, что уделили время и прочитали это иКонечно, я был бы признателен за любые указания о том, почему это происходит, и что я могу сделать, чтобы улучшить этот код.