【问题标题】:swing step-type cursor moving摆动步进式光标移动
【发布时间】:2012-01-26 14:39:06
【问题描述】:

我有 java swing 国际象棋应用程序。光标具有自定义视图 - 矩形,大小适合整个单元格。而且我需要光标仅在整个单元格上移动。不在一个细胞的范围内。这个问题有一些典型的解决方案吗?或者也许可以使用标准 java 功能设置步进式光标移动?

【问题讨论】:

    标签: java swing graphics paintcomponent mouselistener


    【解决方案1】:

    我不会实现某种“步进”光标。相反,我会完全隐藏光标并以编程方式突出显示当前单元格。


    下面“输出”此屏幕截图的完整示例:

    public class StepComponent extends JComponent implements MouseMotionListener {
        private Point point = new Point(0, 0);
    
        public StepComponent() {
            setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
                    new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB), 
                    new Point(0, 0), "blank cursor"));
            addMouseMotionListener(this);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            int x = 0, y = 0;
            while (x < getWidth()) { g.drawLine(x, 0, x, getHeight()); x += 10; }
            while (y < getHeight()) { g.drawLine(0, y, getWidth(), y); y += 10; }
            if (point != null)
                g.fillRect(point.x, point.y, 10, 10);
        }
        @Override public void mouseDragged(MouseEvent e) { update(e.getPoint()); }
        @Override public void mouseMoved(MouseEvent e) { update(e.getPoint()); }
    
        private void update(Point p) {
            Point point = new Point(10 * (p.x / 10), 10 * (p.y / 10));
            if (!this.point.equals(point)) {
                Rectangle changed = new Rectangle(this.point,new Dimension(10,10));
                this.point = point;
                changed.add(new Rectangle(this.point, new Dimension(10, 10)));
                repaint(changed);
            }
        }
    }
    

    还有一些测试代码:

    public static void main(String[] args) {
    
        JFrame frame = new JFrame("Test");
    
        frame.add(new StepComponent());
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setVisible(true);
    }
    

    【讨论】:

    • 这个评论编辑会杀了我......输入作品只是“完美”
    • 是的,谢谢。我在这种解决方案之前尝试过,甚至使用玻璃面板 - 我认为重新粉刷大部分空面板会更快,然后用棋盘重新粉刷面板。主要问题是 - 性能。重绘方法需要大量资源。鼠标移动,尤其是在应用程序最大化时,会占用我所有的处理器时间。所以这就是我决定尝试使用自定义鼠标光标的原因。
    • 根本不应该花那么多时间,“背景”(在我的例子中是网格)总是可以画在Image上。查看称为双缓冲的东西。但这是另一个问题! ;)
    • 我试过你的例子,即使没有画任何网格 - 只是光标矩形。并且在最大化窗口状态下移动光标将我的处理器加载到 100%。据我了解 - repaint() 方法本身需要大量资源
    • 在我的系统上,此代码最多只使用 3%(在我的 2560x1440 屏幕上最大化),然后我将鼠标移动到所有地方。 ;)
    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2023-03-19
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多