Swing: Как я мог бы относиться к JInternalFrame одинаково к другим компонентам внутри контейнера?
Исходная информация:
Я реализую визуальный редактор диаграмм, который состоит из
- различные сложные элементы (изменяемого размера, с заголовком, подэлементами) и
- различные простые элементы (не изменяемого размера, без заголовка, без подэлементов).
Все элементы перетаскиваемы.
Я использую JInternalFrame (для сложных элементов) вместе с JPanel (для простых элементов) для представления элементов схематического представления. Существует контейнер (JDesktopPane или JLayeredPane), который содержит все эти элементы.
У меня есть несколько проблем с этой концепцией:
Случай 1 - контейнер представляет собой JDesktopPane:
- JInternalFrames всегда выше других элементов.
- Нажатие на другие элементы не "деактивирует" ранее активную JInternalFrame
Случай 2 - Контейнер является JLayeredPane:
- После нажатия на некоторые элементы внутри JInternalFrame, он остается "активированным" навсегда.
Случай 3 - JInternalFrame используется для всего, но без оформления для простых элементов:
- Моя пользовательская граница (которая необходима, когда я вручную удаляю строку заголовка JInternalFrame) каждый раз заменяется текущей границей LAF после активации / деактивации JInternalFrame.
В любом случае, я не понимаю всех концепций, стоящих за активацией JInternalFrames. Если бы я мог сделать JInternalFrame вообще не активируемым, я мог бы выбрать вариант 2, любой был бы счастлив.
Пожалуйста, посоветуйте мне, каким было бы простое и понятное решение данных проблем.
ПРИМЕЧАНИЕ. Выбор компонентов и активация JInternalFrame кажутся разными вещами.
2 ответа
Я мог бы неправильно понять вашу проблему. Вы пытались взглянуть на метод setSelected() JIF? Кажется, есть поддержка переопределения метода и вето для событий активации.
Редактировать: Может быть, у нас есть некоторые терминологические недоразумения, как заявляет Javadoc:
/**
* Selects or deselects the internal frame
* if it's showing.
* A <code>JInternalFrame</code> normally draws its title bar
* differently if it is
* the selected frame, which indicates to the user that this
* internal frame has the focus.
* When this method changes the state of the internal frame
* from deselected to selected, it fires an
* <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
* If the change is from selected to deselected,
* an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
* is fired.
*
* @param selected a boolean, where <code>true</code> means this internal frame
* should become selected (currently active)
* and <code>false</code> means it should become deselected
* @exception PropertyVetoException when the attempt to set the
* property is vetoed by the <code>JInternalFrame</code>
*
* @see #isShowing
* @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
* @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
*
* @beaninfo
* constrained: true
* bound: true
* description: Indicates whether this internal frame is currently
* the active frame.
*/
Изменить 2: Теперь я перечитал ваш второй случай. Я бы сказал, что каждый JIF имеет свою отдельную среду фокусировки / выбора. Вы можете создать метод, который пересекает все ваши JIF-файлы и отменяет выбор в нем всего, кроме того компонента, который вы хотели выбрать.
Попробуйте при инициализации JInternalFrame=
new JInternalFrame(<your args>) {
protected void fireInternalFrameEvent(int id){
if (id != InternalFrameEvent.INTERNAL_FRAME_ACTIVATED) {
super.fireInternalFrameEvent(id);
}
}
};
обратите внимание, что глядя на код в JInternalFrame.setSelected(boolean)
, setSelected и 'actvation' связаны друг с другом в процессе, при этом setSelected запускает не только изменения свойств для Selection, но и вызовы fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED)
также.