【问题标题】:Java - Custom shaped draggable JFrameJava - 自定义形状的可拖动 JFrame
【发布时间】:2014-04-04 09:15:50
【问题描述】:

所以我使用setShape(s); 制作了一个自定义形状的 JFrame 当你将 JFrame 设置为未装饰时,我得到它来看看我想要的问题,你不能用鼠标在屏幕上拖动 Frame,所以我尝试实现我自己的可拖动框架,但它没有按预期工作,这是 Frame 类:

package rt;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.event.MouseInputAdapter;

public class MyFrame extends JFrame{

private static final int WIDTH = 1024;
private static final int HEIGHT = 1024;
private static int [] OCTAGON_COORDS_X = {300, 524, 680, 680, 524, 300, 144, 144};
private static int [] OCTAGON_COORDS_Y = {300, 300, 457, 680, 836, 836, 680, 457};

public MyFrame() throws IOException {
    // Determine what the default GraphicsDevice can support.
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice gd = ge.getDefaultScreenDevice();

    boolean isUniformTranslucencySupported = gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT);
    boolean isShapedWindowSupported = gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT);
    if (isUniformTranslucencySupported && isShapedWindowSupported) {
        setUndecorated(true);
        setSize(WIDTH, HEIGHT);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        updateFrame();
        //setOpacity(0.55f);
        setVisible(true);
        MyListener myListener = new MyListener();
        addMouseListener(myListener);
        addMouseMotionListener(myListener);
    }
    else {
        System.err.println("Custom shaped JFrames and trunslucent JFrames are not supported by this device!");
        System.exit(0);
    }
}

public void updateFrame() {
    Shape s = new Polygon (OCTAGON_COORDS_X, OCTAGON_COORDS_Y, OCTAGON_COORDS_X.length);
    setShape(s);
}

private class MyListener extends MouseInputAdapter {

    private int initialPressedX;
    private int initialPressedY;

    @Override
    public void mousePressed(MouseEvent e) {
        initialPressedX = e.getX();
        initialPressedY = e.getY();
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        updateFrameCoords(e);
    }


    void updateFrameCoords(MouseEvent e) {
        int dx = e.getX() - initialPressedX;
        int dy = e.getY() - initialPressedY;
        for (int i = 0; i < OCTAGON_COORDS_X.length; i++) {
            OCTAGON_COORDS_X[i] += dx;
            OCTAGON_COORDS_Y[i] += dy;
        }
        updateFrame();
    }
}

}

主类:

package rt;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    try {
        MyFrame frame = new MyFrame();
    } catch (IOException ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }
}

}

但是拖动操作没有像我预期的那样工作,我猜问题在于这些行: 有人介意检查并解释我做错了什么以及如何解决吗? 提前致谢!

【问题讨论】:

  • 为了尽快获得更好的帮助,请发布MCVE(最小完整且可验证的示例)。
  • 好的,如果有人想在这里查看完整代码:pastebin.com/fLx5hSDA - 只需在 Main 类中创建一个新的 MyFrame 实例
  • “如果有人想查看完整代码” 我不想看到“完整代码”,也不会关注链接。如果您需要我的帮助,请将MCVE 直接以edit 的形式发布到该问题(许多其他人也这么认为)。
  • 我将整个代码包含在代码选项卡中,可以吗?对不起,如果我不明白你的意思,英语不是我的母语,所以请原谅我..
  • "..这样好吗?" 它应该是可运行的,所以它需要一个main(..)。进口似乎也不见了。现在您之前说过“只需在 Main 类中创建一个新的 MyFrame 实例” - 如果您不介意这样做,我们应该这样做吗?毕竟,这是你的问题。MCVE 的想法是制作代码,以便复制/粘贴、编译、运行和查看问题。您为提供免费帮助的人设置的障碍越多,他们就越有可能转到下一个帖子/问题。

标签: java swing jframe


【解决方案1】:

我认为您的问题是在执行mouseDragged 时担心框架的形状。我认为您不必担心这一点。

如果您只是将您的方法更改为以下,它可以工作。测试一下。

void updateFrameCoords(MouseEvent e) {
    setLocation(getLocation().x + e.getX() - initialPressedX,
                getLocation().y + e.getY() - initialPressedY);
}

【讨论】:

    【解决方案2】:
    1. 您必须在每次拖动时更新初始坐标
    2. evt.getX() 给出相对于框架的坐标。您应该改用evt.getXOnScreen()

    替换

    void updateFrameCoords(MouseEvent e) {
        int dx = e.getX() - initialPressedX;
        int dy = e.getY() - initialPressedY;
        for (int i = 0; i < OCTAGON_COORDS_X.length; i++) {
            OCTAGON_COORDS_X[i] += dx;
            OCTAGON_COORDS_Y[i] += dy;
        }
        updateFrame();
    }
    

    void updateFrameCoords(MouseEvent e) {
        int dx = e.getXOnScreen() - initialPressedX;
        int dy = e.getYOnScreen() - initialPressedY;
        for (int i = 0; i < OCTAGON_COORDS_X.length; i++) {
            OCTAGON_COORDS_X[i] += dx;
            OCTAGON_COORDS_Y[i] += dy;
        }
        updateFrame();
        initialPressedX = e.getXOnScreen();
        initialPressedY = e.getYOnScreen();
    }
    

    mousePressed 事件中相同。

    祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 2020-08-06
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 2012-09-30
      相关资源
      最近更新 更多