У меня есть приложение Java, основной интерфейс которого состоит из двух JFrames: клиентской области и инструмента палитра, которая должна всегда отображаться над клиентской областью. Для достижения этой цели палитра инструментов имеет значение alwaysOnTop (true), которая отлично работает во всех случаях, кроме одного эксклюзивного для Windows: когда вызывается модальный JDialog, щелкая по области клиента и/или палитре (оба из которых заблокирован) заставляет палитру отставать от клиентской области. Когда модальный диалог закрыт, палитра снова появляется, но ее «всегда на вершине» потеряно: щелчок по области клиента затеняет палитру.Java (только для Windows): alwaysOnTop JFrame падает на дно z-порядка, когда модальный диалог выскочил и заблокирован JFrames нажата
Вот минимальная, один исходный файл демонстрация:
// FloatingPaletteExample.java
// 4/11/2012 sorghumking
//
// Demo of a Windows-only issue that has me puzzled: When a modal dialog is
// opened, and user clicks in blocked JFrames (sequence depends on ownership of
// modal dialog: follow the instructions in modal dialog to see the problem
// behavior), the floating tool palette loses its "always on top-ness".
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class FloatingPaletteExample {
public static void main(String [] args) {
final JFrame clientAreaJFrame = new JFrame("client JFrame");
clientAreaJFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowevent) {
clientAreaJFrame.dispose();
System.exit(0);
}
});
clientAreaJFrame.setSize(800, 600);
clientAreaJFrame.setVisible(true);
final JFrame floatingToolFrame = new JFrame("tool JFrame");
final JCheckBox ownerCheckbox = new JCheckBox("Owned by tool frame (otherwise, null owner)");
JButton popModalButton = new JButton("Open Modal Dialog");
popModalButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFrame owner = ownerCheckbox.isSelected() ? floatingToolFrame : null;
JDialog modalDialog = new JDialog(owner, "Modal Dialog", true);
final String labelText = ownerCheckbox.isSelected() ? "Click anywhere in the client JFrame." :
"Click the tool JFrame, then anywhere in the client JFrame";
modalDialog.add(new JLabel(labelText));
modalDialog.pack();
modalDialog.setLocation(100, 100);
modalDialog.setVisible(true);
}
});
floatingToolFrame.add(popModalButton, BorderLayout.NORTH);
floatingToolFrame.add(ownerCheckbox, BorderLayout.SOUTH);
floatingToolFrame.pack();
floatingToolFrame.setLocationRelativeTo(clientAreaJFrame);
floatingToolFrame.setAlwaysOnTop(true);
floatingToolFrame.setVisible(true);
}
}
Я попытался floatingToolFrame.setFocusableWindowState (ложь), который в соответствии с the doc является «стандартным механизмом для приложения, чтобы определить, в AWT окна, в котором будет использоваться как плавающая палитра или панель инструментов », но поведение остается неизменным.
Я нашел обходное решение: вызовите floatToolFrame.setAlwaysOnTop (false) перед появлением модального диалога и вызовите функцию плавающегоToolFrame.setAlwaysOnTop (true) после ее закрытия. Однако, кажется, смешно требовать эту упаковку в любое время, когда открывается модальный диалог. Да, я мог бы подклассифицировать JDialog и вывести все мои диалоги из указанного подкласса, чтобы сделать это за кулисами, но опять же, почему это необходимо?
Любые идеи о том, как разрешить это без обходного пути? Является ли мой подход к созданию палитры всегда на вершине полностью ошибочным? (Еще одно замечание: это, по-видимому, противоположно описанной здесь проблеме: Java 6, JFrame stuck alwaysontop).
Любые мысли были бы высоко оценены!