Справочная информация
Я хотел бы создать окно инструментов / палитр (также называемое "плавающим" окном) в Swing с Java Version 1.6.0_26 .Я думал, что JWindow - лучший выбор, а также документация Swing указывает на использование JWindow для таких целей (плавающее окно, которое имеет рамку владельца, не имеет декорации и не имеет входа в панель задач Windows).
MyСодержимое плавающего окна инструментов состоит из нескольких других компонентов, таких как JButtons, а также JTextFields.
Проблема
Когда я щелкаю в плавающем окне инструментов, окно владельца (JFrame, мое "главное окно приложения)иногда мерцает.«Мерцание» выглядит так, как будто окно владельца теряет фокус на несколько миллисекунд, а затем возвращает фокус обратно, что приводит к очень быстрому отключению / включению окна (обратите внимание, что событие окна не запускается, например, потеря фокуса или окно-деактивирован).
Я проверил это в Windows 7 64-битной и Windows XP.
Видео и пример кода
Чтобы прояснить проблему (это немного сложнообъясните), я снял видео, там вы можете увидеть «мерцание» окна владельца, когда я несколько раз нажимаю на плавающее окно инструмента:
Я также собрал простой пример кода для воспроизведения проблемы (этот код используется в видео):
import java.awt.*;
import javax.swing.*;
public class JWindowFlickerExample
{
public JWindowFlickerExample()
{
// I know swing code should be executed on the EDT,
// just wanted to keep it simple
// Create and show the "main application window"
JFrame frame = new JFrame( getClass().getSimpleName() );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setSize( 640, 480 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
// Create and show the "floating tool window"
MyFloatingToolWindow testWindow = new MyFloatingToolWindow( frame );
testWindow.setLocation( 400, 400 );
testWindow.setVisible( true );
}
public static void main( String[] args )
{
new JWindowFlickerExample();
}
@SuppressWarnings( "serial" )
private class MyFloatingToolWindow extends JWindow
{
public MyFloatingToolWindow( Window hostWindow )
{
super( hostWindow );
// setFocusableWindowState( false );
setSize( 300, 400 );
setLayout( null );
getContentPane().setBackground( Color.LIGHT_GRAY );
JTextField textField = new JTextField();
textField.setLocation( 50, 50 );
textField.setSize( 70, 30 );
add( textField );
}
}
}
Прогресс до сих пор
Я также попытался установить для «Window.setFocusableWindowState» значение false для плавающего окна инструмента.Если оно ложно, мерцания нет, проблема исчезла.JavaDoc для этого метода указывает:
Установка состояния фокусировки окна на false - это стандартный механизм для приложения, чтобы идентифицировать AWT окно, которое будет использоваться в качестве плавающей палитры или панели инструментов, итаким образом, должно быть окно без фокуса. "
Но тогда я не могу использовать JTextField в плавающем окне инструмента, конечно, потому что я не могу сфокусировать его (возможно, текстовое поле вплавающее окно инструмента необычно, но в моем случае это необходимо).
Я думаю, что эффект "мерцания" как-то связан с управлением фокусом ... на долю секунды плавающий инструментокно получает фокус, убирая его из окна владельца, а затем обратно. Но я не уверен, как примечание стороны: если текстовое поле в плавающем окне инструмента имеет фокус, окно владельца остается включенным (который являетсяправильное поведение).
Я надеюсь, что есть простое решение, так что я могу остаться с JWindow в качестве моего плавающего окна инструмента и с текстовыми полями как оно 's содержание - потому что, кроме описанной проблемы с «мерцанием», все прекрасно работает.
Я очень ценю любую помощь, большое спасибо!