2

私はJavaGUI操作を試しており、ユーザー入力を収集するために要求に応じて表示される、jPanel想像力で呼び出されたDLogから作成されたカスタムダイアログを持っています。これは正常に機能しますが、もちろん私のダイアログはモーダルではありません。これにより、ダイアログが開いている間、残りのコントロールが表示され、ユーザーがアクセスできるようになります。全然ダメ!

これを克服するために、ウィンドウに合わせてサイズが変更されますが、必要になるまで表示されないDLogCoverjPanelという名前の別のものがあります。カスタム ダイアログが表示されると、ウィンドウのスクリーンショットが取得され、DLogCoverのラベルに画像として表示されます。これは、カスタム ダイアログの下に表示されますが、他のすべてのものの上に表示されます (ので- カスタム ダイアログは に表示されます)。これは計画どおりに機能しますが、2 つの問題点がありますが、ご協力いただければ幸いです。MODAL_LAYERjLayeredPanelPOPUP_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

4

1 に答える 1

1

JXLayer プロジェクトをご覧になることを強くお勧めします。それはあなたが求めていることを正確に行います。

また、 http://www.jhlabs.com/ip/filters/index.htmlで JHLabs-Filters を見てください。

どうしても気が進まない場合は、コンテンツ ペインのサイズを取得して、それをメイン フレームの高さから引くことができます。これにより、(通常) 必要な結果が得られます。

次のようなことをする必要があります

Point pos = ((JComponent)frame.getContentPane()).getLocationOnScreen();
Point fPos = frame.getLocation();

これにより、フレーム内のコンテンツ ペインのオフセットを計算でき、そこから調整を行うことができます。

個人的には、JXLayer を検討したいと思います。

シェーン

アップデート:

さて、難しい方法です。これで、画面のキャプチャができました。上記で提案したように、フレームの境界線を切り取る必要があります。

JHLabs-Filters を使用すると、次のように画像をぼかすことができます

GaussianFilter gf = new GaussianFilter(10);
imgBG = gf.filter(imgBG, null);

マウス イベント ハンドラーを実行するには、「ガラス ペイン」を使用する必要があります。これは、フレームの上部に配置できる単純なコンポーネントであり、マウス リスナー (およびキー リスナー) をアタッチすると、イベントを「消費」する必要があります。

JFrame.getGlassPane() を検索します。基本的に、背景を描画する (そしてダイアログを配置する) ために使用しているコンポーネントをこれに追加します (表示することを忘れないでください)。

これは、この分野で役立つかもしれませんhttp://www.java2s.com/Code/Java/Swing-JFC/Showhowaglasspanecanbeusedtoblockmouseandkeyevents.htm

シェーンを助けることを願っています

于 2012-07-10T05:43:27.657 に答える