26

Swingを使用してクラスを実装する必要があります。このクラスは、ユーザーが画面上の任意の場所をクリックしたときにマウスの座標を取得できます。自分のウィンドウ内でマウス座標を取得したい場合は、を使用しMouseListenerますが、ユーザーがプログラムの外をクリックしても機能するようにします。

クラスをKColorChooserのように動作させたいのですが、ユーザーはドロップボタンをクリックすると、画面上の任意の場所をクリックしてそのスポットの色を取得できます。しかし、純粋なJavaを使用してそれが可能かどうかはわかりません。

4

12 に答える 12

28

制限はありますが可能です:

フォーカス イベントの AWTEventListener を追加します。ボタンがクリックされる前にアプリにフォーカスがある限り、フォーカス喪失イベントを受け取ります。次に、ポインターの位置を照会します。

もちろん、制限は、アプリがフォーカスを失うことです。したがって、最終的に何を達成しようとしているのかによっては、これが役に立たない場合があります。

フォーカスを失いたくない場合は、一時的に画面全体のスクリーンショットを撮り、それを通常どおりマウス クリックをリッスンする画面いっぱいのウィンドウに表示する必要があります。

最初の方法の証明:

import java.awt.AWTEvent;
import java.awt.MouseInfo;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;

import javax.swing.JFrame;

