ウィンドウへの入力をブロックしたいが、それでも移動できるようにしたい。
それを生成したウィンドウを移動できるモーダル ダイアログ タイプがあれば、私は満足です。
別のウィンドウを開くウィンドウがあるとします。次に、この 2 番目のウィンドウがモーダル ダイアログを開き、他の 2 つのウィンドウへの入力をブロックします (問題ありません) が、これら 2 つのウィンドウを所定の位置にロックします (なぜ - Amigas はこれを行わなかったのですか :) ?)。
私の問題は、ダイアログで使用するために最初のウィンドウで何かを視覚的に読み取る必要がある場合があることですが、2番目のウィンドウが所定の位置にロックされており、それを覆っているため、これは不可能な場合があります。
私はこれをガラス板でほぼ解決したと思います。以下のクラスをウィンドウのルート ペインのガラス ペインに設定し、ブロックするときは setVisible(true) を呼び出し、ウィンドウのロックを解除するときは setVisible(false) を呼び出します。ロックすると、ウィンドウが灰色になり、これを示します。
ウィンドウを閉じる以外はマウス入力がブロックされますが、今のところは問題ありません。問題は、ブロックされたウィンドウのコンポーネントをタブで移動でき、編集可能なウィンドウに到達した場合は、キーボードで編集できることです。空の KeyListener。
ガラス ペインの背後にあるコンポーネントがフォーカスされないようにする簡単な方法はありますか?
「InputSink」クラス自体で実行できることを願っています。
独自の利己的なフォーカス トラバーサル ポリシーを追加し、フォーカスが表示されたときにフォーカスを要求しようとしましたが、これは効果がありません。
また、FocusListener が追加された場所で見つかった例を試してみました。その focusLost メソッドは、ガラス ペインが表示されている場合にフォーカスを要求しますが、ウィンドウが常に前面にあるため、やり過ぎです。
これらの両極端の間の解決策を知っている人はいますか? これは私が持っているものです:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import javax.swing.JPanel;
public class InputSink extends JPanel {
public InputSink() {
this(0.2f); //Default opacity.
}
public InputSink(float alpha) {
setOpaque(false);
setBackground(new Color(0, 0, 0, alpha)); //Just store it here.
addMouseListener(new MouseAdapter() {});
addKeyListener(new KeyAdapter() {});
setFocusTraversalPolicy(new FocusTraversalPolicy() {
@Override
public Component getLastComponent(Container aContainer) {
return InputSink.this;
}
@Override
public Component getFirstComponent(Container aContainer) {
return InputSink.this;
}
@Override
public Component getDefaultComponent(Container aContainer) {
return InputSink.this;
}
@Override
public Component getComponentBefore(Container aContainer, Component aComponent) {
return InputSink.this;
}
@Override
public Component getComponentAfter(Container aContainer, Component aComponent) {
return InputSink.this;
}
});
}
public void paintComponent(final Graphics gfx) { //Handle grey-out.
gfx.setColor(getBackground());
Rectangle rect = gfx.getClipBounds();
gfx.fillRect(rect.x, rect.y, rect.width, rect.height);
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible)
requestFocus();
}
}
したがって、Guillaume Polet の提案に従って使用したバージョンは
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class InputSink extends JPanel {
KeyEventDispatcher blockingDispatcher = new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
return InputSink.this == ((JFrame) SwingUtilities.getWindowAncestor((Component) e.getSource())).getGlassPane(); //Consume!
}
};
public InputSink) {
this(0.2f); //Default opacity.
}
public InputSinkfloat alpha) {
setOpaque(false);
setBackground(new Color(0, 0, 0, alpha)); //Just store it here.
addMouseListener(new MouseAdapter() {});
addKeyListener(new KeyAdapter() {});
}
public void paintComponent(final Graphics gfx) { //Handle grey-out.
gfx.setColor(getBackground());
Rectangle rect = gfx.getClipBounds();
gfx.fillRect(rect.x, rect.y, rect.width, rect.height);
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible)
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(blockingDispatcher);
else
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(blockingDispatcher);
}
}
ありがとうございました!