最近想用swing做一个设想的demo,涉及到背景卷动,虽然我自己也觉得swing的界面不怎么样,但做着玩一玩也没啥。
下面的代码(仅贴出相关代码,其他省略)具体功能是鼠标移向左右边界时,有吸附效果,并且横向x轴坐标滚动,鼠标加速度小于数值时,控制鼠标无法移出窗口。当然,这只是简易实现,很多地方都还要完善,而且可能也并不是最好的,希望大家可以交流更好的方式。
private static final int FPS = 30;
private static final int FRAME_WIDTH = 800;
private static final int BORDER_WIDTH = 4;
private static final int BORDER_BACK_WIDTH = BORDER_WIDTH + 5;
private static final int MOVE_BORDER_WIDTH = BORDER_BACK_WIDTH + 2;
private static final int BORDER_CHECK_WIDTH = MOVE_BORDER_WIDTH + 5;
private static final int BORDER_BACK_RIGHT = FRAME_WIDTH - BORDER_BACK_WIDTH;
private static final int MOVE_BORDER_RIGHT = FRAME_WIDTH - MOVE_BORDER_WIDTH;
private static final int BORDER_CHECK_RIGHT = FRAME_WIDTH - BORDER_CHECK_WIDTH;
private static final int MOVE_SPEED = 4;
private boolean moreLeft = false;
private boolean moreRight = false;
private int bgWidth;
private int bgPosXOfImage = 0;
private int mouseLastX = 0;
private final Robot robot;
public Home() throws AWTException {
initComponents();
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
robot = new Robot(device);
bgWidth = 1000;//just stub
ScheduledExecutorService refreshSchedule = new ScheduledThreadPoolExecutor(1);
refreshSchedule.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
refreshUI();
}
}, 1000 / FPS, 1000 / FPS, TimeUnit.MILLISECONDS);
}
private void refreshUI() {
if (moreLeft && bgPosXOfImage >= MOVE_SPEED) {
moveLeft();
drawBGImage();
}
if (moreRight && (bgPosXOfImage + FRAME_WIDTH) <= (bgWidth - MOVE_SPEED)) {
moveRight();
drawBGImage();
}
}
private void moveRight() {
bgPosXOfImage += MOVE_SPEED;
}
private void moveLeft() {
bgPosXOfImage -= MOVE_SPEED;
}
private void drawBGImage() {
System.out.println("drawBG x:" + bgPosXOfImage);
}
/*
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
onMouseMoved(e);
}
});
*/
private void onMouseMoved(MouseEvent e) {
int x = e.getX();
int zeroXPosOnScreen = e.getXOnScreen() - x;
if (x > BORDER_CHECK_WIDTH && x < BORDER_CHECK_RIGHT) {
moreLeft = moreRight = false;
mouseLastX = x;
return;
}
if (x < mouseLastX && x <= BORDER_CHECK_WIDTH && x > MOVE_BORDER_WIDTH) {
robot.mouseMove(zeroXPosOnScreen + (x = MOVE_BORDER_WIDTH), e.getYOnScreen());
}
if (x > mouseLastX && x >= BORDER_CHECK_RIGHT && x < MOVE_BORDER_RIGHT) {
robot.mouseMove(zeroXPosOnScreen + (x = MOVE_BORDER_RIGHT), e.getYOnScreen());
}
if (x <= MOVE_BORDER_WIDTH) {
moreLeft = true;
moreRight = false;
if (x <= BORDER_BACK_WIDTH) {
robot.mouseMove(zeroXPosOnScreen + MOVE_BORDER_WIDTH, e.getYOnScreen());
}
}
if (x >= MOVE_BORDER_RIGHT) {
moreLeft = false;
moreRight = true;
if (x >= BORDER_BACK_RIGHT) {
robot.mouseMove(zeroXPosOnScreen + MOVE_BORDER_RIGHT, e.getYOnScreen());
}
}
mouseLastX = x;
}
/*
addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
onMouseExited();
}
});
*/
private void onMouseExited() {
moreLeft = false;
moreRight = false;
}