public class Application1 {
    public static void main(String[] args) {
        Toolkit.getDefaultToolkit().addAWTEventListener(
          new Listener(), AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static class Listener implements AWTEventListener {
        public void eventDispatched(AWTEvent event) {
            System.out.print(MouseInfo.getPointerInfo().getLocation() + " | ");
            System.out.println(event);
        }
    }
}

生成されたアプリの外側をクリックすると:

java.awt.Point[x=198,y=59] | java.awt.event.MouseEvent[MOUSE_EXITED, ...
java.awt.Point[x=976,y=503] | java.awt.FocusEvent[FOCUS_LOST, ...

2点目はアプリの外です。

于 2010-03-10T20:10:00.427 に答える
24

のことは忘れてくださいGlassPane。OS X と Windows の両方で動作する、100% ネイティブな Java の方法がもう 1 つあります。

Java は常にOS X 上のウィンドウの半透明性をサポートしてきましたが、Java は Windows 上のウィンドウの半透明性もサポートするようになりました (Java 1.6.0_10 などをチェックする必要があるため)。

つまり、「色を選択」ツールをクリックすると、画面全体を覆うほぼ透明なボーダレス Java ウィンドウが作成されます。そのアルファを 10 に設定します (アルファは 0 ~ 255 です)。そのアルファは非常に低いため、ユーザーは、画面全体を覆う非常に薄い「ほぼ透明であるが、非常に非常に半透明な」境界のないウィンドウがあることに気付かない.

ユーザーが画面全体をカバーする「10 半透明のボーダレス ウィンドウに設定されたアルファ」をクリックすると、(x,y) が表示されます。

ボーダレス Java ウィンドウを破棄します。

を使用すれば完了ですRobotgetRgb(x,y)

なぜアルファを 0 ではなく 10 に設定するのですか? それ以外の場合、クリックは Java によってインターセプトされず、OS に直接送信されるためです (少なくとも、OS X の事実としてはそうです)。しきい値があり、それが「1」でも「2」でもなく、約 10 程度であることはわかっています。

編集いくつかの色を選択する必要があることを知っていることに気付きました.これはよりトリッキーですが、100%Javaを使用して実行できます. 「わずかにオフ」な色 (「ほぼ透明な」「見えない」レイヤーの影響を受ける) を使用する、クリックしてレイヤーを削除し、正しいピクセル色を取得して、「ほぼ透明な」レイヤーを再度配置する必要があります。もちろん、これはハックの 1 つですが、100% Java で実行できます。

于 2010-03-10T21:38:02.500 に答える
14

使用する

import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;

PointerInfo inf = MouseInfo.getPointerInfo();
Point p = inf.getLocation();

px と py は、ウィンドウの外側の座標を提供します。

于 2011-05-18T20:54:44.107 に答える
5

これらのイベントは、フォーカスのあるウィンドウに向けられます。デスクトップ上のすべてのイベントからは、マウスの位置しか取得できません。

Keilly が既に示したように、マウスの位置を取得することしかできません。

ネイティブ ライブラリを含める必要があります

于 2010-03-10T21:08:58.170 に答える
5

純粋なJavaを使用してそれが可能かどうかはわかりません。

Java は Java に属する Windows 上の MouseEvents しか認識しないため、純粋な Java を使用することはできません。

于 2010-03-10T19:12:41.213 に答える
3

私はこれを自分で試したことはありませんが、フルスクリーンの透明なパネル/フレームなどを作成し、それに MouseListener を追加できるかもしれません。

于 2010-03-10T19:04:59.250 に答える
2

ちょっとしたコツで可能です。100% クロスプラットフォームである必要があります (Linux と Windows でテスト済み)。基本的に、小さな JWindow を作成し、それを「alwaysOnTop」にして、タイマーを使用してマウスで移動します。

詳細については、こちらの回答を参照してください

于 2016-11-27T18:22:45.257 に答える
0

SyntaxT3rr0rの回答に基づいて、どのように機能するかを示すサンプル カラー ピッカーを groovy で作成しました。

import java.awt.*
import java.awt.datatransfer.*
//import com.sun.awt.AWTUtilities;
import javax.swing.WindowConstants as WC;
import javax.swing.SwingConstants as SWC
import groovy.swing.SwingBuilder

class ColorPicker {

    SwingBuilder swb = new SwingBuilder()
    def window;
    def overlayWindow
    def mainPanel;
    def mainLabel;
    def menu;
    def transparent = new Color(0, 0, 0, 0);
    def nearlyTransparent = new Color(0, 0, 0, 26);

    Color color = new Color(150, 150, 255);
    def colorHex = { col ->
        col = col?: color;
        "#"+Integer.toHexString(col.getRGB())[2..-1]
    }
    def getTextColor = { baseColor ->
        baseColor = baseColor?: color;
        (baseColor.red*1.5 + baseColor.green*1.5 + baseColor.blue > 400) ? Color.BLACK : Color.WHITE;
    }
    def setDisplayColor = {newColor ->
        mainPanel.background = newColor
        mainLabel.foreground = getTextColor(newColor)
        mainLabel.text = colorHex(newColor)
    }

    def show(){
        menu = swb.popupMenu { // invoker: mainPanel
            menuItem(text: "Pick Color", actionPerformed: capturePixelColor)
            menuItem(text: "Copy to Clipboard", actionPerformed: {
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                clipboard.setContents(new StringSelection(colorHex()), null);
            })
            separator()
            menuItem(text: "Close", actionPerformed: {dispose()})
        }
        window = swb.frame(
            title: "Color Picker",
            location:[50,50],
            size:[60, 60],
            resizable: false,
            undecorated: true,
            alwaysOnTop: true,
            defaultCloseOperation:WC.EXIT_ON_CLOSE
        ){
            def textColor = getTextColor()
            mainPanel = panel( constraints: BorderLayout.CENTER,
                    border: lineBorder(color: Color.BLACK),
                    componentPopupMenu: menu){
                borderLayout()
                mainLabel = label(text: "--",
                    constraints: BorderLayout.CENTER,
                    horizontalAlignment: SWC.CENTER)
            }
        }
        setDisplayColor(color);
        window.show();
    }

    def capturePixelColor = {
        def screenSize = Toolkit.getDefaultToolkit().screenSize
        overlayWindow = swb.frame(
            location:[0,0],
            size: screenSize,
            resizable: false,
            undecorated: true,
            alwaysOnTop: true,
            defaultCloseOperation:WC.DISPOSE_ON_CLOSE,
            show: true,
            background: nearlyTransparent, // AWTUtilities.setWindowOpacity(overlayWindow, 0.1f);
            cursor: Cursor.CROSSHAIR_CURSOR,
            mouseClicked: {event -> 
                int x = event.getXOnScreen() // or maybe getX() is enough
                int y = event.getYOnScreen()
                overlayWindow.dispose()
                overlayWindow = null
                color = new Robot().getPixelColor(x, y)
                setDisplayColor(color)
            }
        )
    }

    public static void main(String...args){
        println "Welcome to ColorPicker"
        def picker = new ColorPicker()
        picker.show()
    }
}
于 2014-01-09T13:41:13.973 に答える
0

コメントを残すのに十分な担当者がまだいませんが、他のテクニックについてのコメントは次のとおりです。

  • ネイティブ ライブラリを使用: 動作しますが、明らかな配布制限があります

  • GlassPane を使用して画面全体を埋める: GlassPane は Window 内に含まれている必要があります。

  • デスクトップの画像を含むウィンドウを作成し、画面全体を埋めます: 動作しますが、突然デスクトップが静的になります。カーソルは変化しなくなり、他のウィンドウやデスクトップのアニメーションやビデオは不気味なほど静的になります。

別の解決策: Java 6u10 以降を使用している場合、画面いっぱいのウィンドウを改良して、ウィンドウを完全に透明にします。このウィンドウを他のすべてのウィンドウの前に置き、マウス クリックをリッスンします。カーソルの変更がないなどの欠点はまだありますが、何をしたいかによって異なります。

于 2010-03-10T22:02:16.457 に答える