Zuersteinmal: Unter Hot Corner Funktionalität verstehe ich die Möglichkeit dass der User die Maus in eine der vier Bildschirm-Ecken zieht und daraufhin eine frei wählbare Funktionalität ausgeführt wird.
Ich brauche das für eine Software die ich schreibe. Da ich keine Bibliotheken gefunden habe die das können, habe ich das selbst umgesetzt. Grundsätzlich funktioniert alles so wie ich es will. Derzeitige Funktionalität:
Worüber ich mich freuen würde: Wenn sich jemand der einen Verbesserungsvorschlag hat melden würde und mir zeigt wie ich es besser machen kann. Wichtig wäre mir auch das Thema Performance (da gibt es derzeit keine Probleme aber vielleicht kann man das trotzdem noch verbessern?).
Hier ein lauffähiges Beispiel in zwei Klassen zusammengewürfelt bei dem ein JFrame angezeigt bzw. versteckt wird wenn man die Maus in die linke obere Ecke zieht. Hot Corner Implementierung:
Test JFrame:
Ich habe die Darstellung der Grafik auskommentiert damit es keine Probleme gibt mit irgendwelchen Pfaden usw. aber wer will, kann sie gerne einkommentieren und sich z.B. diese Grafik hier holen um sie darzustellen: http://s28.postimg.org/xlyf58yl5/corner.png oder aber irgendeine animierte GIF verwenden. Dann die Datei direkt in das Projektverzeichnis legen.
Ich brauche das für eine Software die ich schreibe. Da ich keine Bibliotheken gefunden habe die das können, habe ich das selbst umgesetzt. Grundsätzlich funktioniert alles so wie ich es will. Derzeitige Funktionalität:
- Eine Klasse kann ein Interface implementieren und somit bestimmen was passieren soll wenn der Mauszeiger in eine Ecke gezogen wird
- Es können wenn gewünscht grundsätzlich all vier Ecken registriert werden
- Der Radius der Ecke kann angepasst werden
- Es kann eine animierte / transparente Grafik in die Ecke eingeblendet und ausgeblendet werden wenn die Hot Corner Aktivität ausgeführt wird
- Die Java Anwendung muss nicht sichtbar sein damit die Hot Corners funktionieren
- Wenn eine Ecke registriert wird, wird jedesmal ein neuer Thread gestartet der die Maus überwacht. Es wäre aber besser wenn sich ein einziger Thread um alle registrierten Ecken kümmern würde
- Derzeit ist das anzeigen der Grafik nur in der linken oberen Ecke möglich
- Die Grafiken werden aus Dateien geladen (GIF / PNG). Diese Funktionalität würde ich gerne behalten aber es wäre klasse wenn es auch möglich wäre eine in Java erstellte Grafik (änlich der Form von "corner.png" zu verwenden)
- Grundsätzlich kommt mir die Implementierung wie sie jetzt ist unnötig komplex und kompliziert vor, ließe sich das verbessern?
- Das Interface hat derzeit nur eine Methode und deshalb kann momentan nur eine Funktionalität hinterlegt werden, selbst wenn man alle 4 Bildschirmecken registriert. Ich könnte das Interface natürlich erweitern aber irgendwie kommt mir das alles unnötig kompliziert vor. Kann man hier nicht irgendwie vielleicht AbstractActions verwenden? Wenn ich bei dem Interface bleibe, dann muss in Zukunft jede Klasse alle vier Methoden implementieren selbst wenn sie nur eine nutzt...
Worüber ich mich freuen würde: Wenn sich jemand der einen Verbesserungsvorschlag hat melden würde und mir zeigt wie ich es besser machen kann. Wichtig wäre mir auch das Thema Performance (da gibt es derzeit keine Probleme aber vielleicht kann man das trotzdem noch verbessern?).
Hier ein lauffähiges Beispiel in zwei Klassen zusammengewürfelt bei dem ein JFrame angezeigt bzw. versteckt wird wenn man die Maus in die linke obere Ecke zieht. Hot Corner Implementierung:
Java:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Endogen on 14.02.14.
*/
public class HotCorner {
private static final HotCorner instance = new HotCorner();
private static Map<Corner, HotCornerInterface> owners = new HashMap<Corner, HotCornerInterface>();
private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private static double radius = 6;
private static boolean switchBool = true;
private HotCorner() {}
public static HotCorner getInstance() {
return instance;
}
public static void registerHotCorner(final Corner corner, HotCornerInterface owner) {
owners.put(corner, owner);
Runnable runnable = new Runnable() {
@Override
public void run() {
Point lastPosition = new Point();
Point cornerPoint = new Point();
switch (corner) {
case TOP_LEFT:
cornerPoint = new Point(0, 0);
break;
case TOP_RIGHT:
cornerPoint = new Point((int)screenSize.getWidth(), 0);
break;
case BOTTOM_LEFT:
cornerPoint = new Point(0, (int)screenSize.getHeight());
break;
case BOTTOM_RIGHT:
cornerPoint = new Point((int)screenSize.getWidth(), (int)screenSize.getHeight());
break;
}
while (true) {
Point currentPosition = MouseInfo.getPointerInfo().getLocation();
if (!currentPosition.equals(lastPosition)) {
lastPosition = currentPosition;
boolean inside = isInside(currentPosition, cornerPoint);
if (inside && switchBool) {
HotCornerInterface owner = owners.get(corner);
if (owner != null) {
owner.onHotCorner();
// showImage();
} else {
return;
}
switchBool = false;
}
if (!inside) {
switchBool = true;
}
}
}
}
};
new Thread(runnable).start();
}
private static boolean isInside(Point currentPosition, Point cornerPoint) {
double x = cornerPoint.getX() - (radius/2);
double y = cornerPoint.getY() - (radius/2);
Ellipse2D circle = new Ellipse2D.Double(x, y, radius, radius);
if (circle.contains(currentPosition.getX(), currentPosition.getY())) {
return true;
}
return false;
}
private static void showImage() {
final JWindow frame = new JWindow();
frame.setAlwaysOnTop(true);
frame.setBackground(new Color(0f, 0f, 0f, 0.0f));
frame.setOpacity(0);
frame.add(new JLabel(new ClearImageIcon("corner.png")));
frame.pack();
frame.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
try {
while (frame.getOpacity() <= 0.90F) {
Thread.sleep(10);
frame.setOpacity(frame.getOpacity() + 0.05F);
}
Thread.sleep(800);
while (frame.getOpacity() >= 0.04F) {
Thread.sleep(20);
frame.setOpacity(frame.getOpacity() - 0.02F);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
frame.dispose();
}
}).start();
}
public static void unregisterHotCorner(Corner corner) {
owners.remove(corner);
}
public enum Corner {
TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT;
}
public static void setRadius(int radius) {
HotCorner.radius = radius;
}
public static class ClearImageIcon extends ImageIcon {
public ClearImageIcon(String filename) {
super(filename);
}
@Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D)g.create();
g2.setBackground(new Color(0,0,0,0));
g2.clearRect(0, 0, getIconWidth(), getIconHeight());
super.paintIcon(c, g2, x, y);
}
}
public interface HotCornerInterface {
public void onHotCorner();
}
}
Test JFrame:
Java:
import javax.swing.*;
import java.awt.*;
/**
* Created by Endogen on 15.02.14.
*/
public class TestFrame extends JFrame implements HotCorner.HotCornerInterface {
public static void main(String[] args) {
new TestFrame().setVisible(true);
}
public TestFrame() {
setPreferredSize(new Dimension(400, 500));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
HotCorner.getInstance().registerHotCorner(HotCorner.Corner.TOP_LEFT, this);
}
@Override
public void onHotCorner() {
if (TestFrame.this.isVisible()) {
TestFrame.this.setVisible(false);
} else {
TestFrame.this.setVisible(true);
TestFrame.this.setState(JFrame.NORMAL);
TestFrame.this.toFront();
TestFrame.this.repaint();
}
}
}
Ich habe die Darstellung der Grafik auskommentiert damit es keine Probleme gibt mit irgendwelchen Pfaden usw. aber wer will, kann sie gerne einkommentieren und sich z.B. diese Grafik hier holen um sie darzustellen: http://s28.postimg.org/xlyf58yl5/corner.png oder aber irgendeine animierte GIF verwenden. Dann die Datei direkt in das Projektverzeichnis legen.
Zuletzt bearbeitet: