私はJava
GUI操作を試しており、ユーザー入力を収集するために要求に応じて表示される、jPanel
想像力で呼び出されたDLogから作成されたカスタムダイアログを持っています。これは正常に機能しますが、もちろん私のダイアログはモーダルではありません。これにより、ダイアログが開いている間、残りのコントロールが表示され、ユーザーがアクセスできるようになります。全然ダメ!
これを克服するために、ウィンドウに合わせてサイズが変更されますが、必要になるまで表示されないDLogCoverjPanel
という名前の別のものがあります。カスタム ダイアログが表示されると、ウィンドウのスクリーンショットが取得され、DLogCoverのラベルに画像として表示されます。これは、カスタム ダイアログの下に表示されますが、他のすべてのものの上に表示されます (ので- カスタム ダイアログは に表示されます)。これは計画どおりに機能しますが、2 つの問題点がありますが、ご協力いただければ幸いです。MODAL_LAYER
jLayeredPanel
POPUP_LAYER
まず、スクリーンショットにはもちろんタイトルバーとウィンドウの左端が含まれています。私はこれを考慮して、現在私にとって適切な任意の数値を使用していますが、もちろん、システムのルック アンド フィールを使用しているため、これは OS ごとに異なり、これらのサイズは正しくない可能性があります。
質問: スクリーンショットがウィンドウの内部コンテンツのみであることを確認する方法はありますか (または、OS に関係なく、ウィンドウのタイトル バーと境界線の正しいサイズを常に取得する方法はありますか)?
第二に、私のスクリーンショットは問題なく動作しますが、それは単なるウィンドウの画像です。実際にコントロールを覆っているものがあるように見せるために、少し色あせたりぼかしたりしたいと考えています。
質問: 画像を操作してこのような外観にする方法はありますか?
画像をキャプチャして表示するために使用しているコードは次のとおりです(カスタムダイアログを表示する前に):
DLOGCover.setVisible(true);
Point pos = this.getLocationOnScreen();
Dimension dim = this.getSize();
//Arbitrary sizes! These need to be discovered and set correctly!
int xLoc = pos.x +1 ;
int yLoc = pos.y + 11;
try
{
Robot robot = new Robot();
Rectangle captureSize = new Rectangle(xLoc, yLoc, dim.width, dim.height);
BufferedImage bImage = robot.createScreenCapture(captureSize);
Image imgwork = (Image)bImage;
ImageIcon labelimg = new ImageIcon(imgwork);
imageLabel.setIcon(labelimg);
}
catch(AWTException e)
{
System.err.println("Ouch!");
}
//... show the custom dialog
以前と同様に、私がこの方法で物事を行っている理由は、私が学ぼうとしてJava
実験しているためであり、現在はこれを使用しています!
あなたが与えることができるどんな助けにも感謝します.もちろん、同じことを達成するための代替方法についての提案も受け付けています.
いくつかの答え
この情報を追加して、見に来る他の人が見つけられるようにしたいと思います。
Andrew Thompson のコード (リンクを提供してくれた nIcE cOw に感謝します) のおかげで、ウィンドウの内容だけのスクリーンショットを取得できるようになり、タイトルバーと境界線のサイズを試してみる必要がなくなりました。
public static BufferedImage getScreenShot(Component component)
{
BufferedImage image = new BufferedImage(
component.getWidth(),
component.getHeight(),
BufferedImage.TYPE_INT_RGB
);
// call the Component's paint method, using
// the Graphics object of the image.
component.paint( image.getGraphics() );
return image;
}
これは、カスタム ダイアログを開いたときに呼び出され、画像を少し暗くしたりぼかしたりしてからjLabel
、カスタムDLogCoverjPanel
に存在する に表示することができます (画像の aと aだけですjLabel
)。
//get the screenshot
BufferedImage bufferedImage = getScreenShot( this.getContentPane() );
//blur and darken the image slightly
Kernel myKernel = new Kernel(3, 3,new float[] {1f/9f, 1f/9f, 1f/9f,1f/9f, 1f/9f, 1f/9f,1f/9f, 1f/9f, 1f/9f});
BufferedImageOp myOp1 = new ConvolveOp(myKernel);
bufferedImage = myOp1.filter(bufferedImage, null);
RescaleOp myOp2 = new RescaleOp(.6f, 0, null);
bufferedImage = myOp2.filter(bufferedImage, null);
//prepare the image to be shown in a `jLabel`
Image Conv1 = (Image)bufferedImage;
ImageIcon Conv2 = new ImageIcon(Conv1);
myLabel.setIcon(Conv2);
次に、マウス イベントとキー イベントがメイン ウィンドウのコントロールと相互作用しないようにする必要があります。これらのコントロールは、画像によって隠されていますが、現時点ではまだアクセス可能です。次のコードでこれを実行しようとしていますが、これはマウスイベントのみをブロックしているようです:
myLabel.addMouseListener(new MouseAdapter() {});
myLabel.addMouseMotionListener(new MouseMotionAdapter() {});
myLabel.addKeyListener(new KeyAdapter() {});
代わりにさまざまなコントロールを試しましたjLabel
が、同じ効果がありました。マウスはブロックされていますが、キーはブロックされていません。アプリの主要な要素の 1 つは、jTextPane
無関係なキー入力を受け入れることを絶対に許可してはならないため、これは問題です。
簡単にするために、現時点では、テキスト ペインに誤って入力するのを防ぐために必要に応じて編集可能なプロパティをオンまたはオフにしていますが、ある時点でキーボード アクセラレータが割り当てられている可能性があり、それらを必要としないため、これは回避策のハックです。カスタムダイアログが開いているときに誤ってアクティブ化されています。
カスタム ダイアログが開いているときにキーボード イベントが基になるコントロールに到達するのを防ぐための提案が他にある場合は、ID を聞いてみたいと思います。
よろしく
MVK