我想阻止輸入到窗口,但仍然可以移動它。不使用模態對話框阻止Swing輸入
如果有一個模式對話框類型允許產生它移動的窗口,那麼我會很高興。
說我有一個窗口打開另一個窗口。這第二個窗口然後打開一個模式對話框,阻止輸入到其他兩個窗口(罰款),但也鎖定這兩個窗口到位(爲什麼 - Amigas沒有這樣做:)?)。
我的問題是,我可能需要在對話框中使用的第一個窗口在視覺上讀到的東西,但因爲第二個窗口被鎖定到位,覆蓋它,這可能是不可能的。
我想,我幾乎已經用玻璃窗解決了這個問題。我將下面的類設置爲窗口根窗格的玻璃窗格,然後當我想要解鎖窗口時,我想阻止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();
}
}
所以我用以下紀堯姆波萊的建議的版本是
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);
}
}
謝謝!
爲什麼你的應用程序無法運行將數據從第一個窗口複製到對話框? –
我需要做出(人類)決定,並根據我可以在第一個窗口中讀取的內容在對話框中輸入內容。第二個窗口在它的前面,如果它打開一個模式對話框,那麼我不能移動第二個窗口或第一個窗口,所以如果我需要的位在第二個窗口的後面,我需要關閉對話框,將第二個窗口窗口,剪切/粘貼,記下或記憶有問題的值,然後再次打開對話框。 – nsandersen
我明白了。將您需要的信息複製到第一個窗口(人類)決定的對話框中。爲什麼在一個窗口內有2個窗口而不是2個面板?有一個窗口的兩個面板可以解決重疊問題。 –