Как прослушать "видимое" свойство Window в Swing/AWT?
Существует свойство bean-компонента "visible", которое представлено getter isVisible()
и сеттер setVisible()
в классе Window
,
Как выслушать это значение?
Я хотел бы реализовать популярное "представление" меню с флажком с библиотекой привязки. К сожалению, я не вижу, как связать "видимое" свойство окна. Даже я не могу написать переводчик, потому что не вижу никакого предопределенного способа прослушивания этого свойства:
package tests;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Try_Swing2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame2 = new JFrame();
frame2.addWindowStateListener(new WindowStateListener() {
@Override
public void windowStateChanged(WindowEvent e) {
System.out.println("windowState.newState = " + e.getNewState());
}
});
frame2.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("windowOpened");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("windowIconified");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("windowDeiconified");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing");
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed");
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated");
}
});
frame2.addPropertyChangeListener("visible", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("visible = " + evt.getNewValue());
}
});
frame2.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame2.setTitle("This window is controlled by another window");
frame2.setSize(800, 600);
frame2.setLocationRelativeTo(null);
frame2.setVisible(true);
AbstractAction toggleAction = new AbstractAction("Toggle another window visibility") {
@Override
public void actionPerformed(ActionEvent e) {
frame2.setVisible( !frame2.isVisible() );
}
};
JButton toggleButton = new JButton(toggleAction);
JFrame frame1 = new JFrame();
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setTitle("This windows controls");
frame1.setLayout(new FlowLayout());
frame1.add(toggleButton);
frame1.pack();
frame1.setLocation(0, 0);
frame1.setVisible(true);
}
});
}
}
3 ответа
visible
собственность на самом деле не связана с WindowsListener
, но к ComponentListener
потому что это принадлежит Component
класс, а не Window
учебный класс.
Для того, чтобы прослушать изменения в visible
собственность, componentShown(ComponentEvent e)
метод ComponentListener
должен быть реализован. Всегда легче унаследовать от адаптеров, поэтому в этом случае:
frame2.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(WindowEvent e) {
System.out.println("Component is Visible");
}
}
Адаптеры имеют пустые реализации слушателей, например ComponentAdapter
класс, который имеет пустые реализации методов в ComponentListener
, а также WindowAdapter
от WindowListener
,
Для получения дополнительной информации см. Адаптер компонента, Слушатель компонента и Как написать компонентный слушатель и
Методическая документация для Component.addPropertyChangeListener
четко перечисляет свойства, которые наблюдаются. Состояние видимости не указано. И как JFrame
(или один из его суперклассов до Component
) не добавляет никакого нового поведения, вы не можете наблюдать изменения в состоянии видимости на JFrame
,
Тем не менее, вы могли бы подкласс JFrame
с переопределением setVisible
метод. В этой новой реализации вы можете запустить такое изменение свойства:
public class VisibleAwareFrame extends JFrame {
public void setVisible(boolean b) {
boolean visible = isVisible();
super.setVisible(b);
firePropertyChange("visible", visible, b);
}
}
Попробуйте Global AWT Event Listener
long eventMask = AWTEvent.COMPONENT_EVENT_MASK;
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
public void eventDispatched(AWTEvent e) {
String paramString = e.paramString();
System.out.println(paramString);
}
}, eventMask);
Вот некоторые выводы
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_HIDDEN
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_RESIZED (4,23 492x473)
COMPONENT_MOVED (4,23 492x473)
COMPONENT_RESIZED (0,0 492x473)
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_MOVED (0,0 500x500)
COMPONENT_SHOWN
COMPONENT_MOVED (0,0 500x500)
COMPONENT_MOVED (0,0 500x500)
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_HIDDEN
COMPONENT_RESIZED (0,0 494x475)
COMPONENT_MOVED (0,0 494x475)
Вы можете поставить проверки на источник, а также тип события на paramString
, Проверить COMPONENT_HIDDEN
а также COMPONENT_SHOWN
событие и на основе изменения события или установить visible
имущество. Это может помочь вам.