我想创建一个简单的小awt.component,它给我一个调整大小的光标在所有4个边(以及4个角)和一个移动光标在" body"组件。
以下代码可以正常工作,但对于这样一个简单的任务而言看起来很丑陋和复杂。
@Override
public void mouseMoved(MouseEvent arg0) {
if (interactMode != InteractivityMode.EDIT_WINDOW){
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
return;
}
// left border
if (arg0.getX() < RESCALE_AREA) {
if (arg0.getY() < RESCALE_AREA) {
setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
} else if(arg0.getY() > getHeight()-RESCALE_AREA) {
setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
}
// right border
} else if (arg0.getX() > getWidth() - RESCALE_AREA) {
if (arg0.getY() < RESCALE_AREA) {
setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
} else if(arg0.getY() > getHeight()-RESCALE_AREA) {
setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
}
// top border
} else if (arg0.getY() < RESCALE_AREA) {
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
// bottom border
} else if (arg0.getY() > getHeight()-RESCALE_AREA) {
setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
// cursor not on the border
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
}
这可以用更短/更清晰/更好的方式完成吗?
是否有某种&#34;真值表&#34; thingy允许我写一些更具人类可读性和防错性的东西,如:
X < RA | X > w-RA | Y < RA | Y > h-RA | result
----------------------------------------------
y | n | y | n | NW cursor
y | n | n | n | W cursor
y | n | n | y | SW cursor
n | y | y | n | NE cursor
n | y | n | n | E cursor
n | y | n | y | SE cursor
n | n | y | n | N cursor
n | n | n | n | movement cursor
n | n | n | y | S cursor
奖励:在我看来,只要我将鼠标移动到一个像素,上面的代码就会被执行(理论上)。这似乎是相当多的计算能力..有没有另一种方法来做到这一点,或者我应该简单地停止担心并把它全部交给awt事件处理的手? :)
答案 0 :(得分:3)
解决此问题的一种方法是将可能的游标存储在9个元素的数组中,并使用条件计算该数组中的索引。这样的事情:
int horzIndex = x < RA ? 0 : x > w-RA ? 2 : 1;
int vertIndex = y < RA ? 0 : y > h-RA ? 2 : 1;
return cursors[horzIndex * 3 + vertIndex];
答案 1 :(得分:2)
你可能会更好地分离X
和Y
的条件,类似于这个伪代码:
const int[] cursorTable = { NW, N, NE, W, M, E, SW, S, SE }
if X < RA, cursor_X = 0
else if X > w-RA, cursor_X = 2
else cursor_X = 1
if Y < RA, cursor_Y = 0
else if Y > h-RA, cursor_Y = 2
else cursor_Y = 1
cursor = cursorTable[cursor_Y * 3 + cursor_Y]
答案 2 :(得分:0)
我会创建一个带有以下签名的辅助方法:
setCursor(chooseCursor(
arg0.getX(), // x
arg0.getY(), // y
RESCALE_AREA, // top
RESCALE_AREA, // left
getHeight() - RESCALE_AREA, // bottom
getWidth () - RESCALE_AREA // right
));
然后你可以像这样打电话给这个帮手。这提取了一些变量,因此帮助程序可以专注于核心侧检测逻辑。
int v = (y < top ? -1 : y > bottom ? +1 : 0);
int h = (x < left ? -1 : x > right ? +1 : 0);
那么这个辅助方法会是什么样子呢?好吧,您可以使用一些嵌套条件来隔离测试。水平检查时,如果光标在左侧,则存储-1;如果光标在右侧,则存储+1;如果光标在中间,则存储0。像这样:
private Cursor chooseCursor(int x, int y, int top, int left, int bottom, int right) {
int v = (y < top ? -1 : y > bottom ? +1 : 0);
int h = (x < left ? -1 : x > right ? +1 : 0);
int cursor;
switch (v*3 + h) {
case -3 + -1: cursor = Cursor.NW_RESIZE_CURSOR; break;
case -3 + 0: cursor = Cursor.N_RESIZE_CURSOR; break;
case -3 + +1: cursor = Cursor.NE_RESIZE_CURSOR; break;
case 0 + -1: cursor = Cursor.W_RESIZE_CURSOR; break;
case 0 + 0: cursor = Cursor.MOVE_CURSOR; break;
case 0 + +1: cursor = Cursor.E_RESIZE_CURSOR; break;
case +3 + -1: cursor = Cursor.SW_RESIZE_CURSOR; break;
case +3 + 0: cursor = Cursor.S_RESIZE_CURSOR; break;
case +3 + +1: cursor = Cursor.SE_RESIZE_CURSOR; break;
default:
throw new AssertionError(String.format("impossible v=%s,h=%s", v, h));
}
return Cursor.getPredefinedCursor(cursor);
}
然后聪明的部分正在弄清楚如何一次打开两个变量。每个变量都包含-1,0或+1。您可以逐个乘以三并将它们相加以获得介于-4和+4之间的值。该范围内有9个值,现在您可以执行一个开关来返回九个光标中的一个。
该代码如下所示:
originalArray[5] = {9, 2, 3, 4, 15};
// code
// ..
答案 3 :(得分:0)
我唯一可以建议的是分别确定水平和垂直状态。结合它的一种方法是@yole使用数组。但是有点难以理解。恕我直言,更好的方法是通过位标志和从表中读取来组合。
public class Main {
static int S = 1;
static int N = 2;
static int E = 4;
static int W = 8;
static Map<Integer, Integer> cursors = new HashMap<Integer, Integer>() {{
put(S, Cursor.S_RESIZE_CURSOR);
put(N, Cursor.N_RESIZE_CURSOR);
put(S | W, Cursor.SW_RESIZE_CURSOR);
//...
}};
public static void main(String[] args) {
// int delta = 3;
// int width = 100;
// int height = 100;
//
// int x = 100;
// int y = 200;
int pos = 0;
if (x < delta) pos |= W;
else if (x > width - delta) pos |= E;
if (y < delta) pos |= N;
else if (y > height - delta) pos |= S;
Integer cursor = cursors.get(pos);
if (cursor != null) {
//setCursor
}
}
}