#java #swing
#java #качать
Вопрос:
Я хочу показать небольшое всплывающее меню, когда вы щелкаете правой кнопкой мыши по вкладке, теперь это работает нормально, но при щелчке правой кнопкой мыши также выбирается та вкладка, которая является нежелательной.
Итак, моя идея состояла в том, чтобы создать новый класс, расширить JTabbedPane и перекодировать эти события мыши. Проблема в том, что я понятия не имею, с чего начать, я просматривал его исходный код, но я не могу найти, какая часть обрабатывает MouseEvents.
Tabs.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me) {
if(me.getButton()==3){
int tabNr = ((TabbedPaneUI)Tabs.getUI()).tabForCoordinate(Tabs, me.getX(), me.getY());
Component clickedTab = EventsConfig.window.MainTabs.getComponentAt(tabNr);
newMenu(clickedTab, me.getX(), me.getY());
}
}
});
Комментарии:
1. пожалуйста, изучите соглашения об именовании Java и придерживайтесь их
2. для меня звучит как ошибка: обычно popupTrigger (== щелчок правой кнопкой мыши) должен не выбирать. Не могу сказать, каково собственное поведение (в win), Eclipse выбирает и показывает, Firefox нет. Вы нашли что-нибудь в параде ошибок?
3. Хм, может быть, это потому, что я на Linux atm?
4. вероятно, было слишком неясно 🙂 Я действительно могу воспроизвести поведение в win. И я считаю это ошибкой удобства использования в любой ОС
Ответ №1:
Осторожно: впереди грязный взлом! Единственная причина, по которой я рекомендую это, заключается в том, что я считаю поведение (выбор при нажатии правой кнопкой мыши) ошибкой в обработчике BasicTabbedPaneUI.
Основная идея состоит в том, чтобы захватить прослушиватель, установленный пользовательским интерфейсом, удалить его, преобразовать в пользовательский прослушиватель, который делегирует все, кроме нажатия правой кнопки мыши, оригиналу, и добавить это на панель:
private void installMouseListenerWrapper(JComponent tabbedPane) {
MouseListener handler = findUIMouseListener(tabbedPane);
tabbedPane.removeMouseListener(handler);
tabbedPane.addMouseListener(new MouseListenerWrapper(handler));
}
private MouseListener findUIMouseListener(JComponent tabbedPane) {
MouseListener[] listeners = tabbedPane.getMouseListeners();
for (MouseListener l : listeners) {
if (l.getClass().getName().contains("$Handler")) {
return l;
}
}
return null;
}
public static class MouseListenerWrapper implements MouseListener {
private MouseListener delegate;
public MouseListenerWrapper(MouseListener delegate) {
this.delegate = delegate;
}
@Override
public void mouseClicked(MouseEvent e) {
delegate.mouseClicked(e);
}
@Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) return;
delegate.mousePressed(e);
}
@Override
public void mouseReleased(MouseEvent e) {
delegate.mouseReleased(e);
}
@Override
public void mouseEntered(MouseEvent e) {
delegate.mouseEntered(e);
}
@Override
public void mouseExited(MouseEvent e) {
delegate.mouseExited(e);
}
}
Комментарии:
1. Спасибо, перезапись события — это именно то, что я хотел сделать.
Ответ №2:
затем вы должны добавить JPopupMenu (или JToolTip при наведении курсора мыши) в JTabbedPane
Комментарии:
1. Нет, я хочу запретить переключение на новую вкладку при нажатии на нее правой кнопкой мыши. Само меню не представляет проблем
Ответ №3:
Возможный обходной путь — установить пользовательский компонент вкладки для каждой вкладки — см. JTabbedPane#setTabComponentAt(…). Добавьте обработчик мыши в свой пользовательский компонент вкладки и повторно распределите события щелчка левой кнопкой мыши по панели вкладок, как описано вhttp://www.jyloo.com/news/?pubId=1315817317000.
Пользовательский компонент вкладки может быть простым JLabel (используется для заголовка вкладки) или контейнером для нескольких компонентов. В зависимости от ваших требований вы можете, например, добавить кнопку со стрелкой, которая откроет всплывающее меню, щелкнув левой кнопкой мыши соответствующую кнопку.
Ответ №4:
Эта статья поможет удалить ненужный выбор вкладки при нажатии правой кнопки мыши. Остановить событие щелчка правой кнопкой мыши на JTabbedPane
Мне понравилось добавить больше об удалении прослушивателей мыши. Попробуйте переопределить метод, а не удалять его. Это лучше для будущих обновлений кода.
Проблема в том, что у BasicTabbedPaneUI есть внутренний класс, называемый Handler. Этот класс обработчика переопределяет прослушиватель мыши. Чтобы остановить выбор вкладки, щелкните правой кнопкой мыши и отобразится всплывающее меню; нам нужно переопределить этот метод в BasicTabbedPaneUI,
protected MouseListener createMouseListener() {
return getHandler();
}
Чтобы получить лучший внешний вид, мы должны переопределить класс SynthTabbedPaneUI.
SynthTabbedPaneUI является расширением BasicTabbedPaneUI.
Итак, наш внутренний класс выглядит следующим образом,
private class SynthTabbedPaneUIWrapper extends SynthTabbedPaneUI
{
private MouseAdapter menuAdapter;
private MouseAdapter getMenuAdapter()
{
if (menuAdapter == null)
{
menuAdapter =
new MouseAdapter()
{
@Override
public void mouseReleased(final MouseEvent e)
{
//implement to stop right click tab selection
//implement to show pop up menu
}
};
}
}
@Override
protected MouseListener createMouseListener()
{
return getMenuAdapter();
}
}
После этого мы можем установить наш пользовательский объект пользовательского интерфейса в TabbedPane.
tabbedPane.setUI(new SynthTabbedPaneUIWrapper());